Current File : /home/mmdealscpanel/yummmdeals.com/firewall.tar
__init__.py000064400000000000150351351710006644 0ustar00client.py000064400000410670150351351710006405 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

from gi.repository import GLib, GObject

# force use of pygobject3 in python-slip
import sys
sys.modules['gobject'] = GObject

import dbus.mainloop.glib
import slip.dbus
from decorator import decorator

from firewall import config
from firewall.core.base import DEFAULT_ZONE_TARGET, DEFAULT_POLICY_TARGET, DEFAULT_POLICY_PRIORITY
from firewall.dbus_utils import dbus_to_python
from firewall.functions import b2u
from firewall.core.rich import Rich_Rule
from firewall.core.ipset import normalize_ipset_entry, check_entry_overlaps_existing, \
                                check_for_overlapping_entries
from firewall import errors
from firewall.errors import FirewallError

import dbus
import traceback

exception_handler = None
not_authorized_loop = False

@decorator
def handle_exceptions(func, *args, **kwargs):
    """Decorator to handle exceptions
    """
    authorized = False
    while not authorized:
        try:
            return func(*args, **kwargs)
        except dbus.exceptions.DBusException as e:
            dbus_message = e.get_dbus_message() # returns unicode
            dbus_name = e.get_dbus_name()
            if not exception_handler:
                raise
            if "NotAuthorizedException" in dbus_name:
                exception_handler("NotAuthorizedException")
            elif "org.freedesktop.DBus.Error" in dbus_name:
                # dbus error, try again
                exception_handler(dbus_message)
            else:
                authorized = True
                if dbus_message:
                    exception_handler(dbus_message)
                else:
                    exception_handler(b2u(str(e)))
        except FirewallError as e:
            if not exception_handler:
                raise
            else:
                exception_handler(b2u(str(e)))
        except Exception:
            if not exception_handler:
                raise
            else:
                exception_handler(b2u(traceback.format_exc()))
        if not not_authorized_loop:
            break

# zone config setings

class FirewallClientZoneSettings(object):
    @handle_exceptions
    def __init__(self, settings = None):
        self.settings = ["", "", "", False, DEFAULT_ZONE_TARGET, [], [],
                         [], False, [], [], [], [], [], [], False, False]
        self.settings_name = ["version", "short", "description", "UNUSED",
                              "target", "services", "ports",
                              "icmp_blocks", "masquerade", "forward_ports",
                              "interfaces", "sources", "rules_str",
                              "protocols", "source_ports", "icmp_block_inversion",
                              "forward"]
        self.settings_dbus_type = ["s", "s", "s", "b",
                                   "s", "s", "(ss)",
                                   "s", "b", "(ssss)",
                                   "s", "s", "s",
                                   "s", "(ss)", "b",
                                   "b"]
        if settings:
            if isinstance(settings, list):
                for i,v in enumerate(settings):
                    self.settings[i] = settings[i]
            if isinstance(settings, dict):
                self.setSettingsDict(settings)

    @handle_exceptions
    def __repr__(self):
        return '%s(%r)' % (self.__class__, self.settings)

    @handle_exceptions
    def getSettingsDict(self):
        settings = {}
        for key,value in zip(self.settings_name, self.settings):
            if key == 'UNUSED':
                continue
            settings[key] = value
        return settings
    @handle_exceptions
    def setSettingsDict(self, settings):
        for key in settings:
            self.settings[self.settings_name.index(key)] = settings[key]
    @handle_exceptions
    def getSettingsDbusDict(self):
        settings = {}
        for key,value,sig in zip(self.settings_name, self.settings, self.settings_dbus_type):
            if key == 'UNUSED':
                continue
            if type(value) is list:
                settings[key] = dbus.Array(value, signature=sig)
            elif type(value) is dict:
                settings[key] = dbus.Dictionary(value, signature=sig)
            else:
                settings[key] = value
        return settings

    @handle_exceptions
    def getRuntimeSettingsDict(self):
        settings = self.getSettingsDict()
        # These are not configurable at runtime:
        del settings['version']
        del settings['short']
        del settings['description']
        del settings['target']
        return settings
    @handle_exceptions
    def getRuntimeSettingsDbusDict(self):
        settings = self.getSettingsDbusDict()
        # These are not configurable at runtime:
        del settings['version']
        del settings['short']
        del settings['description']
        del settings['target']
        return settings

    @handle_exceptions
    def getVersion(self):
        return self.settings[0]
    @handle_exceptions
    def setVersion(self, version):
        self.settings[0] = version

    @handle_exceptions
    def getShort(self):
        return self.settings[1]
    @handle_exceptions
    def setShort(self, short):
        self.settings[1] = short

    @handle_exceptions
    def getDescription(self):
        return self.settings[2]
    @handle_exceptions
    def setDescription(self, description):
        self.settings[2] = description

    # self.settings[3] was used for 'immutable'

    @handle_exceptions
    def getTarget(self):
        return self.settings[4] if self.settings[4] != DEFAULT_ZONE_TARGET else "default"
    @handle_exceptions
    def setTarget(self, target):
        self.settings[4] = target if target != "default" else DEFAULT_ZONE_TARGET

    @handle_exceptions
    def getServices(self):
        return self.settings[5]
    @handle_exceptions
    def setServices(self, services):
        self.settings[5] = services
    @handle_exceptions
    def addService(self, service):
        if service not in self.settings[5]:
            self.settings[5].append(service)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, service)
    @handle_exceptions
    def removeService(self, service):
        if service in self.settings[5]:
            self.settings[5].remove(service)
        else:
            raise FirewallError(errors.NOT_ENABLED, service)
    @handle_exceptions
    def queryService(self, service):
        return service in self.settings[5]

    @handle_exceptions
    def getPorts(self):
        return self.settings[6]
    @handle_exceptions
    def setPorts(self, ports):
        self.settings[6] = ports
    @handle_exceptions
    def addPort(self, port, protocol):
        if (port,protocol) not in self.settings[6]:
            self.settings[6].append((port,protocol))
        else:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def removePort(self, port, protocol):
        if (port,protocol) in self.settings[6]:
            self.settings[6].remove((port,protocol))
        else:
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def queryPort(self, port, protocol):
        return (port,protocol) in self.settings[6]

    @handle_exceptions
    def getProtocols(self):
        return self.settings[13]
    @handle_exceptions
    def setProtocols(self, protocols):
        self.settings[13] = protocols
    @handle_exceptions
    def addProtocol(self, protocol):
        if protocol not in self.settings[13]:
            self.settings[13].append(protocol)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, protocol)
    @handle_exceptions
    def removeProtocol(self, protocol):
        if protocol in self.settings[13]:
            self.settings[13].remove(protocol)
        else:
            raise FirewallError(errors.NOT_ENABLED, protocol)
    @handle_exceptions
    def queryProtocol(self, protocol):
        return protocol in self.settings[13]

    @handle_exceptions
    def getSourcePorts(self):
        return self.settings[14]
    @handle_exceptions
    def setSourcePorts(self, ports):
        self.settings[14] = ports
    @handle_exceptions
    def addSourcePort(self, port, protocol):
        if (port,protocol) not in self.settings[14]:
            self.settings[14].append((port,protocol))
        else:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def removeSourcePort(self, port, protocol):
        if (port,protocol) in self.settings[14]:
            self.settings[14].remove((port,protocol))
        else:
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def querySourcePort(self, port, protocol):
        return (port,protocol) in self.settings[14]

    @handle_exceptions
    def getIcmpBlocks(self):
        return self.settings[7]
    @handle_exceptions
    def setIcmpBlocks(self, icmpblocks):
        self.settings[7] = icmpblocks
    @handle_exceptions
    def addIcmpBlock(self, icmptype):
        if icmptype not in self.settings[7]:
            self.settings[7].append(icmptype)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, icmptype)
    @handle_exceptions
    def removeIcmpBlock(self, icmptype):
        if icmptype in self.settings[7]:
            self.settings[7].remove(icmptype)
        else:
            raise FirewallError(errors.NOT_ENABLED, icmptype)
    @handle_exceptions
    def queryIcmpBlock(self, icmptype):
        return icmptype in self.settings[7]

    @handle_exceptions
    def getIcmpBlockInversion(self):
        return self.settings[15]
    @handle_exceptions
    def setIcmpBlockInversion(self, flag):
        self.settings[15] = flag
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addIcmpBlockInversion(self):
        if not self.settings[15]:
            self.settings[15] = True
        else:
            FirewallError(errors.ALREADY_ENABLED, "icmp-block-inversion")
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeIcmpBlockInversion(self):
        if self.settings[15]:
            self.settings[15] = False
        else:
            FirewallError(errors.NOT_ENABLED, "icmp-block-inversion")
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryIcmpBlockInversion(self):
        return self.settings[15]

    @handle_exceptions
    def getForward(self):
        return self.settings[16]
    @handle_exceptions
    def setForward(self, forward):
        self.settings[16] = forward
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addForward(self):
        if not self.settings[16]:
            self.settings[16] = True
        else:
            FirewallError(errors.ALREADY_ENABLED, "forward")
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeForward(self):
        if self.settings[16]:
            self.settings[16] = False
        else:
            FirewallError(errors.NOT_ENABLED, "forward")
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryForward(self):
        return self.settings[16]

    @handle_exceptions
    def getMasquerade(self):
        return self.settings[8]
    @handle_exceptions
    def setMasquerade(self, masquerade):
        self.settings[8] = masquerade
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addMasquerade(self):
        if not self.settings[8]:
            self.settings[8] = True
        else:
            FirewallError(errors.ALREADY_ENABLED, "masquerade")
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeMasquerade(self):
        if self.settings[8]:
            self.settings[8] = False
        else:
            FirewallError(errors.NOT_ENABLED, "masquerade")
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryMasquerade(self):
        return self.settings[8]

    @handle_exceptions
    def getForwardPorts(self):
        return self.settings[9]
    @handle_exceptions
    def setForwardPorts(self, ports):
        self.settings[9] = ports
    @handle_exceptions
    def addForwardPort(self, port, protocol, to_port, to_addr):
        if to_port is None:
            to_port = ''
        if to_addr is None:
            to_addr = ''
        if (port,protocol,to_port,to_addr) not in self.settings[9]:
            self.settings[9].append((port,protocol,to_port,to_addr))
        else:
            raise FirewallError(errors.ALREADY_ENABLED, "'%s:%s:%s:%s'" % \
                                (port, protocol, to_port, to_addr))
    @handle_exceptions
    def removeForwardPort(self, port, protocol, to_port, to_addr):
        if to_port is None:
            to_port = ''
        if to_addr is None:
            to_addr = ''
        if (port,protocol,to_port,to_addr) in self.settings[9]:
            self.settings[9].remove((port,protocol,to_port,to_addr))
        else:
            raise FirewallError(errors.NOT_ENABLED, "'%s:%s:%s:%s'" % \
                                (port, protocol, to_port, to_addr))
    @handle_exceptions
    def queryForwardPort(self, port, protocol, to_port, to_addr):
        if to_port is None:
            to_port = ''
        if to_addr is None:
            to_addr = ''
        return (port,protocol,to_port,to_addr) in self.settings[9]

    @handle_exceptions
    def getInterfaces(self):
        return self.settings[10]
    @handle_exceptions
    def setInterfaces(self, interfaces):
        self.settings[10] = interfaces
    @handle_exceptions
    def addInterface(self, interface):
        if interface not in self.settings[10]:
            self.settings[10].append(interface)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, interface)
    @handle_exceptions
    def removeInterface(self, interface):
        if interface in self.settings[10]:
            self.settings[10].remove(interface)
        else:
            raise FirewallError(errors.NOT_ENABLED, interface)
    @handle_exceptions
    def queryInterface(self, interface):
        return interface in self.settings[10]

    @handle_exceptions
    def getSources(self):
        return self.settings[11]
    @handle_exceptions
    def setSources(self, sources):
        self.settings[11] = sources
    @handle_exceptions
    def addSource(self, source):
        if source not in self.settings[11]:
            self.settings[11].append(source)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, source)
    @handle_exceptions
    def removeSource(self, source):
        if source in self.settings[11]:
            self.settings[11].remove(source)
        else:
            raise FirewallError(errors.NOT_ENABLED, source)
    @handle_exceptions
    def querySource(self, source):
        return source in self.settings[11]

    @handle_exceptions
    def getRichRules(self):
        return self.settings[12]
    @handle_exceptions
    def setRichRules(self, rules):
        rules = [ str(Rich_Rule(rule_str=r)) for r in rules ]
        self.settings[12] = rules
    @handle_exceptions
    def addRichRule(self, rule):
        rule = str(Rich_Rule(rule_str=rule))
        if rule not in self.settings[12]:
            self.settings[12].append(rule)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, rule)
    @handle_exceptions
    def removeRichRule(self, rule):
        rule = str(Rich_Rule(rule_str=rule))
        if rule in self.settings[12]:
            self.settings[12].remove(rule)
        else:
            raise FirewallError(errors.NOT_ENABLED, rule)
    @handle_exceptions
    def queryRichRule(self, rule):
        rule = str(Rich_Rule(rule_str=rule))
        return rule in self.settings[12]


# zone config

class FirewallClientConfigZone(object):
    def __init__(self, bus, path):
        self.bus = bus
        self.path = path
        self.dbus_obj = self.bus.get_object(config.dbus.DBUS_INTERFACE, path)
        self.fw_zone = dbus.Interface(
            self.dbus_obj,
            dbus_interface=config.dbus.DBUS_INTERFACE_CONFIG_ZONE)
        self.fw_properties = dbus.Interface(
            self.dbus_obj, dbus_interface='org.freedesktop.DBus.Properties')
        #TODO: check interface version and revision (need to match client 
        # version)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_property(self, prop):
        return dbus_to_python(self.fw_properties.Get(
            config.dbus.DBUS_INTERFACE_CONFIG_ZONE, prop))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_properties(self):
        return dbus_to_python(self.fw_properties.GetAll(
            config.dbus.DBUS_INTERFACE_CONFIG_ZONE))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def set_property(self, prop, value):
        self.fw_properties.Set(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                               prop, value)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSettings(self):
        return FirewallClientZoneSettings(dbus_to_python(self.fw_zone.getSettings2()))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def update(self, settings):
        self.fw_zone.update2(settings.getSettingsDbusDict())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def loadDefaults(self):
        self.fw_zone.loadDefaults()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def remove(self):
        self.fw_zone.remove()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def rename(self, name):
        self.fw_zone.rename(name)

    # version

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getVersion(self):
        return self.fw_zone.getVersion()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setVersion(self, version):
        self.fw_zone.setVersion(version)

    # short

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getShort(self):
        return self.fw_zone.getShort()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setShort(self, short):
        self.fw_zone.setShort(short)

    # description

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getDescription(self):
        return self.fw_zone.getDescription()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setDescription(self, description):
        self.fw_zone.setDescription(description)

    # target

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getTarget(self):
        return self.fw_zone.getTarget()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setTarget(self, target):
        self.fw_zone.setTarget(target)

    # service

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getServices(self):
        return self.fw_zone.getServices()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setServices(self, services):
        self.fw_zone.setServices(services)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addService(self, service):
        self.fw_zone.addService(service)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeService(self, service):
        self.fw_zone.removeService(service)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryService(self, service):
        return self.fw_zone.queryService(service)

    # port

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getPorts(self):
        return self.fw_zone.getPorts()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setPorts(self, ports):
        self.fw_zone.setPorts(ports)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addPort(self, port, protocol):
        self.fw_zone.addPort(port, protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removePort(self, port, protocol):
        self.fw_zone.removePort(port, protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryPort(self, port, protocol):
        return self.fw_zone.queryPort(port, protocol)

    # protocol

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getProtocols(self):
        return self.fw_zone.getProtocols()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setProtocols(self, protocols):
        self.fw_zone.setProtocols(protocols)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addProtocol(self, protocol):
        self.fw_zone.addProtocol(protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeProtocol(self, protocol):
        self.fw_zone.removeProtocol(protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryProtocol(self, protocol):
        return self.fw_zone.queryProtocol(protocol)

    # source-port

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSourcePorts(self):
        return self.fw_zone.getSourcePorts()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setSourcePorts(self, ports):
        self.fw_zone.setSourcePorts(ports)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addSourcePort(self, port, protocol):
        self.fw_zone.addSourcePort(port, protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeSourcePort(self, port, protocol):
        self.fw_zone.removeSourcePort(port, protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def querySourcePort(self, port, protocol):
        return self.fw_zone.querySourcePort(port, protocol)

    # icmp block

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIcmpBlocks(self):
        return self.fw_zone.getIcmpBlocks()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setIcmpBlocks(self, icmptypes):
        self.fw_zone.setIcmpBlocks(icmptypes)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addIcmpBlock(self, icmptype):
        self.fw_zone.addIcmpBlock(icmptype)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeIcmpBlock(self, icmptype):
        self.fw_zone.removeIcmpBlock(icmptype)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryIcmpBlock(self, icmptype):
        return self.fw_zone.queryIcmpBlock(icmptype)

    # icmp-block-inversion

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIcmpBlockInversion(self):
        return self.fw_zone.getIcmpBlockInversion()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setIcmpBlockInversion(self, inversion):
        self.fw_zone.setIcmpBlockInversion(inversion)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addIcmpBlockInversion(self):
        self.fw_zone.addIcmpBlockInversion()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeIcmpBlockInversion(self):
        self.fw_zone.removeIcmpBlockInversion()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryIcmpBlockInversion(self):
        return self.fw_zone.queryIcmpBlockInversion()

    # forward

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getForward(self):
        return self.fw_zone.getSettings2()["forward"]

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setForward(self, forward):
        self.fw_zone.update2({"forward": forward})

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addForward(self):
        self.fw_zone.update2({"forward": True})

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeForward(self):
        self.fw_zone.update2({"forward": False})

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryForward(self):
        return self.fw_zone.getSettings2()["forward"]

    # masquerade

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getMasquerade(self):
        return self.fw_zone.getMasquerade()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setMasquerade(self, masquerade):
        self.fw_zone.setMasquerade(masquerade)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addMasquerade(self):
        self.fw_zone.addMasquerade()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeMasquerade(self):
        self.fw_zone.removeMasquerade()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryMasquerade(self):
        return self.fw_zone.queryMasquerade()

    # forward port

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getForwardPorts(self):
        return self.fw_zone.getForwardPorts()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setForwardPorts(self, ports):
        self.fw_zone.setForwardPorts(ports)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addForwardPort(self, port, protocol, toport, toaddr):
        if toport is None:
            toport = ''
        if toaddr is None:
            toaddr = ''
        self.fw_zone.addForwardPort(port, protocol, toport, toaddr)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeForwardPort(self, port, protocol, toport, toaddr):
        if toport is None:
            toport = ''
        if toaddr is None:
            toaddr = ''
        self.fw_zone.removeForwardPort(port, protocol, toport, toaddr)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryForwardPort(self, port, protocol, toport, toaddr):
        if toport is None:
            toport = ''
        if toaddr is None:
            toaddr = ''
        return self.fw_zone.queryForwardPort(port, protocol, toport, toaddr)

    # interface

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getInterfaces(self):
        return self.fw_zone.getInterfaces()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setInterfaces(self, interfaces):
        self.fw_zone.setInterfaces(interfaces)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addInterface(self, interface):
        self.fw_zone.addInterface(interface)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeInterface(self, interface):
        self.fw_zone.removeInterface(interface)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryInterface(self, interface):
        return self.fw_zone.queryInterface(interface)

    # source

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSources(self):
        return self.fw_zone.getSources()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setSources(self, sources):
        self.fw_zone.setSources(sources)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addSource(self, source):
        self.fw_zone.addSource(source)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeSource(self, source):
        self.fw_zone.removeSource(source)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def querySource(self, source):
        return self.fw_zone.querySource(source)

    # rich rule

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getRichRules(self):
        return self.fw_zone.getRichRules()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setRichRules(self, rules):
        self.fw_zone.setRichRules(rules)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addRichRule(self, rule):
        self.fw_zone.addRichRule(rule)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeRichRule(self, rule):
        self.fw_zone.removeRichRule(rule)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryRichRule(self, rule):
        return self.fw_zone.queryRichRule(rule)

class FirewallClientPolicySettings(object):
    @handle_exceptions
    def __init__(self, settings=None):
        self.settings = {"description": "",
                         "egress_zones": [],
                         "forward_ports": [],
                         "icmp_blocks": [],
                         "ingress_zones": [],
                         "masquerade": False,
                         "ports": [],
                         "priority": DEFAULT_POLICY_PRIORITY,
                         "protocols": [],
                         "rich_rules": [],
                         "services": [],
                         "short": "",
                         "source_ports": [],
                         "target": DEFAULT_POLICY_TARGET,
                         "version": "",
                         }
        self.settings_dbus_type = ["s", "s", "(ssss)", "s",
                                   "s", "b", "(ss)",
                                   "i", "s", "s",
                                   "s", "s", "(ss)",
                                   "s", "s"]
        if settings:
            self.setSettingsDict(settings)

    @handle_exceptions
    def __repr__(self):
        return '%s(%r)' % (self.__class__, self.settings)

    @handle_exceptions
    def getSettingsDict(self):
        return self.settings
    @handle_exceptions
    def setSettingsDict(self, settings):
        for key in settings:
            self.settings[key] = settings[key]
    @handle_exceptions
    def getSettingsDbusDict(self):
        settings = {}
        for key,sig in zip(self.settings, self.settings_dbus_type):
            value = self.settings[key]
            if type(value) is list:
                settings[key] = dbus.Array(value, signature=sig)
            elif type(value) is dict:
                settings[key] = dbus.Dictionary(value, signature=sig)
            else:
                settings[key] = value
        return settings
    def getRuntimeSettingsDbusDict(self):
        settings = self.getSettingsDbusDict()
        for key in ["version", "short", "description", "target"]:
            del settings[key]
        return settings

    @handle_exceptions
    def getVersion(self):
        return self.settings["version"]
    @handle_exceptions
    def setVersion(self, version):
        self.settings["version"] = version

    @handle_exceptions
    def getShort(self):
        return self.settings["short"]
    @handle_exceptions
    def setShort(self, short):
        self.settings["short"] = short

    @handle_exceptions
    def getDescription(self):
        return self.settings["description"]
    @handle_exceptions
    def setDescription(self, description):
        self.settings["description"] = description

    @handle_exceptions
    def getTarget(self):
        return self.settings["target"]
    @handle_exceptions
    def setTarget(self, target):
        self.settings["target"] = target

    @handle_exceptions
    def getServices(self):
        return self.settings["services"]
    @handle_exceptions
    def setServices(self, services):
        self.settings["services"] = services
    @handle_exceptions
    def addService(self, service):
        if service not in self.settings["services"]:
            self.settings["services"].append(service)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, service)
    @handle_exceptions
    def removeService(self, service):
        if service in self.settings["services"]:
            self.settings["services"].remove(service)
        else:
            raise FirewallError(errors.NOT_ENABLED, service)
    @handle_exceptions
    def queryService(self, service):
        return service in self.settings["services"]

    @handle_exceptions
    def getPorts(self):
        return self.settings["ports"]
    @handle_exceptions
    def setPorts(self, ports):
        self.settings["ports"] = ports
    @handle_exceptions
    def addPort(self, port, protocol):
        if (port,protocol) not in self.settings["ports"]:
            self.settings["ports"].append((port,protocol))
        else:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def removePort(self, port, protocol):
        if (port,protocol) in self.settings["ports"]:
            self.settings["ports"].remove((port,protocol))
        else:
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def queryPort(self, port, protocol):
        return (port,protocol) in self.settings["ports"]

    @handle_exceptions
    def getProtocols(self):
        return self.settings["protocols"]
    @handle_exceptions
    def setProtocols(self, protocols):
        self.settings["protocols"] = protocols
    @handle_exceptions
    def addProtocol(self, protocol):
        if protocol not in self.settings["protocols"]:
            self.settings["protocols"].append(protocol)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, protocol)
    @handle_exceptions
    def removeProtocol(self, protocol):
        if protocol in self.settings["protocols"]:
            self.settings["protocols"].remove(protocol)
        else:
            raise FirewallError(errors.NOT_ENABLED, protocol)
    @handle_exceptions
    def queryProtocol(self, protocol):
        return protocol in self.settings["protocols"]

    @handle_exceptions
    def getSourcePorts(self):
        return self.settings["source_ports"]
    @handle_exceptions
    def setSourcePorts(self, ports):
        self.settings["source_ports"] = ports
    @handle_exceptions
    def addSourcePort(self, port, protocol):
        if (port,protocol) not in self.settings["source_ports"]:
            self.settings["source_ports"].append((port,protocol))
        else:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def removeSourcePort(self, port, protocol):
        if (port,protocol) in self.settings["source_ports"]:
            self.settings["source_ports"].remove((port,protocol))
        else:
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def querySourcePort(self, port, protocol):
        return (port,protocol) in self.settings["source_ports"]

    @handle_exceptions
    def getIcmpBlocks(self):
        return self.settings["icmp_blocks"]
    @handle_exceptions
    def setIcmpBlocks(self, icmpblocks):
        self.settings["icmp_blocks"] = icmpblocks
    @handle_exceptions
    def addIcmpBlock(self, icmptype):
        if icmptype not in self.settings["icmp_blocks"]:
            self.settings["icmp_blocks"].append(icmptype)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, icmptype)
    @handle_exceptions
    def removeIcmpBlock(self, icmptype):
        if icmptype in self.settings["icmp_blocks"]:
            self.settings["icmp_blocks"].remove(icmptype)
        else:
            raise FirewallError(errors.NOT_ENABLED, icmptype)
    @handle_exceptions
    def queryIcmpBlock(self, icmptype):
        return icmptype in self.settings["icmp_blocks"]

    @handle_exceptions
    def getMasquerade(self):
        return self.settings["masquerade"]
    @handle_exceptions
    def setMasquerade(self, masquerade):
        self.settings["masquerade"] = masquerade
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addMasquerade(self):
        if not self.settings["masquerade"]:
            self.settings["masquerade"] = True
        else:
            FirewallError(errors.ALREADY_ENABLED, "masquerade")
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeMasquerade(self):
        if self.settings["masquerade"]:
            self.settings["masquerade"] = False
        else:
            FirewallError(errors.NOT_ENABLED, "masquerade")
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryMasquerade(self):
        return self.settings["masquerade"]

    @handle_exceptions
    def getForwardPorts(self):
        return self.settings["forward_ports"]
    @handle_exceptions
    def setForwardPorts(self, ports):
        self.settings["forward_ports"] = ports
    @handle_exceptions
    def addForwardPort(self, port, protocol, to_port, to_addr):
        if to_port is None:
            to_port = ''
        if to_addr is None:
            to_addr = ''
        if (port,protocol,to_port,to_addr) not in self.settings["forward_ports"]:
            self.settings["forward_ports"].append((port,protocol,to_port,to_addr))
        else:
            raise FirewallError(errors.ALREADY_ENABLED, "'%s:%s:%s:%s'" % \
                                (port, protocol, to_port, to_addr))
    @handle_exceptions
    def removeForwardPort(self, port, protocol, to_port, to_addr):
        if to_port is None:
            to_port = ''
        if to_addr is None:
            to_addr = ''
        if (port,protocol,to_port,to_addr) in self.settings["forward_ports"]:
            self.settings["forward_ports"].remove((port,protocol,to_port,to_addr))
        else:
            raise FirewallError(errors.NOT_ENABLED, "'%s:%s:%s:%s'" % \
                                (port, protocol, to_port, to_addr))
    @handle_exceptions
    def queryForwardPort(self, port, protocol, to_port, to_addr):
        if to_port is None:
            to_port = ''
        if to_addr is None:
            to_addr = ''
        return (port,protocol,to_port,to_addr) in self.settings["forward_ports"]

    @handle_exceptions
    def getRichRules(self):
        return self.settings["rich_rules"]
    @handle_exceptions
    def setRichRules(self, rules):
        rules = [ str(Rich_Rule(rule_str=r)) for r in rules ]
        self.settings["rich_rules"] = rules
    @handle_exceptions
    def addRichRule(self, rule):
        rule = str(Rich_Rule(rule_str=rule))
        if rule not in self.settings["rich_rules"]:
            self.settings["rich_rules"].append(rule)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, rule)
    @handle_exceptions
    def removeRichRule(self, rule):
        rule = str(Rich_Rule(rule_str=rule))
        if rule in self.settings["rich_rules"]:
            self.settings["rich_rules"].remove(rule)
        else:
            raise FirewallError(errors.NOT_ENABLED, rule)
    @handle_exceptions
    def queryRichRule(self, rule):
        rule = str(Rich_Rule(rule_str=rule))
        return rule in self.settings["rich_rules"]

    @handle_exceptions
    def getIngressZones(self):
        return self.settings["ingress_zones"]
    @handle_exceptions
    def setIngressZones(self, ingress_zones):
        self.settings["ingress_zones"] = ingress_zones
    @handle_exceptions
    def addIngressZone(self, ingress_zone):
        if ingress_zone not in self.settings["ingress_zones"]:
            self.settings["ingress_zones"].append(ingress_zone)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, ingress_zone)
    @handle_exceptions
    def removeIngressZone(self, ingress_zone):
        if ingress_zone in self.settings["ingress_zones"]:
            self.settings["ingress_zones"].remove(ingress_zone)
        else:
            raise FirewallError(errors.NOT_ENABLED, ingress_zone)
    @handle_exceptions
    def queryIngressZone(self, ingress_zone):
        return ingress_zone in self.settings["ingress_zones"]

    @handle_exceptions
    def getEgressZones(self):
        return self.settings["egress_zones"]
    @handle_exceptions
    def setEgressZones(self, egress_zones):
        self.settings["egress_zones"] = egress_zones
    @handle_exceptions
    def addEgressZone(self, egress_zone):
        if egress_zone not in self.settings["egress_zones"]:
            self.settings["egress_zones"].append(egress_zone)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, egress_zone)
    @handle_exceptions
    def removeEgressZone(self, egress_zone):
        if egress_zone in self.settings["egress_zones"]:
            self.settings["egress_zones"].remove(egress_zone)
        else:
            raise FirewallError(errors.NOT_ENABLED, egress_zone)
    @handle_exceptions
    def queryEgressZone(self, egress_zone):
        return egress_zone in self.settings["egress_zones"]

    @handle_exceptions
    def getPriority(self):
        return self.settings["priority"]
    @handle_exceptions
    def setPriority(self, priority):
        self.settings["priority"] = int(priority)

class FirewallClientConfigPolicy(object):
    def __init__(self, bus, path):
        self.bus = bus
        self.path = path
        self.dbus_obj = self.bus.get_object(config.dbus.DBUS_INTERFACE, path)
        self.fw_policy = dbus.Interface(
            self.dbus_obj,
            dbus_interface=config.dbus.DBUS_INTERFACE_CONFIG_POLICY)
        self.fw_properties = dbus.Interface(
            self.dbus_obj, dbus_interface='org.freedesktop.DBus.Properties')

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_property(self, prop):
        return dbus_to_python(self.fw_properties.Get(
            config.dbus.DBUS_INTERFACE_CONFIG_POLICY, prop))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_properties(self):
        return dbus_to_python(self.fw_properties.GetAll(
            config.dbus.DBUS_INTERFACE_CONFIG_POLICY))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def set_property(self, prop, value):
        self.fw_properties.Set(config.dbus.DBUS_INTERFACE_CONFIG_POLICY,
                               prop, value)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSettings(self):
        return FirewallClientPolicySettings(dbus_to_python(self.fw_policy.getSettings()))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def update(self, settings):
        self.fw_policy.update(settings.getSettingsDbusDict())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def loadDefaults(self):
        self.fw_policy.loadDefaults()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def remove(self):
        self.fw_policy.remove()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def rename(self, name):
        self.fw_policy.rename(name)

# service config settings

class FirewallClientServiceSettings(object):
    @handle_exceptions
    def __init__(self, settings=None):
        self.settings = ["", "", "", [], [], {}, [], [], [], []]
        self.settings_name = ["version", "short", "description", "ports",
                              "modules", "destination", "protocols",
                              "source_ports", "includes", "helpers"]
        self.settings_dbus_type = ["s", "s", "s", "(ss)",
                                   "s", "ss", "s",
                                   "(ss)", "s", "s"]
        if settings:
            if type(settings) is list:
                for i,v in enumerate(settings):
                    self.settings[i] = settings[i]
            elif type(settings) is dict:
                self.setSettingsDict(settings)

    @handle_exceptions
    def __repr__(self):
        return '%s(%r)' % (self.__class__, self.settings)

    @handle_exceptions
    def getSettingsDict(self):
        settings = {}
        for key,value in zip(self.settings_name, self.settings):
            settings[key] = value
        return settings
    @handle_exceptions
    def setSettingsDict(self, settings):
        for key in settings:
            self.settings[self.settings_name.index(key)] = settings[key]
    @handle_exceptions
    def getSettingsDbusDict(self):
        settings = {}
        for key,value,sig in zip(self.settings_name, self.settings, self.settings_dbus_type):
            if type(value) is list:
                settings[key] = dbus.Array(value, signature=sig)
            elif type(value) is dict:
                settings[key] = dbus.Dictionary(value, signature=sig)
            else:
                settings[key] = value
        return settings

    @handle_exceptions
    def getVersion(self):
        return self.settings[0]
    @handle_exceptions
    def setVersion(self, version):
        self.settings[0] = version

    @handle_exceptions
    def getShort(self):
        return self.settings[1]
    @handle_exceptions
    def setShort(self, short):
        self.settings[1] = short

    @handle_exceptions
    def getDescription(self):
        return self.settings[2]
    @handle_exceptions
    def setDescription(self, description):
        self.settings[2] = description

    @handle_exceptions
    def getPorts(self):
        return self.settings[3]
    @handle_exceptions
    def setPorts(self, ports):
        self.settings[3] = ports
    @handle_exceptions
    def addPort(self, port, protocol):
        if (port,protocol) not in self.settings[3]:
            self.settings[3].append((port,protocol))
        else:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def removePort(self, port, protocol):
        if (port,protocol) in self.settings[3]:
            self.settings[3].remove((port,protocol))
        else:
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def queryPort(self, port, protocol):
        return (port,protocol) in self.settings[3]

    @handle_exceptions
    def getProtocols(self):
        return self.settings[6]
    @handle_exceptions
    def setProtocols(self, protocols):
        self.settings[6] = protocols
    @handle_exceptions
    def addProtocol(self, protocol):
        if protocol not in self.settings[6]:
            self.settings[6].append(protocol)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, protocol)
    @handle_exceptions
    def removeProtocol(self, protocol):
        if protocol in self.settings[6]:
            self.settings[6].remove(protocol)
        else:
            raise FirewallError(errors.NOT_ENABLED, protocol)
    @handle_exceptions
    def queryProtocol(self, protocol):
        return protocol in self.settings[6]

    @handle_exceptions
    def getSourcePorts(self):
        return self.settings[7]
    @handle_exceptions
    def setSourcePorts(self, ports):
        self.settings[7] = ports
    @handle_exceptions
    def addSourcePort(self, port, protocol):
        if (port,protocol) not in self.settings[7]:
            self.settings[7].append((port,protocol))
        else:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def removeSourcePort(self, port, protocol):
        if (port,protocol) in self.settings[7]:
            self.settings[7].remove((port,protocol))
        else:
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def querySourcePort(self, port, protocol):
        return (port,protocol) in self.settings[7]

    @handle_exceptions
    def getModules(self):
        return self.settings[4]
    @handle_exceptions
    def setModules(self, modules):
        self.settings[4] = modules
    @handle_exceptions
    def addModule(self, module):
        if module not in self.settings[4]:
            self.settings[4].append(module)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, module)
    @handle_exceptions
    def removeModule(self, module):
        if module in self.settings[4]:
            self.settings[4].remove(module)
        else:
            raise FirewallError(errors.NOT_ENABLED, module)
    @handle_exceptions
    def queryModule(self, module):
        return module in self.settings[4]

    @handle_exceptions
    def getDestinations(self):
        return self.settings[5]
    @handle_exceptions
    def setDestinations(self, destinations):
        self.settings[5] = destinations
    @handle_exceptions
    def setDestination(self, dest_type, address):
        if dest_type not in self.settings[5] or \
           self.settings[5][dest_type] != address:
            self.settings[5][dest_type] = address
        else:
            raise FirewallError(errors.ALREADY_ENABLED, "'%s:%s'" % \
                                (dest_type, address))
    @handle_exceptions
    def removeDestination(self, dest_type, address=None):
        if dest_type in self.settings[5]:
            if address is not None and self.settings[5][dest_type] != address:
                raise FirewallError(errors.NOT_ENABLED, "'%s:%s'" % \
                                    (dest_type, address))
            del self.settings[5][dest_type]
        else:
            raise FirewallError(errors.NOT_ENABLED, "'%s'" % dest_type)
    @handle_exceptions
    def queryDestination(self, dest_type, address):
        return (dest_type in self.settings[5] and \
                    address == self.settings[5][dest_type])

    @handle_exceptions
    def getIncludes(self):
        return self.settings[8]
    @handle_exceptions
    def setIncludes(self, includes):
        self.settings[8] = includes
    @handle_exceptions
    def addInclude(self, include):
        if include not in self.settings[8]:
            self.settings[8].append(include)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, include)
    @handle_exceptions
    def removeInclude(self, include):
        if include in self.settings[8]:
            self.settings[8].remove(include)
        else:
            raise FirewallError(errors.NOT_ENABLED, include)
    @handle_exceptions
    def queryInclude(self, include):
        return include in self.settings[8]

    @handle_exceptions
    def getHelpers(self):
        return self.settings[9]
    @handle_exceptions
    def setHelpers(self, helpers):
        self.settings[9] = helpers
    @handle_exceptions
    def addHelper(self, helper):
        if helper not in self.settings[9]:
            self.settings[9].append(helper)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, helper)
    @handle_exceptions
    def removeHelper(self, helper):
        if helper in self.settings[9]:
            self.settings[9].remove(helper)
        else:
            raise FirewallError(errors.NOT_ENABLED, helper)
    @handle_exceptions
    def queryHelper(self, helper):
        return helper in self.settings[9]

# ipset config settings

class FirewallClientIPSetSettings(object):
    @handle_exceptions
    def __init__(self, settings=None):
        if settings:
            self.settings = settings
        else:
            self.settings = ["", "", "", "", {}, []]

    @handle_exceptions
    def __repr__(self):
        return '%s(%r)' % (self.__class__, self.settings)

    @handle_exceptions
    def getVersion(self):
        return self.settings[0]
    @handle_exceptions
    def setVersion(self, version):
        self.settings[0] = version

    @handle_exceptions
    def getShort(self):
        return self.settings[1]
    @handle_exceptions
    def setShort(self, short):
        self.settings[1] = short

    @handle_exceptions
    def getDescription(self):
        return self.settings[2]
    @handle_exceptions
    def setDescription(self, description):
        self.settings[2] = description

    @handle_exceptions
    def getType(self):
        return self.settings[3]
    @handle_exceptions
    def setType(self, ipset_type):
        self.settings[3] = ipset_type

    @handle_exceptions
    def getOptions(self):
        return self.settings[4]
    @handle_exceptions
    def setOptions(self, options):
        self.settings[4] = options
    @handle_exceptions
    def addOption(self, key, value):
        if key not in self.settings[4] or self.settings[4][key] != value:
            self.settings[4][key] = value
        else:
            raise FirewallError(errors.ALREADY_ENABLED, "'%s=%s'" % (key,value)
                                if value else key)
    @handle_exceptions
    def removeOption(self, key):
        if key in self.settings[4]:
            del self.settings[4][key]
        else:
            raise FirewallError(errors.NOT_ENABLED, key)
    @handle_exceptions
    def queryOption(self, key, value):
        return key in self.settings[4] and self.settings[4][key] == value

    @handle_exceptions
    def getEntries(self):
        return self.settings[5]
    @handle_exceptions
    def setEntries(self, entries):
        if "timeout" in self.settings[4] and \
           self.settings[4]["timeout"] != "0":
            raise FirewallError(errors.IPSET_WITH_TIMEOUT)
        check_for_overlapping_entries(entries)
        self.settings[5] = entries
    @handle_exceptions
    def addEntry(self, entry):
        if "timeout" in self.settings[4] and \
           self.settings[4]["timeout"] != "0":
            raise FirewallError(errors.IPSET_WITH_TIMEOUT)
        entry = normalize_ipset_entry(entry)
        if entry not in self.settings[5]:
            check_entry_overlaps_existing(entry, self.settings[5])
            self.settings[5].append(entry)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, entry)
    @handle_exceptions
    def removeEntry(self, entry):
        if "timeout" in self.settings[4] and \
           self.settings[4]["timeout"] != "0":
            raise FirewallError(errors.IPSET_WITH_TIMEOUT)
        entry = normalize_ipset_entry(entry)
        if entry in self.settings[5]:
            self.settings[5].remove(entry)
        else:
            raise FirewallError(errors.NOT_ENABLED, entry)
    @handle_exceptions
    def queryEntry(self, entry):
        if "timeout" in self.settings[4] and \
           self.settings[4]["timeout"] != "0":
            raise FirewallError(errors.IPSET_WITH_TIMEOUT)
        entry = normalize_ipset_entry(entry)
        return entry in self.settings[5]

# ipset config

class FirewallClientConfigIPSet(object):
    @handle_exceptions
    def __init__(self, bus, path):
        self.bus = bus
        self.path = path
        self.dbus_obj = self.bus.get_object(config.dbus.DBUS_INTERFACE, path)
        self.fw_ipset = dbus.Interface(
            self.dbus_obj,
            dbus_interface=config.dbus.DBUS_INTERFACE_CONFIG_IPSET)
        self.fw_properties = dbus.Interface(
            self.dbus_obj, dbus_interface='org.freedesktop.DBus.Properties')

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_property(self, prop):
        return dbus_to_python(self.fw_properties.Get(
            config.dbus.DBUS_INTERFACE_CONFIG_IPSET, prop))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_properties(self):
        return dbus_to_python(self.fw_properties.GetAll(
            config.dbus.DBUS_INTERFACE_CONFIG_IPSET))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def set_property(self, prop, value):
        self.fw_properties.Set(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                               prop, value)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSettings(self):
        return FirewallClientIPSetSettings(list(dbus_to_python(\
                    self.fw_ipset.getSettings())))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def update(self, settings):
        self.fw_ipset.update(tuple(settings.settings))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def loadDefaults(self):
        self.fw_ipset.loadDefaults()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def remove(self):
        self.fw_ipset.remove()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def rename(self, name):
        self.fw_ipset.rename(name)

    # version

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getVersion(self):
        return self.fw_ipset.getVersion()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setVersion(self, version):
        self.fw_ipset.setVersion(version)

    # short

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getShort(self):
        return self.fw_ipset.getShort()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setShort(self, short):
        self.fw_ipset.setShort(short)

    # description

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getDescription(self):
        return self.fw_ipset.getDescription()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setDescription(self, description):
        self.fw_ipset.setDescription(description)

    # entry

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getEntries(self):
        return self.fw_ipset.getEntries()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setEntries(self, entries):
        self.fw_ipset.setEntries(entries)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addEntry(self, entry):
        self.fw_ipset.addEntry(entry)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeEntry(self, entry):
        self.fw_ipset.removeEntry(entry)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryEntry(self, entry):
        return self.fw_ipset.queryEntry(entry)

# helper config settings

class FirewallClientHelperSettings(object):
    @handle_exceptions
    def __init__(self, settings=None):
        if settings:
            self.settings = settings
        else:
            self.settings = ["", "", "", "", "", [ ]]

    @handle_exceptions
    def __repr__(self):
        return '%s(%r)' % (self.__class__, self.settings)

    @handle_exceptions
    def getVersion(self):
        return self.settings[0]
    @handle_exceptions
    def setVersion(self, version):
        self.settings[0] = version

    @handle_exceptions
    def getShort(self):
        return self.settings[1]
    @handle_exceptions
    def setShort(self, short):
        self.settings[1] = short

    @handle_exceptions
    def getDescription(self):
        return self.settings[2]
    @handle_exceptions
    def setDescription(self, description):
        self.settings[2] = description

    @handle_exceptions
    def getFamily(self):
        return self.settings[3]
    @handle_exceptions
    def setFamily(self, ipv):
        if ipv is None:
            self.settings[3] = ""
        self.settings[3] = ipv

    @handle_exceptions
    def getModule(self):
        return self.settings[4]
    @handle_exceptions
    def setModule(self, module):
        self.settings[4] = module

    @handle_exceptions
    def getPorts(self):
        return self.settings[5]
    @handle_exceptions
    def setPorts(self, ports):
        self.settings[5] = ports
    @handle_exceptions
    def addPort(self, port, protocol):
        if (port,protocol) not in self.settings[5]:
            self.settings[5].append((port,protocol))
        else:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def removePort(self, port, protocol):
        if (port,protocol) in self.settings[5]:
            self.settings[5].remove((port,protocol))
        else:
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s:%s'" % (port, protocol))
    @handle_exceptions
    def queryPort(self, port, protocol):
        return (port,protocol) in self.settings[5]

# helper config

class FirewallClientConfigHelper(object):
    @handle_exceptions
    def __init__(self, bus, path):
        self.bus = bus
        self.path = path
        self.dbus_obj = self.bus.get_object(config.dbus.DBUS_INTERFACE, path)
        self.fw_helper = dbus.Interface(
            self.dbus_obj,
            dbus_interface=config.dbus.DBUS_INTERFACE_CONFIG_HELPER)
        self.fw_properties = dbus.Interface(
            self.dbus_obj, dbus_interface='org.freedesktop.DBus.Properties')

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_property(self, prop):
        return dbus_to_python(self.fw_properties.Get(
            config.dbus.DBUS_INTERFACE_CONFIG_HELPER, prop))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_properties(self):
        return dbus_to_python(self.fw_properties.GetAll(
            config.dbus.DBUS_INTERFACE_CONFIG_HELPER))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def set_property(self, prop, value):
        self.fw_properties.Set(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                               prop, value)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSettings(self):
        return FirewallClientHelperSettings(list(dbus_to_python(\
                    self.fw_helper.getSettings())))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def update(self, settings):
        self.fw_helper.update(tuple(settings.settings))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def loadDefaults(self):
        self.fw_helper.loadDefaults()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def remove(self):
        self.fw_helper.remove()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def rename(self, name):
        self.fw_helper.rename(name)

    # version

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getVersion(self):
        return self.fw_helper.getVersion()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setVersion(self, version):
        self.fw_helper.setVersion(version)

    # short

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getShort(self):
        return self.fw_helper.getShort()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setShort(self, short):
        self.fw_helper.setShort(short)

    # description

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getDescription(self):
        return self.fw_helper.getDescription()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setDescription(self, description):
        self.fw_helper.setDescription(description)

    # port

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getPorts(self):
        return self.fw_helper.getPorts()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setPorts(self, ports):
        self.fw_helper.setPorts(ports)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addPort(self, port, protocol):
        self.fw_helper.addPort(port, protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removePort(self, port, protocol):
        self.fw_helper.removePort(port, protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryPort(self, port, protocol):
        return self.fw_helper.queryPort(port, protocol)

    # family

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getFamily(self):
        return self.fw_helper.getFamily()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setFamily(self, ipv):
        if ipv is None:
            self.fw_helper.setFamily("")
        self.fw_helper.setFamily(ipv)

    # module

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getModule(self):
        return self.fw_helper.getModule()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setModule(self, module):
        self.fw_helper.setModule(module)

# service config

class FirewallClientConfigService(object):
    @handle_exceptions
    def __init__(self, bus, path):
        self.bus = bus
        self.path = path
        self.dbus_obj = self.bus.get_object(config.dbus.DBUS_INTERFACE, path)
        self.fw_service = dbus.Interface(
            self.dbus_obj,
            dbus_interface=config.dbus.DBUS_INTERFACE_CONFIG_SERVICE)
        self.fw_properties = dbus.Interface(
            self.dbus_obj, dbus_interface='org.freedesktop.DBus.Properties')

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_property(self, prop):
        return dbus_to_python(self.fw_properties.Get(
            config.dbus.DBUS_INTERFACE_CONFIG_SERVICE, prop))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_properties(self):
        return dbus_to_python(self.fw_properties.GetAll(
            config.dbus.DBUS_INTERFACE_CONFIG_SERVICE))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def set_property(self, prop, value):
        self.fw_properties.Set(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                               prop, value)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSettings(self):
        return FirewallClientServiceSettings(dbus_to_python(
                    self.fw_service.getSettings2()))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def update(self, settings):
        self.fw_service.update2(settings.getSettingsDbusDict())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def loadDefaults(self):
        self.fw_service.loadDefaults()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def remove(self):
        self.fw_service.remove()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def rename(self, name):
        self.fw_service.rename(name)

    # version

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getVersion(self):
        return self.fw_service.getVersion()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setVersion(self, version):
        self.fw_service.setVersion(version)

    # short

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getShort(self):
        return self.fw_service.getShort()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setShort(self, short):
        self.fw_service.setShort(short)

    # description

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getDescription(self):
        return self.fw_service.getDescription()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setDescription(self, description):
        self.fw_service.setDescription(description)

    # port

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getPorts(self):
        return self.fw_service.getPorts()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setPorts(self, ports):
        self.fw_service.setPorts(ports)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addPort(self, port, protocol):
        self.fw_service.addPort(port, protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removePort(self, port, protocol):
        self.fw_service.removePort(port, protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryPort(self, port, protocol):
        return self.fw_service.queryPort(port, protocol)

    # protocol

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getProtocols(self):
        return self.fw_service.getProtocols()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setProtocols(self, protocols):
        self.fw_service.setProtocols(protocols)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addProtocol(self, protocol):
        self.fw_service.addProtocol(protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeProtocol(self, protocol):
        self.fw_service.removeProtocol(protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryProtocol(self, protocol):
        return self.fw_service.queryProtocol(protocol)

    # source-port

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSourcePorts(self):
        return self.fw_service.getSourcePorts()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setSourcePorts(self, ports):
        self.fw_service.setSourcePorts(ports)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addSourcePort(self, port, protocol):
        self.fw_service.addSourcePort(port, protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeSourcePort(self, port, protocol):
        self.fw_service.removeSourcePort(port, protocol)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def querySourcePort(self, port, protocol):
        return self.fw_service.querySourcePort(port, protocol)

    # module

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getModules(self):
        return self.fw_service.getModules()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setModules(self, modules):
        self.fw_service.setModules(modules)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addModule(self, module):
        self.fw_service.addModule(module)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeModule(self, module):
        self.fw_service.removeModule(module)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryModule(self, module):
        return self.fw_service.queryModule(module)

    # destination

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getDestinations(self):
        return self.fw_service.getDestinations()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setDestinations(self, destinations):
        self.fw_service.setDestinations(destinations)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getDestination(self, destination):
        return self.fw_service.getDestination(destination)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setDestination(self, destination, address):
        self.fw_service.setDestination(destination, address)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeDestination(self, destination, address=None):
        if address is not None and self.getDestination(destination) != address:
            raise FirewallError(errors.NOT_ENABLED, "'%s:%s'" % \
                                (destination, address))
        self.fw_service.removeDestination(destination)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryDestination(self, destination, address):
        return self.fw_service.queryDestination(destination, address)

    # include

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIncludes(self):
        return self.fw_service.getIncludes()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setIncludes(self, includes):
        self.fw_service.setIncludes(includes)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addInclude(self, include):
        self.fw_service.addInclude(include)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeInclude(self, include):
        self.fw_service.removeInclude(include)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryInclude(self, include):
        return self.fw_service.queryInclude(include)


# icmptype config settings

class FirewallClientIcmpTypeSettings(object):
    @handle_exceptions
    def __init__(self, settings=None):
        if settings:
            self.settings = settings
        else:
            self.settings = ["", "", "", []]

    @handle_exceptions
    def __repr__(self):
        return '%s(%r)' % (self.__class__, self.settings)

    @handle_exceptions
    def getVersion(self):
        return self.settings[0]
    @handle_exceptions
    def setVersion(self, version):
        self.settings[0] = version

    @handle_exceptions
    def getShort(self):
        return self.settings[1]
    @handle_exceptions
    def setShort(self, short):
        self.settings[1] = short

    @handle_exceptions
    def getDescription(self):
        return self.settings[2]
    @handle_exceptions
    def setDescription(self, description):
        self.settings[2] = description

    @handle_exceptions
    def getDestinations(self):
        return self.settings[3]
    @handle_exceptions
    def setDestinations(self, destinations):
        self.settings[3] = destinations
    @handle_exceptions
    def addDestination(self, destination):
        # empty means all
        if not self.settings[3]:
            raise FirewallError(errors.ALREADY_ENABLED, destination)
        elif destination not in self.settings[3]:
            self.settings[3].append(destination)
        else:
            raise FirewallError(errors.ALREADY_ENABLED, destination)
    @handle_exceptions
    def removeDestination(self, destination):
        if destination in self.settings[3]:
            self.settings[3].remove(destination)
        # empty means all
        elif not self.settings[3]:
            self.setDestinations(list(set(['ipv4','ipv6']) - \
                                      set([destination])))
        else:
            raise FirewallError(errors.NOT_ENABLED, destination)

    @handle_exceptions
    def queryDestination(self, destination):
        # empty means all
        return not self.settings[3] or \
               destination in self.settings[3]

# icmptype config

class FirewallClientConfigIcmpType(object):
    @handle_exceptions
    def __init__(self, bus, path):
        self.bus = bus
        self.path = path
        self.dbus_obj = self.bus.get_object(config.dbus.DBUS_INTERFACE, path)
        self.fw_icmptype = dbus.Interface(
            self.dbus_obj,
            dbus_interface=config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE)
        self.fw_properties = dbus.Interface(
            self.dbus_obj, dbus_interface='org.freedesktop.DBus.Properties')

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_property(self, prop):
        return dbus_to_python(self.fw_properties.Get(
            config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE, prop))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_properties(self):
        return dbus_to_python(self.fw_properties.GetAll(
            config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def set_property(self, prop, value):
        self.fw_properties.Set(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                               prop, value)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSettings(self):
        return FirewallClientIcmpTypeSettings(list(dbus_to_python(\
                    self.fw_icmptype.getSettings())))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def update(self, settings):
        self.fw_icmptype.update(tuple(settings.settings))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def loadDefaults(self):
        self.fw_icmptype.loadDefaults()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def remove(self):
        self.fw_icmptype.remove()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def rename(self, name):
        self.fw_icmptype.rename(name)

    # version

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getVersion(self):
        return self.fw_icmptype.getVersion()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setVersion(self, version):
        self.fw_icmptype.setVersion(version)

    # short

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getShort(self):
        return self.fw_icmptype.getShort()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setShort(self, short):
        self.fw_icmptype.setShort(short)

    # description

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getDescription(self):
        return self.fw_icmptype.getDescription()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setDescription(self, description):
        self.fw_icmptype.setDescription(description)

    # destination

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getDestinations(self):
        return self.fw_icmptype.getDestinations()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setDestinations(self, destinations):
        self.fw_icmptype.setDestinations(destinations)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addDestination(self, destination):
        self.fw_icmptype.addDestination(destination)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeDestination(self, destination):
        self.fw_icmptype.removeDestination(destination)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryDestination(self, destination):
        return self.fw_icmptype.queryDestination(destination)


# config.policies lockdown whitelist

class FirewallClientPoliciesLockdownWhitelist(object):
    @handle_exceptions
    def __init__(self, settings=None):
        if settings:
            self.settings = settings
        else:
            self.settings = [ [], [], [], [] ]

    @handle_exceptions
    def __repr__(self):
        return '%s(%r)' % (self.__class__, self.settings)

    @handle_exceptions
    def getCommands(self):
        return self.settings[0]
    @handle_exceptions
    def setCommands(self, commands):
        self.settings[0] = commands
    @handle_exceptions
    def addCommand(self, command):
        if command not in self.settings[0]:
            self.settings[0].append(command)
    @handle_exceptions
    def removeCommand(self, command):
        if command in self.settings[0]:
            self.settings[0].remove(command)
    @handle_exceptions
    def queryCommand(self, command):
        return command in self.settings[0]

    @handle_exceptions
    def getContexts(self):
        return self.settings[1]
    @handle_exceptions
    def setContexts(self, contexts):
        self.settings[1] = contexts
    @handle_exceptions
    def addContext(self, context):
        if context not in self.settings[1]:
            self.settings[1].append(context)
    @handle_exceptions
    def removeContext(self, context):
        if context in self.settings[1]:
            self.settings[1].remove(context)
    @handle_exceptions
    def queryContext(self, context):
        return context in self.settings[1]

    @handle_exceptions
    def getUsers(self):
        return self.settings[2]
    @handle_exceptions
    def setUsers(self, users):
        self.settings[2] = users
    @handle_exceptions
    def addUser(self, user):
        if user not in self.settings[2]:
            self.settings[2].append(user)
    @handle_exceptions
    def removeUser(self, user):
        if user in self.settings[2]:
            self.settings[2].remove(user)
    @handle_exceptions
    def queryUser(self, user):
        return user in self.settings[2]

    @handle_exceptions
    def getUids(self):
        return self.settings[3]
    @handle_exceptions
    def setUids(self, uids):
        self.settings[3] = uids
    @handle_exceptions
    def addUid(self, uid):
        if uid not in self.settings[3]:
            self.settings[3].append(uid)
    @handle_exceptions
    def removeUid(self, uid):
        if uid in self.settings[3]:
            self.settings[3].remove(uid)
    @handle_exceptions
    def queryUid(self, uid):
        return uid in self.settings[3]

# config.policies

class FirewallClientConfigPolicies(object):
    @handle_exceptions
    def __init__(self, bus):
        self.bus = bus
        self.dbus_obj = self.bus.get_object(config.dbus.DBUS_INTERFACE,
                                            config.dbus.DBUS_PATH_CONFIG)
        self.fw_policies = dbus.Interface(
            self.dbus_obj,
            dbus_interface=config.dbus.DBUS_INTERFACE_CONFIG_POLICIES)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getLockdownWhitelist(self):
        return FirewallClientPoliciesLockdownWhitelist( \
            list(dbus_to_python(self.fw_policies.getLockdownWhitelist())))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setLockdownWhitelist(self, settings):
        self.fw_policies.setLockdownWhitelist(tuple(settings.settings))

    # command

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addLockdownWhitelistCommand(self, command):
        self.fw_policies.addLockdownWhitelistCommand(command)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeLockdownWhitelistCommand(self, command):
        self.fw_policies.removeLockdownWhitelistCommand(command)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryLockdownWhitelistCommand(self, command):
        return dbus_to_python(self.fw_policies.queryLockdownWhitelistCommand(command))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getLockdownWhitelistCommands(self):
        return dbus_to_python(self.fw_policies.getLockdownWhitelistCommands())

    # context

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addLockdownWhitelistContext(self, context):
        self.fw_policies.addLockdownWhitelistContext(context)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeLockdownWhitelistContext(self, context):
        self.fw_policies.removeLockdownWhitelistContext(context)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryLockdownWhitelistContext(self, context):
        return dbus_to_python(self.fw_policies.queryLockdownWhitelistContext(context))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getLockdownWhitelistContexts(self):
        return dbus_to_python(self.fw_policies.getLockdownWhitelistContexts())

    # user

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addLockdownWhitelistUser(self, user):
        self.fw_policies.addLockdownWhitelistUser(user)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeLockdownWhitelistUser(self, user):
        self.fw_policies.removeLockdownWhitelistUser(user)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryLockdownWhitelistUser(self, user):
        return dbus_to_python(self.fw_policies.queryLockdownWhitelistUser(user))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getLockdownWhitelistUsers(self):
        return dbus_to_python(self.fw_policies.getLockdownWhitelistUsers())

    # uid

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getLockdownWhitelistUids(self):
        return dbus_to_python(self.fw_policies.getLockdownWhitelistUids())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setLockdownWhitelistUids(self, uids):
        self.fw_policies.setLockdownWhitelistUids(uids)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addLockdownWhitelistUid(self, uid):
        self.fw_policies.addLockdownWhitelistUid(uid)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeLockdownWhitelistUid(self, uid):
        self.fw_policies.removeLockdownWhitelistUid(uid)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryLockdownWhitelistUid(self, uid):
        return dbus_to_python(self.fw_policies.queryLockdownWhitelistUid(uid))

# config.direct

class FirewallClientDirect(object):
    @handle_exceptions
    def __init__(self, settings=None):
        if settings:
            self.settings = settings
        else:
            self.settings = [ [], [], [], ]

    @handle_exceptions
    def __repr__(self):
        return '%s(%r)' % (self.__class__, self.settings)

    @handle_exceptions
    def getAllChains(self):
        return self.settings[0]
    @handle_exceptions
    def getChains(self, ipv, table):
        return [ entry[2] for entry in self.settings[0] \
                 if entry[0] == ipv and entry[1] == table ]
    @handle_exceptions
    def setAllChains(self, chains):
        self.settings[0] = chains
    @handle_exceptions
    def addChain(self, ipv, table, chain):
        idx = (ipv, table, chain)
        if idx not in self.settings[0]:
            self.settings[0].append(idx)
    @handle_exceptions
    def removeChain(self, ipv, table, chain):
        idx = (ipv, table, chain)
        if idx in self.settings[0]:
            self.settings[0].remove(idx)
    @handle_exceptions
    def queryChain(self, ipv, table, chain):
        idx = (ipv, table, chain)
        return idx in self.settings[0]

    @handle_exceptions
    def getAllRules(self):
        return self.settings[1]
    @handle_exceptions
    def getRules(self, ipv, table, chain):
        return [ entry[3:] for entry in self.settings[1] \
                 if entry[0] == ipv and entry[1] == table \
                 and entry[2] == chain ]
    @handle_exceptions
    def setAllRules(self, rules):
        self.settings[1] = rules
    @handle_exceptions
    def addRule(self, ipv, table, chain, priority, args):
        idx = (ipv, table, chain, priority, args)
        if idx not in self.settings[1]:
            self.settings[1].append(idx)
    @handle_exceptions
    def removeRule(self, ipv, table, chain, priority, args):
        idx = (ipv, table, chain, priority, args)
        if idx in self.settings[1]:
            self.settings[1].remove(idx)
    @handle_exceptions
    def removeRules(self, ipv, table, chain):
        for idx in list(self.settings[1]):
            if idx[0] == ipv and idx[1] == table and idx[2] == chain:
                self.settings[1].remove(idx)
    @handle_exceptions
    def queryRule(self, ipv, table, chain, priority, args):
        idx = (ipv, table, chain, priority, args)
        return idx in self.settings[1]

    @handle_exceptions
    def getAllPassthroughs(self):
        return self.settings[2]
    @handle_exceptions
    def setAllPassthroughs(self, passthroughs):
        self.settings[2] = passthroughs
    @handle_exceptions
    def removeAllPassthroughs(self):
        self.settings[2] = []
    @handle_exceptions
    def getPassthroughs(self, ipv):
        return [ entry[1] for entry in self.settings[2] \
                 if entry[0] == ipv ]
    @handle_exceptions
    def addPassthrough(self, ipv, args):
        idx = (ipv, args)
        if idx not in self.settings[2]:
            self.settings[2].append(idx)
    @handle_exceptions
    def removePassthrough(self, ipv, args):
        idx = (ipv, args)
        if idx in self.settings[2]:
            self.settings[2].remove(idx)
    @handle_exceptions
    def queryPassthrough(self, ipv, args):
        idx = (ipv, args)
        return idx in self.settings[2]

# config.direct

class FirewallClientConfigDirect(object):
    @handle_exceptions
    def __init__(self, bus):
        self.bus = bus
        self.dbus_obj = self.bus.get_object(config.dbus.DBUS_INTERFACE,
                                            config.dbus.DBUS_PATH_CONFIG)
        self.fw_direct = dbus.Interface(
            self.dbus_obj,
            dbus_interface=config.dbus.DBUS_INTERFACE_CONFIG_DIRECT)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSettings(self):
        return FirewallClientDirect( \
            list(dbus_to_python(self.fw_direct.getSettings())))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def update(self, settings):
        self.fw_direct.update(tuple(settings.settings))

    # direct chain

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addChain(self, ipv, table, chain):
        self.fw_direct.addChain(ipv, table, chain)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeChain(self, ipv, table, chain):
        self.fw_direct.removeChain(ipv, table, chain)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryChain(self, ipv, table, chain):
        return dbus_to_python(self.fw_direct.queryChain(ipv, table, chain))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getChains(self, ipv, table):
        return dbus_to_python(self.fw_direct.getChains(ipv, table))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getAllChains(self):
        return dbus_to_python(self.fw_direct.getAllChains())

    # direct rule

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addRule(self, ipv, table, chain, priority, args):
        self.fw_direct.addRule(ipv, table, chain, priority, args)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeRule(self, ipv, table, chain, priority, args):
        self.fw_direct.removeRule(ipv, table, chain, priority, args)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeRules(self, ipv, table, chain):
        self.fw_direct.removeRules(ipv, table, chain)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryRule(self, ipv, table, chain, priority, args):
        return dbus_to_python(self.fw_direct.queryRule(ipv, table, chain, priority, args))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getRules(self, ipv, table, chain):
        return dbus_to_python(self.fw_direct.getRules(ipv, table, chain))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getAllRules(self):
        return dbus_to_python(self.fw_direct.getAllRules())

    # tracked passthrough

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addPassthrough(self, ipv, args):
        self.fw_direct.addPassthrough(ipv, args)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removePassthrough(self, ipv, args):
        self.fw_direct.removePassthrough(ipv, args)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryPassthrough(self, ipv, args):
        return dbus_to_python(self.fw_direct.queryPassthrough(ipv, args))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getPassthroughs(self, ipv):
        return dbus_to_python(self.fw_direct.getPassthroughs(ipv))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getAllPassthroughs(self):
        return dbus_to_python(self.fw_direct.getAllPassthroughs())

# config

class FirewallClientConfig(object):
    @handle_exceptions
    def __init__(self, bus):
        self.bus = bus
        self.dbus_obj = self.bus.get_object(config.dbus.DBUS_INTERFACE,
                                            config.dbus.DBUS_PATH_CONFIG)
        self.fw_config = dbus.Interface(
            self.dbus_obj,
            dbus_interface=config.dbus.DBUS_INTERFACE_CONFIG)
        self.fw_properties = dbus.Interface(
            self.dbus_obj, dbus_interface='org.freedesktop.DBus.Properties')
        self._policies = FirewallClientConfigPolicies(self.bus)
        self._direct = FirewallClientConfigDirect(self.bus)

    # properties

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_property(self, prop):
        return dbus_to_python(self.fw_properties.Get(
            config.dbus.DBUS_INTERFACE_CONFIG, prop))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_properties(self):
        return dbus_to_python(self.fw_properties.GetAll(
            config.dbus.DBUS_INTERFACE_CONFIG))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def set_property(self, prop, value):
        self.fw_properties.Set(config.dbus.DBUS_INTERFACE_CONFIG, prop, value)

    # ipset

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIPSetNames(self):
        return dbus_to_python(self.fw_config.getIPSetNames())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def listIPSets(self):
        return dbus_to_python(self.fw_config.listIPSets())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIPSet(self, path):
        return FirewallClientConfigIPSet(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIPSetByName(self, name):
        path = dbus_to_python(self.fw_config.getIPSetByName(name))
        return FirewallClientConfigIPSet(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addIPSet(self, name, settings):
        if isinstance(settings, FirewallClientIPSetSettings):
            path = self.fw_config.addIPSet(name, tuple(settings.settings))
        else:
            path = self.fw_config.addIPSet(name, tuple(settings))
        return FirewallClientConfigIPSet(self.bus, path)

    # zone

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getZoneNames(self):
        return dbus_to_python(self.fw_config.getZoneNames())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def listZones(self):
        return dbus_to_python(self.fw_config.listZones())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getZone(self, path):
        return FirewallClientConfigZone(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getZoneByName(self, name):
        path = dbus_to_python(self.fw_config.getZoneByName(name))
        return FirewallClientConfigZone(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getZoneOfInterface(self, iface):
        return dbus_to_python(self.fw_config.getZoneOfInterface(iface))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getZoneOfSource(self, source):
        return dbus_to_python(self.fw_config.getZoneOfSource(source))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addZone(self, name, settings):
        if isinstance(settings, FirewallClientZoneSettings):
            path = self.fw_config.addZone2(name, settings.getSettingsDbusDict())
        elif isinstance(settings, dict):
            path = self.fw_config.addZone2(name, settings)
        else:
            # tuple based dbus API has 16 elements. Slice what we're given down
            # to the expected size.
            path = self.fw_config.addZone(name, tuple(settings[:16]))
        return FirewallClientConfigZone(self.bus, path)

    # policy

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getPolicyNames(self):
        return dbus_to_python(self.fw_config.getPolicyNames())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def listPolicies(self):
        return dbus_to_python(self.fw_config.listPolicies())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getPolicy(self, path):
        return FirewallClientConfigPolicy(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getPolicyByName(self, name):
        path = dbus_to_python(self.fw_config.getPolicyByName(name))
        return FirewallClientConfigPolicy(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addPolicy(self, name, settings):
        if isinstance(settings, FirewallClientPolicySettings):
            path = self.fw_config.addPolicy(name, settings.getSettingsDbusDict())
        else: # dict
            path = self.fw_config.addPolicy(name, settings)
        return FirewallClientConfigPolicy(self.bus, path)

    # service

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getServiceNames(self):
        return dbus_to_python(self.fw_config.getServiceNames())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def listServices(self):
        return dbus_to_python(self.fw_config.listServices())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getService(self, path):
        return FirewallClientConfigService(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getServiceByName(self, name):
        path = dbus_to_python(self.fw_config.getServiceByName(name))
        return FirewallClientConfigService(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addService(self, name, settings):
        if isinstance(settings, FirewallClientServiceSettings):
            path = self.fw_config.addService2(name, settings.getSettingsDbusDict())
        elif type(settings) is dict:
            path = self.fw_config.addService2(name, settings)
        else:
            # tuple based dbus API has 8 elements. Slice what we're given down
            # to the expected size.
            path = self.fw_config.addService(name, tuple(settings[:8]))
        return FirewallClientConfigService(self.bus, path)

    # icmptype

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIcmpTypeNames(self):
        return dbus_to_python(self.fw_config.getIcmpTypeNames())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def listIcmpTypes(self):
        return dbus_to_python(self.fw_config.listIcmpTypes())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIcmpType(self, path):
        return FirewallClientConfigIcmpType(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIcmpTypeByName(self, name):
        path = dbus_to_python(self.fw_config.getIcmpTypeByName(name))
        return FirewallClientConfigIcmpType(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addIcmpType(self, name, settings):
        if isinstance(settings, FirewallClientIcmpTypeSettings):
            path = self.fw_config.addIcmpType(name, tuple(settings.settings))
        else:
            path = self.fw_config.addIcmpType(name, tuple(settings))
        return FirewallClientConfigIcmpType(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def policies(self):
        return self._policies

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def direct(self):
        return self._direct

    # helper

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getHelperNames(self):
        return dbus_to_python(self.fw_config.getHelperNames())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def listHelpers(self):
        return dbus_to_python(self.fw_config.listHelpers())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getHelper(self, path):
        return FirewallClientConfigHelper(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getHelperByName(self, name):
        path = dbus_to_python(self.fw_config.getHelperByName(name))
        return FirewallClientConfigHelper(self.bus, path)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addHelper(self, name, settings):
        if isinstance(settings, FirewallClientHelperSettings):
            path = self.fw_config.addHelper(name, tuple(settings.settings))
        else:
            path = self.fw_config.addHelper(name, tuple(settings))
        return FirewallClientConfigHelper(self.bus, path)

#

class FirewallClient(object):
    @handle_exceptions
    def __init__(self, bus=None, wait=0, quiet=True):
        if not bus:
            dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
            try:
                self.bus = slip.dbus.SystemBus()
                self.bus.default_timeout = None
            except Exception:
                try:
                    self.bus = dbus.SystemBus()
                except dbus.exceptions.DBusException as e:
                    raise FirewallError(errors.DBUS_ERROR,
                                        e.get_dbus_message())
                else:
                    print("Not using slip.dbus")
        else:
            self.bus = bus

        self.bus.add_signal_receiver(
            handler_function=self._dbus_connection_changed,
            signal_name="NameOwnerChanged",
            dbus_interface="org.freedesktop.DBus",
            arg0=config.dbus.DBUS_INTERFACE)

        for interface in [ config.dbus.DBUS_INTERFACE,
                           config.dbus.DBUS_INTERFACE_IPSET,
                           config.dbus.DBUS_INTERFACE_ZONE,
                           config.dbus.DBUS_INTERFACE_POLICY,
                           config.dbus.DBUS_INTERFACE_DIRECT,
                           config.dbus.DBUS_INTERFACE_POLICIES,
                           config.dbus.DBUS_INTERFACE_CONFIG,
                           config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                           config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                           config.dbus.DBUS_INTERFACE_CONFIG_POLICY,
                           config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                           config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                           config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                           config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                           config.dbus.DBUS_INTERFACE_CONFIG_POLICIES ]:
            self.bus.add_signal_receiver(self._signal_receiver,
                                         dbus_interface=interface,
                                         interface_keyword='interface',
                                         member_keyword='member',
                                         path_keyword='path')

        # callbacks
        self._callback = { }
        self._callbacks = {
            # client callbacks
            "connection-changed": "connection-changed",
            "connection-established": "connection-established",
            "connection-lost": "connection-lost",
            # firewalld callbacks
            "log-denied-changed": "LogDeniedChanged",
            "default-zone-changed": "DefaultZoneChanged",
            "panic-mode-enabled": "PanicModeEnabled",
            "panic-mode-disabled": "PanicModeDisabled",
            "reloaded": "Reloaded",
            "service-added": "ServiceAdded",
            "service-removed": "ServiceRemoved",
            "port-added": "PortAdded",
            "port-removed": "PortRemoved",
            "source-port-added": "SourcePortAdded",
            "source-port-removed": "SourcePortRemoved",
            "protocol-added": "ProtocolAdded",
            "protocol-removed": "ProtocolRemoved",
            "masquerade-added": "MasqueradeAdded",
            "masquerade-removed": "MasqueradeRemoved",
            "forward-port-added": "ForwardPortAdded",
            "forward-port-removed": "ForwardPortRemoved",
            "icmp-block-added": "IcmpBlockAdded",
            "icmp-block-removed": "IcmpBlockRemoved",
            "icmp-block-inversion-added": "IcmpBlockInversionAdded",
            "icmp-block-inversion-removed": "IcmpBlockInversionRemoved",
            "richrule-added": "RichRuleAdded",
            "richrule-removed": "RichRuleRemoved",
            "interface-added": "InterfaceAdded",
            "interface-removed": "InterfaceRemoved",
            "zone-changed": "ZoneOfInterfaceChanged", # DEPRECATED, use zone-of-interface-changed instead
            "zone-of-interface-changed": "ZoneOfInterfaceChanged",
            "source-added": "SourceAdded",
            "source-removed": "SourceRemoved",
            "zone-of-source-changed": "ZoneOfSourceChanged",
            "zone-updated": "ZoneUpdated",
            "policy-updated": "PolicyUpdated",
            # ipset callbacks
            "ipset-entry-added": "EntryAdded",
            "ipset-entry-removed": "EntryRemoved",
            # direct callbacks
            "direct:chain-added": "ChainAdded",
            "direct:chain-removed": "ChainRemoved",
            "direct:rule-added": "RuleAdded",
            "direct:rule-removed": "RuleRemoved",
            "direct:passthrough-added": "PassthroughAdded",
            "direct:passthrough-removed": "PassthroughRemoved",
            "config:direct:updated": "config:direct:Updated",
            # policy callbacks
            "lockdown-enabled": "LockdownEnabled",
            "lockdown-disabled": "LockdownDisabled",
            "lockdown-whitelist-command-added": "LockdownWhitelistCommandAdded",
            "lockdown-whitelist-command-removed": "LockdownWhitelistCommandRemoved",
            "lockdown-whitelist-context-added": "LockdownWhitelistContextAdded",
            "lockdown-whitelist-context-removed": "LockdownWhitelistContextRemoved",
            "lockdown-whitelist-uid-added": "LockdownWhitelistUidAdded",
            "lockdown-whitelist-uid-removed": "LockdownWhitelistUidRemoved",
            "lockdown-whitelist-user-added": "LockdownWhitelistUserAdded",
            "lockdown-whitelist-user-removed": "LockdownWhitelistUserRemoved",
            # firewalld.config callbacks
            "config:policies:lockdown-whitelist-updated": "config:policies:LockdownWhitelistUpdated",
            "config:ipset-added": "config:IPSetAdded",
            "config:ipset-updated": "config:IPSetUpdated",
            "config:ipset-removed": "config:IPSetRemoved",
            "config:ipset-renamed": "config:IPSetRenamed",
            "config:zone-added": "config:ZoneAdded",
            "config:zone-updated": "config:ZoneUpdated",
            "config:zone-removed": "config:ZoneRemoved",
            "config:zone-renamed": "config:ZoneRenamed",
            "config:policy-added": "config:PolicyAdded",
            "config:policy-updated": "config:PolicyUpdated",
            "config:policy-removed": "config:PolicyRemoved",
            "config:policy-renamed": "config:PolicyRenamed",
            "config:service-added": "config:ServiceAdded",
            "config:service-updated": "config:ServiceUpdated",
            "config:service-removed": "config:ServiceRemoved",
            "config:service-renamed": "config:ServiceRenamed",
            "config:icmptype-added": "config:IcmpTypeAdded",
            "config:icmptype-updated": "config:IcmpTypeUpdated",
            "config:icmptype-removed": "config:IcmpTypeRemoved",
            "config:icmptype-renamed": "config:IcmpTypeRenamed",
            "config:helper-added": "config:HelperAdded",
            "config:helper-updated": "config:HelperUpdated",
            "config:helper-removed": "config:HelperRemoved",
            "config:helper-renamed": "config:HelperRenamed",
            }

        # initialize variables used for connection
        self._init_vars()

        self.quiet = quiet

        if wait > 0:
            # connect in one second
            GLib.timeout_add_seconds(wait, self._connection_established)
        else:
            self._connection_established()

    @handle_exceptions
    def _init_vars(self):
        self.fw = None
        self.fw_ipset = None
        self.fw_zone = None
        self.fw_policy = None
        self.fw_helper = None
        self.fw_direct = None
        self.fw_properties = None
        self._config = None
        self.connected = False

    @handle_exceptions
    def getExceptionHandler(self):
        return exception_handler

    @handle_exceptions
    def setExceptionHandler(self, handler):
        global exception_handler
        exception_handler = handler

    @handle_exceptions
    def getNotAuthorizedLoop(self):
        return not_authorized_loop

    @handle_exceptions
    def setNotAuthorizedLoop(self, enable):
        global not_authorized_loop
        not_authorized_loop = enable

    @handle_exceptions
    def connect(self, name, callback, *args):
        if name in self._callbacks:
            self._callback[self._callbacks[name]] = (callback, args)
        else:
            raise ValueError("Unknown callback name '%s'" % name)

    @handle_exceptions
    def _dbus_connection_changed(self, name, old_owner, new_owner):
        if name != config.dbus.DBUS_INTERFACE:
            return

        if new_owner:
            # connection established
            self._connection_established()
        else:
            # connection lost
            self._connection_lost()

    @handle_exceptions
    def _connection_established(self):
        try:
            self.dbus_obj = self.bus.get_object(config.dbus.DBUS_INTERFACE,
                                                config.dbus.DBUS_PATH)
            self.fw = dbus.Interface(self.dbus_obj,
                                     dbus_interface=config.dbus.DBUS_INTERFACE)
            self.fw_ipset = dbus.Interface(
                self.dbus_obj, dbus_interface=config.dbus.DBUS_INTERFACE_IPSET)
            self.fw_zone = dbus.Interface(
                self.dbus_obj,
                dbus_interface=config.dbus.DBUS_INTERFACE_ZONE)
            self.fw_policy = dbus.Interface(
                self.dbus_obj,
                dbus_interface=config.dbus.DBUS_INTERFACE_POLICY)
            self.fw_direct = dbus.Interface(
                self.dbus_obj, dbus_interface=config.dbus.DBUS_INTERFACE_DIRECT)
            self.fw_policies = dbus.Interface(
                self.dbus_obj,
                dbus_interface=config.dbus.DBUS_INTERFACE_POLICIES)
            self.fw_properties = dbus.Interface(
                self.dbus_obj, dbus_interface='org.freedesktop.DBus.Properties')
        except dbus.exceptions.DBusException as e:
            # ignore dbus errors
            if not self.quiet:
                print ("DBusException", e.get_dbus_message())
            return
        except Exception as e:
            if not self.quiet:
                print ("Exception", e)
            return
        self._config = FirewallClientConfig(self.bus)
        self.connected = True
        self._signal_receiver(member="connection-established",
                              interface=config.dbus.DBUS_INTERFACE)
        self._signal_receiver(member="connection-changed",
                              interface=config.dbus.DBUS_INTERFACE)

    @handle_exceptions
    def _connection_lost(self):
        self._init_vars()
        self._signal_receiver(member="connection-lost",
                              interface=config.dbus.DBUS_INTERFACE)
        self._signal_receiver(member="connection-changed",
                              interface=config.dbus.DBUS_INTERFACE)

    @handle_exceptions
    def _signal_receiver(self, *args, **kwargs):
        if "member" not in kwargs or "interface" not in kwargs:
            return

        signal = kwargs["member"]
        interface = kwargs["interface"]

        # config signals need special treatment
        # pimp signal name
        if interface.startswith(config.dbus.DBUS_INTERFACE_CONFIG_ZONE):
            signal = "config:Zone" + signal
        if interface.startswith(config.dbus.DBUS_INTERFACE_CONFIG_POLICY):
            signal = "config:Policy" + signal
        elif interface.startswith(config.dbus.DBUS_INTERFACE_CONFIG_IPSET):
            signal = "config:IPSet" + signal
        elif interface.startswith(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE):
            signal = "config:Service" + signal
        elif interface.startswith(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE):
            signal = "config:IcmpType" + signal
        elif interface.startswith(config.dbus.DBUS_INTERFACE_CONFIG_HELPER):
            signal = "config:Helper" + signal
        elif interface == config.dbus.DBUS_INTERFACE_CONFIG:
            signal = "config:" + signal
        elif interface == config.dbus.DBUS_INTERFACE_CONFIG_POLICIES:
            signal = "config:policies:" + signal
        elif interface == config.dbus.DBUS_INTERFACE_CONFIG_DIRECT:
            signal = "config:direct:" + signal

        cb = None
        for callback in self._callbacks:
            if self._callbacks[callback] == signal and \
                    self._callbacks[callback] in self._callback:
                cb = self._callback[self._callbacks[callback]]
        if cb is None:
            return

        # call back with args converted to python types ...
        cb_args = [ dbus_to_python(arg) for arg in args ]
        try:
            if cb[1]:
                # add call data
                cb_args.extend(cb[1])
            # call back
            cb[0](*cb_args)
        except Exception as msg:
            print(msg)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def config(self):
        return self._config

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def reload(self):
        self.fw.reload()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def complete_reload(self):
        self.fw.completeReload()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    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):
        return dbus_to_python(self.fw_properties.Get(
            config.dbus.DBUS_INTERFACE, prop))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def get_properties(self):
        return dbus_to_python(self.fw_properties.GetAll(
            config.dbus.DBUS_INTERFACE))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def set_property(self, prop, value):
        self.fw_properties.Set(config.dbus.DBUS_INTERFACE, prop, value)

    # panic mode

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def enablePanicMode(self):
        self.fw.enablePanicMode()
    
    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def disablePanicMode(self):
        self.fw.disablePanicMode()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryPanicMode(self):
        return dbus_to_python(self.fw.queryPanicMode())

    # list functions

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getZoneSettings(self, zone):
        return FirewallClientZoneSettings(dbus_to_python(self.fw_zone.getZoneSettings2(zone)))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIPSets(self):
        return dbus_to_python(self.fw_ipset.getIPSets())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIPSetSettings(self, ipset):
        return FirewallClientIPSetSettings(list(dbus_to_python(\
                    self.fw_ipset.getIPSetSettings(ipset))))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addEntry(self, ipset, entry):
        self.fw_ipset.addEntry(ipset, entry)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getEntries(self, ipset):
        return self.fw_ipset.getEntries(ipset)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setEntries(self, ipset, entries):
        return self.fw_ipset.setEntries(ipset, entries)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeEntry(self, ipset, entry):
        self.fw_ipset.removeEntry(ipset, entry)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryEntry(self, ipset, entry):
        return dbus_to_python(self.fw_ipset.queryEntry(ipset, entry))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def listServices(self):
        return dbus_to_python(self.fw.listServices())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getServiceSettings(self, service):
        return FirewallClientServiceSettings(dbus_to_python(
                    self.fw.getServiceSettings2(service)))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def listIcmpTypes(self):
        return dbus_to_python(self.fw.listIcmpTypes())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIcmpTypeSettings(self, icmptype):
        return FirewallClientIcmpTypeSettings(list(dbus_to_python(\
                    self.fw.getIcmpTypeSettings(icmptype))))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getHelpers(self):
        return dbus_to_python(self.fw.getHelpers())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getHelperSettings(self, helper):
        return FirewallClientHelperSettings(list(dbus_to_python(\
                    self.fw.getHelperSettings(helper))))

    # automatic helper setting

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getAutomaticHelpers(self):
        return dbus_to_python(self.fw.getAutomaticHelpers())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setAutomaticHelpers(self, value):
        self.fw.setAutomaticHelpers(value)

    # log denied

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getLogDenied(self):
        return dbus_to_python(self.fw.getLogDenied())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setLogDenied(self, value):
        self.fw.setLogDenied(value)

    # default zone

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getDefaultZone(self):
        return dbus_to_python(self.fw.getDefaultZone())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setDefaultZone(self, zone):
        self.fw.setDefaultZone(zone)

    # zone

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setZoneSettings(self, zone, settings):
        self.fw_zone.setZoneSettings2(zone, settings.getRuntimeSettingsDbusDict())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getZones(self):
        return dbus_to_python(self.fw_zone.getZones())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getActiveZones(self):
        return dbus_to_python(self.fw_zone.getActiveZones())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getZoneOfInterface(self, interface):
        return dbus_to_python(self.fw_zone.getZoneOfInterface(interface))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getZoneOfSource(self, source):
        return dbus_to_python(self.fw_zone.getZoneOfSource(source))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def isImmutable(self, zone):
        return dbus_to_python(self.fw_zone.isImmutable(zone))

    # policy

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getPolicySettings(self, policy):
        return FirewallClientPolicySettings(dbus_to_python(self.fw_policy.getPolicySettings(policy)))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def setPolicySettings(self, policy, settings):
        self.fw_policy.setPolicySettings(policy, settings.getRuntimeSettingsDbusDict())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getPolicies(self):
        return dbus_to_python(self.fw_policy.getPolicies())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getActivePolicies(self):
        return dbus_to_python(self.fw_policy.getActivePolicies())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def isPolicyImmutable(self, policy):
        return dbus_to_python(self.fw_policy.isImmutable(policy))

    # interfaces

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addInterface(self, zone, interface):
        return dbus_to_python(self.fw_zone.addInterface(zone, interface))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def changeZone(self, zone, interface): # DEPRECATED
        return dbus_to_python(self.fw_zone.changeZone(zone, interface))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def changeZoneOfInterface(self, zone, interface):
        return dbus_to_python(self.fw_zone.changeZoneOfInterface(zone,
                                                                 interface))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getInterfaces(self, zone):
        return dbus_to_python(self.fw_zone.getInterfaces(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryInterface(self, zone, interface):
        return dbus_to_python(self.fw_zone.queryInterface(zone, interface))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeInterface(self, zone, interface):
        return dbus_to_python(self.fw_zone.removeInterface(zone, interface))

    # sources

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addSource(self, zone, source):
        return dbus_to_python(self.fw_zone.addSource(zone, source))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def changeZoneOfSource(self, zone, source):
        return dbus_to_python(self.fw_zone.changeZoneOfSource(zone, source))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSources(self, zone):
        return dbus_to_python(self.fw_zone.getSources(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def querySource(self, zone, source):
        return dbus_to_python(self.fw_zone.querySource(zone, source))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeSource(self, zone, source):
        return dbus_to_python(self.fw_zone.removeSource(zone, source))

    # rich rules

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addRichRule(self, zone, rule, timeout=0):
        return dbus_to_python(self.fw_zone.addRichRule(zone, rule, timeout))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getRichRules(self, zone):
        return dbus_to_python(self.fw_zone.getRichRules(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryRichRule(self, zone, rule):
        return dbus_to_python(self.fw_zone.queryRichRule(zone, rule))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeRichRule(self, zone, rule):
        return dbus_to_python(self.fw_zone.removeRichRule(zone, rule))

    # services

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addService(self, zone, service, timeout=0):
        return dbus_to_python(self.fw_zone.addService(zone, service, timeout))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getServices(self, zone):
        return dbus_to_python(self.fw_zone.getServices(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryService(self, zone, service):
        return dbus_to_python(self.fw_zone.queryService(zone, service))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeService(self, zone, service):
        return dbus_to_python(self.fw_zone.removeService(zone, service))

    # ports

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addPort(self, zone, port, protocol, timeout=0):
        return dbus_to_python(self.fw_zone.addPort(zone, port, protocol, timeout))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getPorts(self, zone):
        return dbus_to_python(self.fw_zone.getPorts(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryPort(self, zone, port, protocol):
        return dbus_to_python(self.fw_zone.queryPort(zone, port, protocol))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removePort(self, zone, port, protocol):
        return dbus_to_python(self.fw_zone.removePort(zone, port, protocol))

    # protocols

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addProtocol(self, zone, protocol, timeout=0):
        return dbus_to_python(self.fw_zone.addProtocol(zone, protocol, timeout))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getProtocols(self, zone):
        return dbus_to_python(self.fw_zone.getProtocols(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryProtocol(self, zone, protocol):
        return dbus_to_python(self.fw_zone.queryProtocol(zone, protocol))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeProtocol(self, zone, protocol):
        return dbus_to_python(self.fw_zone.removeProtocol(zone, protocol))

    # forward

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addForward(self, zone):
        self.fw_zone.setZoneSettings2(zone, {"forward": True})

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryForward(self, zone):
        return dbus_to_python(self.fw_zone.getZoneSettings2(zone))["forward"]

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeForward(self, zone):
        self.fw_zone.setZoneSettings2(zone, {"forward": False})

    # masquerade

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addMasquerade(self, zone, timeout=0):
        return dbus_to_python(self.fw_zone.addMasquerade(zone, timeout))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryMasquerade(self, zone):
        return dbus_to_python(self.fw_zone.queryMasquerade(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeMasquerade(self, zone):
        return dbus_to_python(self.fw_zone.removeMasquerade(zone))

    # forward ports

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addForwardPort(self, zone, port, protocol, toport, toaddr,
                       timeout=0):
        if toport is None:
            toport = ""
        if toaddr is None:
            toaddr = ""
        return dbus_to_python(self.fw_zone.addForwardPort(zone, port, protocol,
                                                          toport, toaddr,
                                                          timeout))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getForwardPorts(self, zone):
        return dbus_to_python(self.fw_zone.getForwardPorts(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryForwardPort(self, zone, port, protocol, toport, toaddr):
        if toport is None:
            toport = ""
        if toaddr is None:
            toaddr = ""
        return dbus_to_python(self.fw_zone.queryForwardPort(zone,
                                                            port, protocol,
                                                            toport, toaddr))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeForwardPort(self, zone, port, protocol, toport, toaddr):
        if toport is None:
            toport = ""
        if toaddr is None:
            toaddr = ""
        return dbus_to_python(self.fw_zone.removeForwardPort(zone,
                                                             port, protocol,
                                                             toport, toaddr))

    # source ports

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addSourcePort(self, zone, port, protocol, timeout=0):
        return dbus_to_python(self.fw_zone.addSourcePort(zone, port, protocol,
                                                         timeout))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getSourcePorts(self, zone):
        return dbus_to_python(self.fw_zone.getSourcePorts(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def querySourcePort(self, zone, port, protocol):
        return dbus_to_python(self.fw_zone.querySourcePort(zone, port, protocol))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeSourcePort(self, zone, port, protocol):
        return dbus_to_python(self.fw_zone.removeSourcePort(zone, port,
                                                            protocol))

    # icmpblock

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addIcmpBlock(self, zone, icmp, timeout=0):
        return dbus_to_python(self.fw_zone.addIcmpBlock(zone, icmp, timeout))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getIcmpBlocks(self, zone):
        return dbus_to_python(self.fw_zone.getIcmpBlocks(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryIcmpBlock(self, zone, icmp):
        return dbus_to_python(self.fw_zone.queryIcmpBlock(zone, icmp))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeIcmpBlock(self, zone, icmp):
        return dbus_to_python(self.fw_zone.removeIcmpBlock(zone, icmp))

    # icmp block inversion

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addIcmpBlockInversion(self, zone):
        return dbus_to_python(self.fw_zone.addIcmpBlockInversion(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryIcmpBlockInversion(self, zone):
        return dbus_to_python(self.fw_zone.queryIcmpBlockInversion(zone))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeIcmpBlockInversion(self, zone):
        return dbus_to_python(self.fw_zone.removeIcmpBlockInversion(zone))

    # direct chain

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addChain(self, ipv, table, chain):
        self.fw_direct.addChain(ipv, table, chain)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeChain(self, ipv, table, chain):
        self.fw_direct.removeChain(ipv, table, chain)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryChain(self, ipv, table, chain):
        return dbus_to_python(self.fw_direct.queryChain(ipv, table, chain))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getChains(self, ipv, table):
        return dbus_to_python(self.fw_direct.getChains(ipv, table))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getAllChains(self):
        return dbus_to_python(self.fw_direct.getAllChains())

    # direct rule

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addRule(self, ipv, table, chain, priority, args):
        self.fw_direct.addRule(ipv, table, chain, priority, args)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeRule(self, ipv, table, chain, priority, args):
        self.fw_direct.removeRule(ipv, table, chain, priority, args)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeRules(self, ipv, table, chain):
        self.fw_direct.removeRules(ipv, table, chain)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryRule(self, ipv, table, chain, priority, args):
        return dbus_to_python(self.fw_direct.queryRule(ipv, table, chain, priority, args))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getRules(self, ipv, table, chain):
        return dbus_to_python(self.fw_direct.getRules(ipv, table, chain))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getAllRules(self):
        return dbus_to_python(self.fw_direct.getAllRules())

    # direct passthrough

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def passthrough(self, ipv, args):
        return dbus_to_python(self.fw_direct.passthrough(ipv, args))

    # tracked passthrough

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getAllPassthroughs(self):
        return dbus_to_python(self.fw_direct.getAllPassthroughs())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeAllPassthroughs(self):
        self.fw_direct.removeAllPassthroughs()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getPassthroughs(self, ipv):
        return dbus_to_python(self.fw_direct.getPassthroughs(ipv))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addPassthrough(self, ipv, args):
        self.fw_direct.addPassthrough(ipv, args)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removePassthrough(self, ipv, args):
        self.fw_direct.removePassthrough(ipv, args)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryPassthrough(self, ipv, args):
        return dbus_to_python(self.fw_direct.queryPassthrough(ipv, args))

    # lockdown

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def enableLockdown(self):
        self.fw_policies.enableLockdown()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def disableLockdown(self):
        self.fw_policies.disableLockdown()

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryLockdown(self):
        return dbus_to_python(self.fw_policies.queryLockdown())

    # policies

    # lockdown white list commands

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addLockdownWhitelistCommand(self, command):
        self.fw_policies.addLockdownWhitelistCommand(command)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getLockdownWhitelistCommands(self):
        return dbus_to_python(self.fw_policies.getLockdownWhitelistCommands())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryLockdownWhitelistCommand(self, command):
        return dbus_to_python(self.fw_policies.queryLockdownWhitelistCommand(command))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeLockdownWhitelistCommand(self, command):
        self.fw_policies.removeLockdownWhitelistCommand(command)

    # lockdown white list contexts

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addLockdownWhitelistContext(self, context):
        self.fw_policies.addLockdownWhitelistContext(context)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getLockdownWhitelistContexts(self):
        return dbus_to_python(self.fw_policies.getLockdownWhitelistContexts())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryLockdownWhitelistContext(self, context):
        return dbus_to_python(self.fw_policies.queryLockdownWhitelistContext(context))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeLockdownWhitelistContext(self, context):
        self.fw_policies.removeLockdownWhitelistContext(context)

    # lockdown white list uids

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addLockdownWhitelistUid(self, uid):
        self.fw_policies.addLockdownWhitelistUid(uid)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getLockdownWhitelistUids(self):
        return dbus_to_python(self.fw_policies.getLockdownWhitelistUids())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryLockdownWhitelistUid(self, uid):
        return dbus_to_python(self.fw_policies.queryLockdownWhitelistUid(uid))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeLockdownWhitelistUid(self, uid):
        self.fw_policies.removeLockdownWhitelistUid(uid)

    # lockdown white list users

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def addLockdownWhitelistUser(self, user):
        self.fw_policies.addLockdownWhitelistUser(user)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def getLockdownWhitelistUsers(self):
        return dbus_to_python(self.fw_policies.getLockdownWhitelistUsers())

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def queryLockdownWhitelistUser(self, user):
        return dbus_to_python(self.fw_policies.queryLockdownWhitelistUser(user))

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def removeLockdownWhitelistUser(self, user):
        self.fw_policies.removeLockdownWhitelistUser(user)

    @slip.dbus.polkit.enable_proxy
    @handle_exceptions
    def authorizeAll(self):
        """ Authorize once for all polkit actions. """
        self.fw.authorizeAll()
fw_types.py000064400000004220150351351710006755 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2013-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "LastUpdatedOrderedDict" ]

class LastUpdatedOrderedDict(object):
    def __init__(self, x=None):
        self._dict = { }
        self._list = [ ]
        if x:
            self.update(x)

    def clear(self):
        del self._list[:]
        self._dict.clear()

    def update(self, x):
        for key,value in x.items():
            self[key] = value

    def items(self):
        return [(key, self[key]) for key in self._list]

    def __delitem__(self, key):
        if key in self._dict:
            self._list.remove(key)
            del self._dict[key]

    def __repr__(self):
        return '%s([%s])' % (self.__class__.__name__, ', '.join(
                ['(%r, %r)' % (key, self[key]) for key in self._list]))

    def __setitem__(self, key, value):
        if key not in self._dict:
            self._list.append(key)
        self._dict[key] = value

    def __getitem__(self, key):
        if type(key) == int:
            return self._list[key]
        else:
            return self._dict[key]

    def __len__(self):
        return len(self._list)

    def copy(self):
        return LastUpdatedOrderedDict(self)

    def keys(self):
        return self._list[:]

    def values(self):
        return [ self[key] for key in self._list ]

    def setdefault(self, key, value=None):
        if key in self:
            return self[key]
        else:
            self[key] = value
            return value
dbus_utils.py000064400000017512150351351710007302 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "command_of_pid", "pid_of_sender", "uid_of_sender", "user_of_uid",
            "context_of_sender", "command_of_sender", "user_of_sender",
            "dbus_to_python", "dbus_signature",
            "dbus_introspection_prepare_properties",
            "dbus_introspection_add_properties" ]

import dbus
import pwd
import sys
from xml.dom import minidom

from firewall.core.logger import log

PY2 = sys.version < '3'

def command_of_pid(pid):
    """ Get command for pid from /proc """
    try:
        with open("/proc/%d/cmdline" % pid, "r") as f:
            cmd = f.readlines()[0].replace('\0', " ").strip()
    except Exception:
        return None
    return cmd

def pid_of_sender(bus, sender):
    """ Get pid from sender string using 
    org.freedesktop.DBus.GetConnectionUnixProcessID """

    dbus_obj = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
    dbus_iface = dbus.Interface(dbus_obj, 'org.freedesktop.DBus')

    try:
        pid = int(dbus_iface.GetConnectionUnixProcessID(sender))
    except ValueError:
        return None
    return pid

def uid_of_sender(bus, sender):
    """ Get user id from sender string using 
    org.freedesktop.DBus.GetConnectionUnixUser """

    dbus_obj = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
    dbus_iface = dbus.Interface(dbus_obj, 'org.freedesktop.DBus')

    try:
        uid = int(dbus_iface.GetConnectionUnixUser(sender))
    except ValueError:
        return None
    return uid

def user_of_uid(uid):
    """ Get user for uid from pwd """

    try:
        pws = pwd.getpwuid(uid)
    except Exception:
        return None
    return pws[0]

def context_of_sender(bus, sender):
    """ Get SELinux context from sender string using 
    org.freedesktop.DBus.GetConnectionSELinuxSecurityContext """

    dbus_obj = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
    dbus_iface = dbus.Interface(dbus_obj, 'org.freedesktop.DBus')

    try:
        context =  dbus_iface.GetConnectionSELinuxSecurityContext(sender)
    except Exception:
        return None

    return "".join(map(chr, dbus_to_python(context)))

def command_of_sender(bus, sender):
    """ Return command of D-Bus sender """

    return command_of_pid(pid_of_sender(bus, sender))

def user_of_sender(bus, sender):
    return user_of_uid(uid_of_sender(bus, sender))

def dbus_to_python(obj, expected_type=None):
    if obj is None:
        python_obj = obj
    elif isinstance(obj, dbus.Boolean):
        python_obj = bool(obj)
    elif isinstance(obj, dbus.String):
        python_obj = obj.encode('utf-8') if PY2 else str(obj)
    elif PY2 and isinstance(obj, dbus.UTF8String):  # Python3 has no UTF8String
        python_obj = str(obj)
    elif isinstance(obj, dbus.ObjectPath):
        python_obj = str(obj)
    elif isinstance(obj, dbus.Byte) or \
            isinstance(obj, dbus.Int16) or \
            isinstance(obj, dbus.Int32) or \
            isinstance(obj, dbus.Int64) or \
            isinstance(obj, dbus.UInt16) or \
            isinstance(obj, dbus.UInt32) or \
            isinstance(obj, dbus.UInt64):
        python_obj = int(obj)
    elif isinstance(obj, dbus.Double):
        python_obj = float(obj)
    elif isinstance(obj, dbus.Array):
        python_obj = [dbus_to_python(x) for x in obj]
    elif isinstance(obj, dbus.Struct):
        python_obj = tuple([dbus_to_python(x) for x in obj])
    elif isinstance(obj, dbus.Dictionary):
        python_obj = {dbus_to_python(k): dbus_to_python(v) for k, v in obj.items()}
    elif isinstance(obj, bool) or \
         isinstance(obj, str) or isinstance(obj, bytes) or \
         isinstance(obj, int) or isinstance(obj, float) or \
         isinstance(obj, list) or isinstance(obj, tuple) or \
         isinstance(obj, dict):
        python_obj = obj
    else:
        raise TypeError("Unhandled %s" % repr(obj))

    if expected_type is not None:
        if (expected_type == bool and not isinstance(python_obj, bool)) or \
           (expected_type == str and not isinstance(python_obj, str)) or \
           (expected_type == int and not isinstance(python_obj, int)) or \
           (expected_type == float and not isinstance(python_obj, float)) or \
           (expected_type == list and not isinstance(python_obj, list)) or \
           (expected_type == tuple and not isinstance(python_obj, tuple)) or \
           (expected_type == dict and not isinstance(python_obj, dict)):
            raise TypeError("%s is %s, expected %s" % (python_obj, type(python_obj), expected_type))

    return python_obj

def dbus_signature(obj):
    if isinstance(obj, dbus.Boolean):
        return 'b'
    elif isinstance(obj, dbus.String):
        return 's'
    elif isinstance(obj, dbus.ObjectPath):
        return 'o'
    elif isinstance(obj, dbus.Byte):
        return 'y'
    elif isinstance(obj, dbus.Int16):
        return 'n'
    elif isinstance(obj, dbus.Int32):
        return 'i'
    elif isinstance(obj, dbus.Int64):
        return 'x'
    elif isinstance(obj, dbus.UInt16):
        return 'q'
    elif isinstance(obj, dbus.UInt32):
        return 'u'
    elif isinstance(obj, dbus.UInt64):
        return 't'
    elif isinstance(obj, dbus.Double):
        return 'd'
    elif isinstance(obj, dbus.Array):
        if len(obj.signature) > 1:
            return 'a(%s)' % obj.signature
        else:
            return 'a%s' % obj.signature
    elif isinstance(obj, dbus.Struct):
        return '(%s)' % obj.signature
    elif isinstance(obj, dbus.Dictionary):
        return 'a{%s}' % obj.signature
    elif PY2 and isinstance(obj, dbus.UTF8String):
        return 's'
    else:
        raise TypeError("Unhandled %s" % repr(obj))

def dbus_introspection_prepare_properties(obj, interface, access=None):
    if access is None:
        access = { }

    if not hasattr(obj, "_fw_dbus_properties"):
        setattr(obj, "_fw_dbus_properties", { })
    dip = getattr(obj, "_fw_dbus_properties")
    dip[interface] = { }

    try:
        _dict = obj.GetAll(interface)
    except Exception:
        _dict = { }
    for key,value in _dict.items():
        dip[interface][key] = { "type": dbus_signature(value) }
        if key in access:
            dip[interface][key]["access"] = access[key]
        else:
            dip[interface][key]["access"] = "read"

def dbus_introspection_add_properties(obj, data, interface):
    doc = minidom.parseString(data)

    if hasattr(obj, "_fw_dbus_properties"):
        for node in doc.getElementsByTagName("interface"):
            if node.hasAttribute("name") and \
               node.getAttribute("name") == interface:
                dip = { }
                if getattr(obj, "_fw_dbus_properties"):
                    dip = getattr(obj, "_fw_dbus_properties")
                if interface in dip:
                    for key,value in dip[interface].items():
                        prop = doc.createElement("property")
                        prop.setAttribute("name", key)
                        prop.setAttribute("type", value["type"])
                        prop.setAttribute("access", value["access"])
                        node.appendChild(prop)

    log.debug10(doc.toxml())
    new_data = doc.toxml()
    doc.unlink()
    return new_data
config/__init__.py000064400000011404150351351710010123 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2007-2016 Red Hat, Inc.
# Authors:
# Thomas Woerner <twoerner@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/>.
#

from __future__ import absolute_import

# translation
import locale
try:
    locale.setlocale(locale.LC_ALL, "")
except locale.Error:
    import os
    os.environ['LC_ALL'] = 'C'
    locale.setlocale(locale.LC_ALL, "")

DOMAIN = 'firewalld'
import gettext
gettext.install(domain=DOMAIN)

from . import dbus # noqa: F401

# configuration
DAEMON_NAME = 'firewalld'
CONFIG_NAME = 'firewall-config'
APPLET_NAME = 'firewall-applet'
DATADIR = '/usr/share/' + DAEMON_NAME
CONFIG_GLADE_NAME = CONFIG_NAME + '.glade'
COPYRIGHT = '(C) 2010-2017 Red Hat, Inc.'
VERSION = '0.9.11'
AUTHORS = [
    "Thomas Woerner <twoerner@redhat.com>",
    "Jiri Popelka <jpopelka@redhat.com>",
    "Eric Garver <e@erig.me>",
    ]
LICENSE = gettext.gettext(
    "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.\n"
    "\n"
    "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.\n"
    "\n"
    "You should have received a copy of the GNU General Public License "
    "along with this program.  If not, see <http://www.gnu.org/licenses/>.")
WEBSITE = 'http://www.firewalld.org'

def set_system_config_paths(path):
    global ETC_FIREWALLD, FIREWALLD_CONF, ETC_FIREWALLD_ZONES, \
           ETC_FIREWALLD_SERVICES, ETC_FIREWALLD_ICMPTYPES, \
           ETC_FIREWALLD_IPSETS, ETC_FIREWALLD_HELPERS, \
           FIREWALLD_DIRECT, LOCKDOWN_WHITELIST, ETC_FIREWALLD_POLICIES
    ETC_FIREWALLD = path
    FIREWALLD_CONF = path + '/firewalld.conf'
    ETC_FIREWALLD_ZONES = path + '/zones'
    ETC_FIREWALLD_SERVICES = path + '/services'
    ETC_FIREWALLD_ICMPTYPES = path + '/icmptypes'
    ETC_FIREWALLD_IPSETS = path + '/ipsets'
    ETC_FIREWALLD_HELPERS = path + '/helpers'
    ETC_FIREWALLD_POLICIES = path + '/policies'
    FIREWALLD_DIRECT = path + '/direct.xml'
    LOCKDOWN_WHITELIST = path + '/lockdown-whitelist.xml'
set_system_config_paths('/etc/firewalld')

def set_default_config_paths(path):
    global USR_LIB_FIREWALLD, FIREWALLD_ZONES, FIREWALLD_SERVICES, \
           FIREWALLD_ICMPTYPES, FIREWALLD_IPSETS, FIREWALLD_HELPERS, \
           FIREWALLD_POLICIES
    USR_LIB_FIREWALLD = path
    FIREWALLD_ZONES = path + '/zones'
    FIREWALLD_SERVICES = path + '/services'
    FIREWALLD_ICMPTYPES = path + '/icmptypes'
    FIREWALLD_IPSETS = path + '/ipsets'
    FIREWALLD_HELPERS = path + '/helpers'
    FIREWALLD_POLICIES = path + '/policies'
set_default_config_paths('/usr/lib/firewalld')

FIREWALLD_LOGFILE = '/var/log/firewalld'

FIREWALLD_PIDFILE = "/var/run/firewalld.pid"

FIREWALLD_TEMPDIR = '/run/firewalld'

SYSCONFIGDIR = '/etc/sysconfig'
IFCFGDIR = "/etc/sysconfig/network-scripts"

SYSCTL_CONFIG = '/etc/sysctl.conf'

# commands used by backends
COMMANDS = {
    "ipv4":         "/usr/sbin/iptables",
    "ipv4-restore": "/usr/sbin/iptables-restore",
    "ipv6":         "/usr/sbin/ip6tables",
    "ipv6-restore": "/usr/sbin/ip6tables-restore",
    "eb":           "/usr/sbin/ebtables",
    "eb-restore":   "/usr/sbin/ebtables-restore",
    "ipset":        "/usr/sbin/ipset",
    "modprobe":     "/sbin/modprobe",
    "rmmod":        "/sbin/rmmod",
}

LOG_DENIED_VALUES = [ "all", "unicast", "broadcast", "multicast", "off" ]
AUTOMATIC_HELPERS_VALUES = [ "yes", "no", "system" ]
FIREWALL_BACKEND_VALUES = [ "nftables", "iptables" ]

# fallbacks: will be overloaded by firewalld.conf
FALLBACK_ZONE = "public"
FALLBACK_MINIMAL_MARK = 100
FALLBACK_CLEANUP_ON_EXIT = True
FALLBACK_CLEANUP_MODULES_ON_EXIT = True
FALLBACK_LOCKDOWN = False
FALLBACK_IPV6_RPFILTER = True
FALLBACK_INDIVIDUAL_CALLS = False
FALLBACK_LOG_DENIED = "off"
FALLBACK_AUTOMATIC_HELPERS = "no"
FALLBACK_FIREWALL_BACKEND = "nftables"
FALLBACK_FLUSH_ALL_ON_RELOAD = True
FALLBACK_RFC3964_IPV4 = True
FALLBACK_ALLOW_ZONE_DRIFTING = True
config/dbus.py000064400000005021150351351710007317 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011,2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

DBUS_INTERFACE_VERSION = 1
DBUS_INTERFACE_REVISION = 15

DBUS_INTERFACE = "org.fedoraproject.FirewallD%d" % DBUS_INTERFACE_VERSION
DBUS_INTERFACE_ZONE = DBUS_INTERFACE+".zone"
DBUS_INTERFACE_POLICY = DBUS_INTERFACE+".policy"
DBUS_INTERFACE_DIRECT = DBUS_INTERFACE+".direct"
DBUS_INTERFACE_POLICIES = DBUS_INTERFACE+".policies"
DBUS_INTERFACE_IPSET = DBUS_INTERFACE+".ipset"
DBUS_INTERFACE_CONFIG = DBUS_INTERFACE+".config"
DBUS_INTERFACE_CONFIG_ZONE = DBUS_INTERFACE_CONFIG+".zone"
DBUS_INTERFACE_CONFIG_POLICY = DBUS_INTERFACE_CONFIG+".policy"
DBUS_INTERFACE_CONFIG_SERVICE = DBUS_INTERFACE_CONFIG+".service"
DBUS_INTERFACE_CONFIG_ICMPTYPE = DBUS_INTERFACE_CONFIG+".icmptype"
DBUS_INTERFACE_CONFIG_POLICIES = DBUS_INTERFACE_CONFIG+".policies"
DBUS_INTERFACE_CONFIG_DIRECT = DBUS_INTERFACE_CONFIG+".direct"
DBUS_INTERFACE_CONFIG_IPSET = DBUS_INTERFACE_CONFIG+".ipset"
DBUS_INTERFACE_CONFIG_HELPER = DBUS_INTERFACE_CONFIG+".helper"

DBUS_PATH = "/org/fedoraproject/FirewallD%d" % DBUS_INTERFACE_VERSION
DBUS_PATH_CONFIG = DBUS_PATH+"/config"
DBUS_PATH_CONFIG_ICMPTYPE = DBUS_PATH+"/config/icmptype"
DBUS_PATH_CONFIG_SERVICE = DBUS_PATH+"/config/service"
DBUS_PATH_CONFIG_ZONE = DBUS_PATH+"/config/zone"
DBUS_PATH_CONFIG_POLICY = DBUS_PATH+"/config/policy"
DBUS_PATH_CONFIG_IPSET = DBUS_PATH+"/config/ipset"
DBUS_PATH_CONFIG_HELPER = DBUS_PATH+"/config/helper"

# Polkit actions
_PK_ACTION = "org.fedoraproject.FirewallD%d" % DBUS_INTERFACE_VERSION
PK_ACTION_POLICIES = _PK_ACTION+".policies"
PK_ACTION_POLICIES_INFO = PK_ACTION_POLICIES+".info"
PK_ACTION_CONFIG = _PK_ACTION+".config"
PK_ACTION_CONFIG_INFO = PK_ACTION_CONFIG+".info"
PK_ACTION_DIRECT = _PK_ACTION+".direct"
PK_ACTION_DIRECT_INFO = PK_ACTION_DIRECT+".info"
PK_ACTION_INFO = _PK_ACTION+".info"
PK_ACTION_ALL = _PK_ACTION+".all" # implies all other actions
config/__pycache__/dbus.cpython-36.opt-1.pyc000064400000002737150351351710014555 0ustar003

��g
�@sdZdZdeZedZedZedZedZedZedZedZ	edZ
ed	Zed
ZedZ
edZedZedZdeZed
ZedZedZedZedZedZedZdeZedZedZedZedZedZedZedZ edZ!dS)��zorg.fedoraproject.FirewallD%dz.zonez.policyz.directz	.policiesz.ipsetz.configz.servicez	.icmptypez.helperz/org/fedoraproject/FirewallD%dz/configz/config/icmptypez/config/servicez/config/zonez/config/policyz
/config/ipsetz/config/helperz.infoz.allN)"ZDBUS_INTERFACE_VERSIONZDBUS_INTERFACE_REVISIONZDBUS_INTERFACEZDBUS_INTERFACE_ZONEZDBUS_INTERFACE_POLICYZDBUS_INTERFACE_DIRECTZDBUS_INTERFACE_POLICIESZDBUS_INTERFACE_IPSETZDBUS_INTERFACE_CONFIGZDBUS_INTERFACE_CONFIG_ZONEZDBUS_INTERFACE_CONFIG_POLICYZDBUS_INTERFACE_CONFIG_SERVICEZDBUS_INTERFACE_CONFIG_ICMPTYPEZDBUS_INTERFACE_CONFIG_POLICIESZDBUS_INTERFACE_CONFIG_DIRECTZDBUS_INTERFACE_CONFIG_IPSETZDBUS_INTERFACE_CONFIG_HELPERZ	DBUS_PATHZDBUS_PATH_CONFIGZDBUS_PATH_CONFIG_ICMPTYPEZDBUS_PATH_CONFIG_SERVICEZDBUS_PATH_CONFIG_ZONEZDBUS_PATH_CONFIG_POLICYZDBUS_PATH_CONFIG_IPSETZDBUS_PATH_CONFIG_HELPERZ
_PK_ACTIONZPK_ACTION_POLICIESZPK_ACTION_POLICIES_INFOZPK_ACTION_CONFIGZPK_ACTION_CONFIG_INFOZPK_ACTION_DIRECTZPK_ACTION_DIRECT_INFOZPK_ACTION_INFOZ
PK_ACTION_ALL�rr�/usr/lib/python3.6/dbus.py�<module>sBconfig/__pycache__/__init__.cpython-36.pyc000064400000007036150351351710014415 0ustar003

��g�@sfddlmZddlZyejejd�Wn6ejk
r\ddlZdejd<ejejd�YnXdZddl	Z	e	j
ed�dd	lmZdZ
d
ZdZde
Zed
ZdZdZdddgZe	j	d�ZdZdd�Zed�dd�Zed�dZdZdZdZdZd Zd!d"d#d$d%d&d'd(d)d*�	Zd+d,d-d.d/gZ d0d1d2gZ!d3d4gZ"d5Z#d6Z$d7Z%d7Z&d8Z'd7Z(d8Z)d/Z*d1Z+d3Z,d7Z-d7Z.d7Z/dS)9�)�absolute_importN��C�LC_ALLZ	firewalld)Zdomain�)�dbuszfirewall-configzfirewall-appletz/usr/share/z.gladez(C) 2010-2017 Red Hat, Inc.z0.9.11z$Thomas Woerner <twoerner@redhat.com>z"Jiri Popelka <jpopelka@redhat.com>zEric Garver <e@erig.me>acThis 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/>.zhttp://www.firewalld.orgcCsP|a|da|da|da|da|da|da|da|da|d	a	dS)
Nz/firewalld.confz/zonesz	/servicesz
/icmptypesz/ipsetsz/helpersz	/policiesz/direct.xmlz/lockdown-whitelist.xml)
Z
ETC_FIREWALLDZFIREWALLD_CONFZETC_FIREWALLD_ZONESZETC_FIREWALLD_SERVICESZETC_FIREWALLD_ICMPTYPESZETC_FIREWALLD_IPSETSZETC_FIREWALLD_HELPERSZETC_FIREWALLD_POLICIESZFIREWALLD_DIRECTZLOCKDOWN_WHITELIST)�path�r	�/usr/lib/python3.6/__init__.py�set_system_config_pathsBsrz/etc/firewalldcCs8|a|da|da|da|da|da|dadS)Nz/zonesz	/servicesz
/icmptypesz/ipsetsz/helpersz	/policies)ZUSR_LIB_FIREWALLDZFIREWALLD_ZONESZFIREWALLD_SERVICESZFIREWALLD_ICMPTYPESZFIREWALLD_IPSETSZFIREWALLD_HELPERSZFIREWALLD_POLICIES)rr	r	r
�set_default_config_pathsSsrz/usr/lib/firewalldz/var/log/firewalldz/var/run/firewalld.pidz/run/firewalldz/etc/sysconfigz/etc/sysconfig/network-scriptsz/etc/sysctl.confz/usr/sbin/iptablesz/usr/sbin/iptables-restorez/usr/sbin/ip6tablesz/usr/sbin/ip6tables-restorez/usr/sbin/ebtablesz/usr/sbin/ebtables-restorez/usr/sbin/ipsetz/sbin/modprobez/sbin/rmmod)	Zipv4zipv4-restoreZipv6zipv6-restoreZebz
eb-restoreZipsetZmodprobeZrmmod�allZunicastZ	broadcastZ	multicastZoff�yes�no�systemZnftablesZiptablesZpublic�dTF)0Z
__future__rZlocale�	setlocaler�Error�os�environZDOMAIN�gettextZinstallrrZDAEMON_NAMEZCONFIG_NAMEZAPPLET_NAMEZDATADIRZCONFIG_GLADE_NAMEZ	COPYRIGHT�VERSIONZAUTHORS�LICENSEZWEBSITErrZFIREWALLD_LOGFILEZFIREWALLD_PIDFILEZFIREWALLD_TEMPDIRZSYSCONFIGDIRZIFCFGDIRZ
SYSCTL_CONFIGZCOMMANDSZLOG_DENIED_VALUESZAUTOMATIC_HELPERS_VALUESZFIREWALL_BACKEND_VALUESZ
FALLBACK_ZONEZFALLBACK_MINIMAL_MARKZFALLBACK_CLEANUP_ON_EXITZ FALLBACK_CLEANUP_MODULES_ON_EXITZFALLBACK_LOCKDOWNZFALLBACK_IPV6_RPFILTERZFALLBACK_INDIVIDUAL_CALLSZFALLBACK_LOG_DENIEDZFALLBACK_AUTOMATIC_HELPERSZFALLBACK_FIREWALL_BACKENDZFALLBACK_FLUSH_ALL_ON_RELOADZFALLBACK_RFC3964_IPV4ZFALLBACK_ALLOW_ZONE_DRIFTINGr	r	r	r
�<module>sv

config/__pycache__/__init__.cpython-36.opt-1.pyc000064400000007036150351351710015354 0ustar003

��g�@sfddlmZddlZyejejd�Wn6ejk
r\ddlZdejd<ejejd�YnXdZddl	Z	e	j
ed�dd	lmZdZ
d
ZdZde
Zed
ZdZdZdddgZe	j	d�ZdZdd�Zed�dd�Zed�dZdZdZdZdZd Zd!d"d#d$d%d&d'd(d)d*�	Zd+d,d-d.d/gZ d0d1d2gZ!d3d4gZ"d5Z#d6Z$d7Z%d7Z&d8Z'd7Z(d8Z)d/Z*d1Z+d3Z,d7Z-d7Z.d7Z/dS)9�)�absolute_importN��C�LC_ALLZ	firewalld)Zdomain�)�dbuszfirewall-configzfirewall-appletz/usr/share/z.gladez(C) 2010-2017 Red Hat, Inc.z0.9.11z$Thomas Woerner <twoerner@redhat.com>z"Jiri Popelka <jpopelka@redhat.com>zEric Garver <e@erig.me>acThis 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/>.zhttp://www.firewalld.orgcCsP|a|da|da|da|da|da|da|da|da|d	a	dS)
Nz/firewalld.confz/zonesz	/servicesz
/icmptypesz/ipsetsz/helpersz	/policiesz/direct.xmlz/lockdown-whitelist.xml)
Z
ETC_FIREWALLDZFIREWALLD_CONFZETC_FIREWALLD_ZONESZETC_FIREWALLD_SERVICESZETC_FIREWALLD_ICMPTYPESZETC_FIREWALLD_IPSETSZETC_FIREWALLD_HELPERSZETC_FIREWALLD_POLICIESZFIREWALLD_DIRECTZLOCKDOWN_WHITELIST)�path�r	�/usr/lib/python3.6/__init__.py�set_system_config_pathsBsrz/etc/firewalldcCs8|a|da|da|da|da|da|dadS)Nz/zonesz	/servicesz
/icmptypesz/ipsetsz/helpersz	/policies)ZUSR_LIB_FIREWALLDZFIREWALLD_ZONESZFIREWALLD_SERVICESZFIREWALLD_ICMPTYPESZFIREWALLD_IPSETSZFIREWALLD_HELPERSZFIREWALLD_POLICIES)rr	r	r
�set_default_config_pathsSsrz/usr/lib/firewalldz/var/log/firewalldz/var/run/firewalld.pidz/run/firewalldz/etc/sysconfigz/etc/sysconfig/network-scriptsz/etc/sysctl.confz/usr/sbin/iptablesz/usr/sbin/iptables-restorez/usr/sbin/ip6tablesz/usr/sbin/ip6tables-restorez/usr/sbin/ebtablesz/usr/sbin/ebtables-restorez/usr/sbin/ipsetz/sbin/modprobez/sbin/rmmod)	Zipv4zipv4-restoreZipv6zipv6-restoreZebz
eb-restoreZipsetZmodprobeZrmmod�allZunicastZ	broadcastZ	multicastZoff�yes�no�systemZnftablesZiptablesZpublic�dTF)0Z
__future__rZlocale�	setlocaler�Error�os�environZDOMAIN�gettextZinstallrrZDAEMON_NAMEZCONFIG_NAMEZAPPLET_NAMEZDATADIRZCONFIG_GLADE_NAMEZ	COPYRIGHT�VERSIONZAUTHORS�LICENSEZWEBSITErrZFIREWALLD_LOGFILEZFIREWALLD_PIDFILEZFIREWALLD_TEMPDIRZSYSCONFIGDIRZIFCFGDIRZ
SYSCTL_CONFIGZCOMMANDSZLOG_DENIED_VALUESZAUTOMATIC_HELPERS_VALUESZFIREWALL_BACKEND_VALUESZ
FALLBACK_ZONEZFALLBACK_MINIMAL_MARKZFALLBACK_CLEANUP_ON_EXITZ FALLBACK_CLEANUP_MODULES_ON_EXITZFALLBACK_LOCKDOWNZFALLBACK_IPV6_RPFILTERZFALLBACK_INDIVIDUAL_CALLSZFALLBACK_LOG_DENIEDZFALLBACK_AUTOMATIC_HELPERSZFALLBACK_FIREWALL_BACKENDZFALLBACK_FLUSH_ALL_ON_RELOADZFALLBACK_RFC3964_IPV4ZFALLBACK_ALLOW_ZONE_DRIFTINGr	r	r	r
�<module>sv

config/__pycache__/dbus.cpython-36.pyc000064400000002737150351351710013616 0ustar003

��g
�@sdZdZdeZedZedZedZedZedZedZedZ	edZ
ed	Zed
ZedZ
edZedZedZdeZed
ZedZedZedZedZedZedZdeZedZedZedZedZedZedZedZ edZ!dS)��zorg.fedoraproject.FirewallD%dz.zonez.policyz.directz	.policiesz.ipsetz.configz.servicez	.icmptypez.helperz/org/fedoraproject/FirewallD%dz/configz/config/icmptypez/config/servicez/config/zonez/config/policyz
/config/ipsetz/config/helperz.infoz.allN)"ZDBUS_INTERFACE_VERSIONZDBUS_INTERFACE_REVISIONZDBUS_INTERFACEZDBUS_INTERFACE_ZONEZDBUS_INTERFACE_POLICYZDBUS_INTERFACE_DIRECTZDBUS_INTERFACE_POLICIESZDBUS_INTERFACE_IPSETZDBUS_INTERFACE_CONFIGZDBUS_INTERFACE_CONFIG_ZONEZDBUS_INTERFACE_CONFIG_POLICYZDBUS_INTERFACE_CONFIG_SERVICEZDBUS_INTERFACE_CONFIG_ICMPTYPEZDBUS_INTERFACE_CONFIG_POLICIESZDBUS_INTERFACE_CONFIG_DIRECTZDBUS_INTERFACE_CONFIG_IPSETZDBUS_INTERFACE_CONFIG_HELPERZ	DBUS_PATHZDBUS_PATH_CONFIGZDBUS_PATH_CONFIG_ICMPTYPEZDBUS_PATH_CONFIG_SERVICEZDBUS_PATH_CONFIG_ZONEZDBUS_PATH_CONFIG_POLICYZDBUS_PATH_CONFIG_IPSETZDBUS_PATH_CONFIG_HELPERZ
_PK_ACTIONZPK_ACTION_POLICIESZPK_ACTION_POLICIES_INFOZPK_ACTION_CONFIGZPK_ACTION_CONFIG_INFOZPK_ACTION_DIRECTZPK_ACTION_DIRECT_INFOZPK_ACTION_INFOZ
PK_ACTION_ALL�rr�/usr/lib/python3.6/dbus.py�<module>sB__pycache__/functions.cpython-36.opt-1.pyc000064400000036460150351351710014363 0ustar003

��g'K�#@sdddddddddd	d
ddd
ddddddddddddddddddd d!d"g#Zd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d%l	m
Z
d#d&lmZm
Z
ejd'kZd(d)�ed#d*�D�Zd+d�Zd,d�ZdXd.d�Zd/d0�Zd1d2�Zd3d4�Zd5d�Zd6d�Zd7d8�Zd9d�Zd:d�Zd;d"�Zd<d�Zd=d	�Zd>d
�Z d?d�Z!d@d�Z"dAd
�Z#dBd�Z$dCd�Z%dDd�Z&dEdF�Z'dGd�Z(dHd�Z)dId�Z*dJd�Z+dKd�Z,dLd�Z-dMd!�Z.dNd�Z/dOd�Z0dPd�Z1dQd�Z2dRd�Z3dSd�Z4dTd�Z5dUd�Z6dVd�Z7dWd �Z8d$S)Y�PY2�	getPortID�getPortRange�portStr�getServiceName�checkIP�checkIP6�checkIPnMask�
checkIP6nMask�
checkProtocol�checkInterface�checkUINT32�firewalld_is_active�tempFile�readfile�	writefile�enable_ip_forwarding�
check_port�
check_address�check_single_address�	check_mac�uniqify�ppid_of_pid�max_zone_name_len�	checkUser�checkUid�checkCommand�checkContext�joinArgs�	splitArgs�b2u�u2b�
u2b_if_py2�max_policy_name_len�stripNonPrintableCharacters�N)�log)�FIREWALLD_TEMPDIR�FIREWALLD_PIDFILE�3cCs"i|]}|dko|dksd|�qS)��N�)�.0�ir+r+�/usr/lib/python3.6/functions.py�
<dictcomp>.sr/�cCstt|t�r|}nT|r|j�}yt|�}Wn:tk
rbytj|�}Wntjk
r\dSXYnX|dkrpdS|S)z� Check and Get port id from port string or port id using socket.getservbyname

    @param port port string or port id
    @return Port id if valid, -1 if port can not be found and -2 if port is too big
    �i���������)�
isinstance�int�strip�
ValueError�socketZ
getservbyname�error)�portZ_idr+r+r.r7s
cCs�t|t�st|t�r|St|t�s*|j�rDt|�}|dkr@|fS|S|jd�}t|�dkr�|dj�r�|dj�r�t|d�}t|d�}|dkr�|dkr�||kr�||fS||kr�||fS|fSg}x�tt|�dd�D]�}tdj	|d|���}dj	||d��}t|�dk�rnt|�}|dk�r�|dk�r�||k�rF|j
||f�n&||k�r`|j
||f�n|j
|f�q�|dkr�|j
|f�|t|�kr�Pq�Wt|�dk�r�dSt|�dk�r�dS|dS)aI Get port range for port range string or single port id

    @param ports an integer or port string or port range string
    @return Array containing start and end port id for a valid range or -1 if port can not be found and -2 if port is too big for integer input or -1 for invalid ranges or None if the range is ambiguous.
    r$�-r2r1Nr3r3)r5�tuple�listr6�isdigitr�split�len�range�join�append)ZportsZid1�splitsZid2Zmatchedr-Zport2r+r+r.rNsL
$

�:cCsX|dkrdSt|�}t|t�r*|dkr*dSt|�dkr>d|Sd|d||dfSdS)a Create port and port range string

    @param port port or port range int or [int, int]
    @param delimiter of the output string for port ranges, default ':'
    @return Port or port range string, empty string if port isn't specified, None if port or port range is not valid
    �r$Nr1z%sz%s%s%s)rr5r6rA)r;Z	delimiter�_ranger+r+r.r�scCst|�}t|�}t|�dkr�t|�dkr@t|d�t|d�kSt|�dkr�t|d�t|d�kr�t|d�t|d�kr�dSn|t|�dkr�t|�dkr�t|d�t|d�kr�t|d�t|d�kr�t|d�t|d�kr�t|d�t|d�kr�dSdS)Nr1r$r2TF)rrAr)r;rBZ_portrHr+r+r.�portInPortRange�s000rIcCsTt|�}t|�dkr$|d|df}tt|�}ttdd�|�dd�d�}g}x�|D]�}|d|dkr�|d|dkr�|j|�qR|d|dkr�|d|dkr�|d|dkr�|j|�|d|df}qR|d|dko�|d|dko�|d|dkrR|j|�|d|df}qRWttdd�|��}|d|dk�rJ|df}|g|fS)z� Coalesce a port range with existing list of port ranges

        @param new_range tuple/list/string
        @param ranges list of tuple/list/string
        @return tuple of (list of ranges added after coalescing, list of removed original ranges)
    r1r$cSs t|�dkr|d|dfS|S)Nr1r$)rA)�xr+r+r.�<lambda>�sz#coalescePortRange.<locals>.<lambda>cSs|dS)Nr$r+)rJr+r+r.rK�s)�keycSs|d|dkr|dfS|S)Nr$r1r+)rJr+r+r.rK�s)rrA�map�sortedrDr>)Z	new_range�rangesZcoalesced_range�_ranges�removed_rangesrBr+r+r.�coalescePortRange�s*

  
 

rRcCs�t|�}t|�dkr$|d|df}tt|�}ttdd�|�dd�d�}g}g}�xJ|D�]@}|d|dkr�|d|dkr�|j|�qX|d|dkr�|d|dkr�|d|dkr�|j|�|j|dd|df�qX|d|dk�r<|d|dk�r<|d|dk�r<|j|�|j|d|ddf�qX|d|dkrX|d|dkrX|j|�|j|d|ddf�|j|dd|df�qXWttdd�|��}ttdd�|��}||fS)	z� break a port range from existing list of port ranges

        @param remove_range tuple/list/string
        @param ranges list of tuple/list/string
        @return tuple of (list of ranges added after breaking up, list of removed original ranges)
    r1r$cSs t|�dkr|d|dfS|S)Nr1r$)rA)rJr+r+r.rK�sz breakPortRange.<locals>.<lambda>cSs|dS)Nr$r+)rJr+r+r.rK�s)rLcSs|d|dkr|dfS|S)Nr$r1r+)rJr+r+r.rK�scSs|d|dkr|dfS|S)Nr$r1r+)rJr+r+r.rK�s)rrArMrNrDr>)Zremove_rangerOrPrQZadded_rangesrBr+r+r.�breakPortRange�s2
  
$
 
rScCs0ytjt|�|�}Wntjk
r*dSX|S)z� Check and Get service name from port and proto string combination using socket.getservbyport

    @param port string or id
    @param protocol string
    @return Service name if port and protocol are valid, else None
    N)r9Z
getservbyportr6r:)r;�proto�namer+r+r.r�s
cCs.ytjtj|�Wntjk
r(dSXdS)zl Check IPv4 address.
    
    @param ip address string
    @return True if address is valid, else False
    FT)r9�	inet_ptonZAF_INETr:)�ipr+r+r.rs
cCs
|jd�S)z� Normalize the IPv6 address

    This is mostly about converting URL-like IPv6 address to normal ones.
    e.g. [1234::4321] --> 1234:4321
    z[])r7)rWr+r+r.�normalizeIP6srXcCs2ytjtjt|��Wntjk
r,dSXdS)zl Check IPv6 address.
    
    @param ip address string
    @return True if address is valid, else False
    FT)r9rVZAF_INET6rXr:)rWr+r+r.r s
cCs�d|krN|d|jd��}||jd�dd�}t|�dksHt|�dkrVdSn|}d}t|�sbdS|r�d|krvt|�Syt|�}Wntk
r�dSX|dks�|dkr�dSdS)N�/r1F�.r$� T)�indexrArr6r8)rW�addr�maskr-r+r+r.r-s&cCs
|jt�S)N)�	translate�NOPRINT_TRANS_TABLE)Zrule_strr+r+r.r#DscCs�d|krN|d|jd��}||jd�dd�}t|�dksHt|�dkrVdSn|}d}t|�sbdS|r�yt|�}Wntk
r�dSX|dks�|dkr�dSdS)NrYr1Fr$�T)r\rArr6r8)rWr]r^r-r+r+r.r	Gs"cCs`yt|�}Wn:tk
rFytj|�Wntjk
r@dSXYnX|dksX|dkr\dSdS)NFr$�T)r6r8r9Zgetprotobynamer:)Zprotocolr-r+r+r.r
\scCs4|st|�dkrdSxdD]}||krdSqWdS)	z� Check interface string

    @param interface string
    @return True if interface is valid (maximum 16 chars and does not contain ' ', '/', '!', ':', '*'), else False
    �F� rY�!�*T)rdrYrerf)rA)Ziface�chr+r+r.rks
cCs<yt|d�}Wntk
r"dSX|dkr8|dkr8dSdS)Nr$Fl��T)r6r8)�valrJr+r+r.r~scCs�tjjt�sdSy"ttd��}|j�}WdQRXWntk
rFdSXtjjd|�s\dSy&td|d��}|j�}WdQRXWntk
r�dSXd|kr�dSdS)zv Check if firewalld is active

    @return True if there is a firewalld pid file and the pid is used by firewalld
    F�rNz/proc/%sz/proc/%s/cmdlineZ	firewalldT)�os�path�existsr'�open�readline�	Exception)�fd�pidZcmdliner+r+r.r
�s"cCsby*tjjt�stjtd�tjddtdd�Stk
r\}ztj	d|��WYdd}~XnXdS)Ni�Zwtztemp.F)�mode�prefix�dir�deletez#Failed to create temporary file: %s)
rjrkrlr&�mkdir�tempfileZNamedTemporaryFileror%r:)�msgr+r+r.r�s
cCsXyt|d��
}|j�SQRXWn4tk
rR}ztjd||f�WYdd}~XnXdS)NrizFailed to read file "%s": %s)rm�	readlinesror%r:)�filename�f�er+r+r.r�s$cCs\y$t|d��}|j|�WdQRXWn2tk
rV}ztjd||f�dSd}~XnXdS)N�wz Failed to write to file "%s": %sFT)rm�writeror%r:)rz�liner{r|r+r+r.r�scCs(|dkrtdd�S|dkr$tdd�SdS)N�ipv4z/proc/sys/net/ipv4/ip_forwardz1
�ipv6z&/proc/sys/net/ipv6/conf/all/forwardingF)r)�ipvr+r+r.r�s


cCs|jdd�jdd�S)N�_r<z
nf-conntrack-rG)�replace)�moduler+r+r.�get_nf_conntrack_short_name�sr�cCs�t|�}|d
ks<|dks<|dks<t|�dkr�|d|dkr�|dkrTtjd|�nZ|d
krltjd|�nB|dkr�tjd|�n*t|�dkr�|d|dkr�tjd|�dSd	S)Nr2r1r$z'%s': port > 65535z'%s': port is invalidz'%s': port is ambiguousz'%s': range start >= endFTr4r3r4r3)rrAr%Zdebug2)r;rHr+r+r.r�scCs(|dkrt|�S|dkr t|�SdSdS)Nr�r�F)rr	)r��sourcer+r+r.r�s
cCs(|dkrt|�S|dkr t|�SdSdS)Nr�r�F)rr)r�r�r+r+r.r�s
cCsRt|�dkrNxdD]}||dkrdSqWxdD]}||tjkr0dSq0WdSdS)N��r2���rFFr$r1�����	�
�
�rcT�)r2r�r�r�r�)r$r1r�r�r�r�r�r�r�r�r�rc)rA�stringZ	hexdigits)Zmacr-r+r+r.r�s

cCs(g}x|D]}||kr
|j|�q
W|S)N)rD)Z_list�outputrJr+r+r.r�s

cCsHy.tjd|�}t|j�dj��}|j�Wntk
rBdSX|S)z Get parent for pid zps -o ppid -h -p %d 2>/dev/nullr$N)rj�popenr6ryr7�closero)rqr{r+r+r.r�scCsBddlm}ddlm}ttt|j���}d|t|�td�S)z�
    iptables limits length of chain to (currently) 28 chars.
    The longest chain we create is POST_<policy>_allow,
    which leaves 28 - 11 = 17 chars for <policy>.
    r$)�POLICY_CHAIN_PREFIX)�	SHORTCUTS�Z_allow)Zfirewall.core.ipXtablesr��firewall.core.baser��maxrMrA�values)r�r��longest_shortcutr+r+r.r"	scCs.ddlm}ttt|j���}d|td�S)z�
    Netfilter limits length of chain to (currently) 28 chars.
    The longest chain we create is FWDI_<zone>_allow,
    which leaves 28 - 11 = 17 chars for <zone>.
    r$)r�r�Z__allow)r�r�r�rMrAr�)r�r�r+r+r.rscCsTt|�dkst|�tjd�kr"dSx,|D]$}|tjkr(|tjkr(|d	kr(dSq(WdS)
Nr1�SC_LOGIN_NAME_MAXFrZr<r��$T)rZr<r�r�)rArj�sysconfr�Z
ascii_lettersZdigits)�user�cr+r+r.rs


cCsDt|t�r,yt|�}Wntk
r*dSX|dkr@|dkr@dSdS)	NFr$r2r)r1Tli���)r5�strr6r8)Zuidr+r+r.r(s
cCsJt|�dkst|�dkrdSxd
D]}||kr"dSq"W|ddkrFdSd	S)Nr1iF�|�
�r$rYT)r�r�r�)rA)Zcommandrgr+r+r.r2s
cCs�|jd�}t|�dkrdS|ddkr>|ddd�dkr>dS|d	dd�d
krVdS|ddd�dkrndSt|d�d	kr�dSd
S)NrFr�r�Fr$�rootr2Z_ur1Z_rZ_tr�T)r�r�r4r4r4)r@rA)�contextrEr+r+r.r<s
 cCs8dtt�kr djdd�|D��Sdjdd�|D��SdS)N�quoterdcss|]}tj|�VqdS)N)�shlexr�)r,�ar+r+r.�	<genexpr>PszjoinArgs.<locals>.<genexpr>css|]}tj|�VqdS)N)�pipesr�)r,r�r+r+r.r�Rs)rtr�rC)�argsr+r+r.rNscCs8tr*t|t�r*t|�}tj|�}tt|�Stj|�SdS)N)rr5�unicoder r�r@rMr)�_stringrEr+r+r.rTs


cCst|t�r|jdd�S|S)z bytes to unicode zUTF-8r�)r5�bytes�decode)r�r+r+r.r]s
cCst|t�s|jdd�S|S)z unicode to bytes zUTF-8r�)r5r��encode)r�r+r+r.r cs
cCstrt|t�r|jdd�S|S)z" unicode to bytes only if Python 2zUTF-8r�)rr5r�r�)r�r+r+r.r!is)rF)9�__all__r9rjZos.pathr�r�r��sysrwZfirewall.core.loggerr%Zfirewall.configr&r'�versionrrBr`rrrrIrRrSrrrXrrr#r	r
rrr
rrrrr�rrrrrrr"rrrrrrrrr r!r+r+r+r.�<module>sz

:
&+


	




	__pycache__/dbus_utils.cpython-36.opt-1.pyc000064400000013117150351351710014522 0ustar003

��gJ�@s�dddddddddd	d
gZddlZddlZddlZdd
lmZddlmZejdkZ	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zddd�Zdd�Zddd	�Zdd
�ZdS)�command_of_pid�
pid_of_sender�
uid_of_sender�user_of_uid�context_of_sender�command_of_sender�user_of_sender�dbus_to_python�dbus_signature�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties�N)�minidom)�log�3cCsPy6td|d��}|j�djdd�j�}WdQRXWntk
rJdSX|S)z  Get command for pid from /proc z/proc/%d/cmdline�rr�� N)�open�	readlines�replace�strip�	Exception)�pid�f�cmd�r� /usr/lib/python3.6/dbus_utils.pyr%s&cCsD|jdd�}tj|d�}yt|j|��}Wntk
r>dSX|S)zW Get pid from sender string using 
    org.freedesktop.DBus.GetConnectionUnixProcessID zorg.freedesktop.DBusz/org/freedesktop/DBusN)�
get_object�dbus�	Interface�intZGetConnectionUnixProcessID�
ValueError)�bus�sender�dbus_obj�
dbus_ifacerrrrr.scCsD|jdd�}tj|d�}yt|j|��}Wntk
r>dSX|S)zV Get user id from sender string using 
    org.freedesktop.DBus.GetConnectionUnixUser zorg.freedesktop.DBusz/org/freedesktop/DBusN)rrrr ZGetConnectionUnixUserr!)r"r#r$r%�uidrrrr;scCs,ytj|�}Wntk
r"dSX|dS)z Get user for uid from pwd Nr)�pwd�getpwuidr)r&ZpwsrrrrHs
c
CsP|jdd�}tj|d�}y|j|�}Wntk
r:dSXdjttt|���S)zl Get SELinux context from sender string using 
    org.freedesktop.DBus.GetConnectionSELinuxSecurityContext zorg.freedesktop.DBusz/org/freedesktop/DBusN�)	rrrZ#GetConnectionSELinuxSecurityContextr�join�map�chrr)r"r#r$r%�contextrrrrQscCstt||��S)z  Return command of D-Bus sender )rr)r"r#rrrr_scCstt||��S)N)rr)r"r#rrrrdscCs�|dkr|}�n�t|tj�r(t|�}�n�t|tj�rNtrB|jd�nt|�}�n�trjt|tj�rjt|�}�ndt|tj	�r�t|�}�nLt|tj
�s�t|tj�s�t|tj�s�t|tj
�s�t|tj�s�t|tj�s�t|tj�r�t|�}n�t|tj�r�t|�}n�t|tj��rdd�|D�}n�t|tj��r6tdd�|D��}n�t|tj��rXdd�|j�D�}nvt|t��s�t|t��s�t|t��s�t|t��s�t|t��s�t|t��s�t|t��s�t|t��r�|}ntdt|���|dk	�r�|tk�r�t|t��s�|tk�rt|t��s�|tk�r t|t��s�|tk�r8t|t��s�|tk�rPt|t��s�|tk�rht|t��s�|tk�r�t|t��r�td|t|�|f��|S)	Nzutf-8cSsg|]}t|��qSr)r)�.0�xrrr�
<listcomp>}sz"dbus_to_python.<locals>.<listcomp>cSsg|]}t|��qSr)r)r.r/rrrr0scSsi|]\}}t|�t|��qSr)r)r.�k�vrrr�
<dictcomp>�sz"dbus_to_python.<locals>.<dictcomp>zUnhandled %sz%s is %s, expected %s)�
isinstancer�Boolean�bool�String�PY2�encode�str�
UTF8String�
ObjectPath�Byte�Int16�Int32�Int64�UInt16�UInt32�UInt64r �Double�float�Array�Struct�tuple�
Dictionary�items�bytes�list�dict�	TypeError�repr�type)�objZ
expected_typeZ
python_objrrrrgsV


cCs>t|tj�rdSt|tj�r dSt|tj�r0dSt|tj�r@dSt|tj�rPdSt|tj�r`dSt|tj�rpdSt|tj	�r�dSt|tj
�r�d	St|tj�r�d
St|tj�r�dSt|tj
��r�t|j�dkr�d
|jSd|jSnXt|tj��r�d|jSt|tj��rd|jSt�r*t|tj��r*dStdt|���dS)N�b�s�o�y�n�ir/�q�u�t�d�za(%s)za%sz(%s)za{%s}zUnhandled %s)r4rr5r7r<r=r>r?r@rArBrCrDrF�lenZ	signaturerGrIr8r;rNrO)rQrrrr	�sB


cCs�|dkri}t|d�s"t|di�t|d�}i||<y|j|�}Wntk
rZi}YnXxV|j�D]J\}}dt|�i|||<||kr�|||||d<qfd|||d<qfWdS)N�_fw_dbus_propertiesrP�access�read)�hasattr�setattr�getattrZGetAllrrJr	)rQ�	interfacer_�dipZ_dict�key�valuerrrr
�s


c
Cs�tj|�}t|d�r�x�|jd�D]�}|jd�r |jd�|kr i}t|d�rTt|d�}||kr xX||j�D]H\}}|jd�}|j	d|�|j	d|d�|j	d|d�|j
|�qjWq Wtj|j
��|j
�}	|j�|	S)Nr^rd�name�propertyrPr_)r
ZparseStringraZgetElementsByTagNameZhasAttributeZgetAttributercrJZ
createElementZsetAttributeZappendChildrZdebug10Ztoxml�unlink)
rQ�datard�docZnodererfrgZpropZnew_datarrrr�s&





)N)N)�__all__rr'�sysZxml.domr
Zfirewall.core.loggerr�versionr8rrrrrrrrr	r
rrrrr�<module>s*
	

	
0%
__pycache__/errors.cpython-36.opt-1.pyc000064400000007340150351351710013662 0ustar003

��g��@s�dZdZdZdZdZdZdZdZdZd	Z	d
Z
dZdZd
Z
dZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZd Z d!Z!d"Z"d#Z#d$Z$d%Z%d&Z&d'Z'd(Z(d)Z)d*Z*d+Z+d,Z,d-Z-d.Z.d/Z/d0Z0d1Z1d2Z2d3Z3d4Z4d5Z5d6Z6d7Z7d8Z8d9Z9d:Z:d;Z;d<Z<d=Z=d>Z>d?Z?d@Z@dAZAdBZBdCZCdDZDdEZEdFZFdGZGdHZHdIZIdJZJdKZKdLZLdMZMdNZNdOZOdPZPdQdRlQZQGdSdT�dTeR�ZSeQjTeSjUZVdUdV�eWeV�D�eS_XdWdV�eSjXD�eS_YdRS)X���
������������������� �!�"�#�$�%�&�d�e�f�g�h�i�j�k�l�m�n�o�p�q�r�s�t�u�v�w�x�y�z�{�|�}�~�����������������������������������Nc@s6eZdZd
dd�Zdd�Zdd�Zdd	�Zee�ZdS)�
FirewallErrorNcCsR||_|dk	rHtjdkrHyt|�}Wn"tk
rFt|�jd�}YnX||_dS)N�3Zunicode_escape)�code�sys�version�str�UnicodeEncodeErrorZunicode�encode�msg)�selfrUr[�x�r^�/usr/lib/python3.6/errors.py�__init__ns
zFirewallError.__init__cCsd|j|j|jfS)Nz
%s(%r, %r))�	__class__rUr[)r\r^r^r_�__repr__yszFirewallError.__repr__cCs(|jrd|j|j|jfS|j|jS)Nz%s: %s)r[�errorsrU)r\r^r^r_�__str__|szFirewallError.__str__cCsPd|kr |jd�}|d|�}n|}ytj|}Wntk
rJt}YnX|S)N�:)�indexrS�codes�KeyError�
UNKNOWN_ERROR)r[�idxZecoderUr^r^r_�get_code�s

zFirewallError.get_code)N)�__name__�
__module__�__qualname__r`rbrdrk�staticmethodr^r^r^r_rSms

rScCs6i|].}|jd�rttt|��tkr|tt|��qS)�_)�
startswith�type�getattr�mod�int)�.0Zvarnamer^r^r_�
<dictcomp>�srwcCsi|]}|tj|�qSr^)rSrc)rvrUr^r^r_rw�s)ZZALREADY_ENABLEDZNOT_ENABLEDZCOMMAND_FAILEDZNO_IPV6_NATZ
PANIC_MODEZZONE_ALREADY_SETZUNKNOWN_INTERFACEZ
ZONE_CONFLICTZ
BUILTIN_CHAINZEBTABLES_NO_REJECTZNOT_OVERLOADABLEZNO_DEFAULTSZBUILTIN_ZONEZBUILTIN_SERVICEZBUILTIN_ICMPTYPEZ
NAME_CONFLICTZ
NAME_MISMATCHZPARSE_ERRORZ
ACCESS_DENIEDZUNKNOWN_SOURCEZRT_TO_PERM_FAILEDZIPSET_WITH_TIMEOUTZ
BUILTIN_IPSETZALREADY_SETZMISSING_IMPORTZ
DBUS_ERRORZBUILTIN_HELPERZNOT_APPLIEDZINVALID_ACTIONZINVALID_SERVICEZINVALID_PORTZINVALID_PROTOCOLZINVALID_INTERFACEZINVALID_ADDRZINVALID_FORWARDZINVALID_ICMPTYPEZ
INVALID_TABLEZ
INVALID_CHAINZINVALID_TARGETZINVALID_IPVZINVALID_ZONEZINVALID_PROPERTYZ
INVALID_VALUEZINVALID_OBJECTZINVALID_NAMEZINVALID_FILENAMEZINVALID_DIRECTORYZINVALID_TYPEZINVALID_SETTINGZINVALID_DESTINATIONZINVALID_RULEZ
INVALID_LIMITZINVALID_FAMILYZINVALID_LOG_LEVELZINVALID_AUDIT_TYPEZINVALID_MARKZINVALID_CONTEXTZINVALID_COMMANDZINVALID_USERZINVALID_UIDZINVALID_MODULEZINVALID_PASSTHROUGHZINVALID_MACZ
INVALID_IPSETZ
INVALID_ENTRYZINVALID_OPTIONZINVALID_HELPERZINVALID_PRIORITYZINVALID_POLICYZ
MISSING_TABLEZ
MISSING_CHAINZMISSING_PORTZMISSING_PROTOCOLZMISSING_ADDRZMISSING_NAMEZMISSING_SETTINGZMISSING_FAMILYZRUNNING_BUT_FAILEDZNOT_RUNNINGZNOT_AUTHORIZEDrirV�	ExceptionrS�modulesrmrt�dirrcrgr^r^r^r_�<module>s�$__pycache__/client.cpython-36.pyc000064400000426232150351351710012672 0ustar003

��g��@s�ddlmZmZddlZeejd<ddlZddlZddl	m	Z	ddl
mZddlm
Z
mZmZddlmZddlmZdd	lmZdd
lmZmZmZddl
mZddlmZddlZddlZdad
ae	dd��Z Gdd�de!�Z"Gdd�de!�Z#Gdd�de!�Z$Gdd�de!�Z%Gdd�de!�Z&Gdd�de!�Z'Gdd�de!�Z(Gdd�de!�Z)Gd d!�d!e!�Z*Gd"d#�d#e!�Z+Gd$d%�d%e!�Z,Gd&d'�d'e!�Z-Gd(d)�d)e!�Z.Gd*d+�d+e!�Z/Gd,d-�d-e!�Z0Gd.d/�d/e!�Z1Gd0d1�d1e!�Z2Gd2d3�d3e!�Z3dS)4�)�GLib�GObjectNZgobject)�	decorator)�config)�DEFAULT_ZONE_TARGET�DEFAULT_POLICY_TARGET�DEFAULT_POLICY_PRIORITY)�dbus_to_python)�b2u)�	Rich_Rule)�normalize_ipset_entry�check_entry_overlaps_existing�check_for_overlapping_entries)�errors)�
FirewallErrorFcOsd}�x|�sy
|||�Stjjk
r�}zb|j�}|j�}tsD�d|krVtd�n4d|krht|�n"d}|rzt|�nttt|���WYdd}~Xnftk
r�}zts��nttt|���WYdd}~Xn.t	k
�r�ts�nttt
j���YnXtsPqWdS)z#Decorator to handle exceptions
    FZNotAuthorizedExceptionzorg.freedesktop.DBus.ErrorTN)
�dbus�
exceptions�
DBusException�get_dbus_messageZ
get_dbus_name�exception_handlerr
�strr�	Exception�	traceback�
format_exc�not_authorized_loop)�func�args�kwargsZ
authorized�eZdbus_messageZ	dbus_name�r�/usr/lib/python3.6/client.py�handle_exceptions0s6




  r!c@s�eZdZed�dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��Zed*d+��Zed,d-��Zed.d/��Zed0d1��Zed2d3��Zed4d5��Zed6d7��Zed8d9��Zed:d;��Z ed<d=��Z!ed>d?��Z"ed@dA��Z#edBdC��Z$edDdE��Z%edFdG��Z&edHdI��Z'edJdK��Z(edLdM��Z)edNdO��Z*edPdQ��Z+edRdS��Z,edTdU��Z-e.j/j0j1edVdW���Z2e.j/j0j1edXdY���Z3e.j/j0j1edZd[���Z4ed\d]��Z5ed^d_��Z6e.j/j0j1ed`da���Z7e.j/j0j1edbdc���Z8e.j/j0j1eddde���Z9edfdg��Z:edhdi��Z;e.j/j0j1edjdk���Z<e.j/j0j1edldm���Z=e.j/j0j1edndo���Z>edpdq��Z?edrds��Z@edtdu��ZAedvdw��ZBedxdy��ZCedzd{��ZDed|d}��ZEed~d��ZFed�d���ZGed�d���ZHed�d���ZIed�d���ZJed�d���ZKed�d���ZLed�d���ZMed�d���ZNed�d���ZOed�d���ZPed�d���ZQed�d���ZRdS)��FirewallClientZoneSettingsNcCs�ddddtgggdggggggddg|_ddddddd	d
ddd
ddddddg|_dddddddddddddddddg|_|r�t|t�r�x"t|�D]\}}|||j|<q�Wt|t�r�|j|�dS)N�F�version�short�description�UNUSED�target�services�ports�icmp_blocks�
masquerade�
forward_ports�
interfaces�sourcesZ	rules_str�	protocols�source_portsZicmp_block_inversion�forward�s�bz(ss)z(ssss))	r�settings�
settings_name�settings_dbus_type�
isinstance�list�	enumerate�dict�setSettingsDict)�selfr5�i�vrrr �__init__Xs(

z#FirewallClientZoneSettings.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r5)r=rrr �__repr__osz#FirewallClientZoneSettings.__repr__cCs6i}x,t|j|j�D]\}}|dkr&q|||<qW|S)Nr')�zipr6r5)r=r5�key�valuerrr �getSettingsDictssz*FirewallClientZoneSettings.getSettingsDictcCs(x"|D]}|||j|jj|�<qWdS)N)r5r6�index)r=r5rDrrr r<{s
z*FirewallClientZoneSettings.setSettingsDictcCs|i}xrt|j|j|j�D]\\}}}|dkr,qt|�tkrLtj||d�||<qt|�tkrltj	||d�||<q|||<qW|S)Nr')�	signature)
rCr6r5r7�typer9r�Arrayr;�
Dictionary)r=r5rDrE�sigrrr �getSettingsDbusDictsz.FirewallClientZoneSettings.getSettingsDbusDictcCs$|j�}|d=|d=|d=|d=|S)Nr$r%r&r()rF)r=r5rrr �getRuntimeSettingsDict�sz1FirewallClientZoneSettings.getRuntimeSettingsDictcCs$|j�}|d=|d=|d=|d=|S)Nr$r%r&r()rM)r=r5rrr �getRuntimeSettingsDbusDict�sz5FirewallClientZoneSettings.getRuntimeSettingsDbusDictcCs
|jdS)Nr)r5)r=rrr �
getVersion�sz%FirewallClientZoneSettings.getVersioncCs||jd<dS)Nr)r5)r=r$rrr �
setVersion�sz%FirewallClientZoneSettings.setVersioncCs
|jdS)N�)r5)r=rrr �getShort�sz#FirewallClientZoneSettings.getShortcCs||jd<dS)NrR)r5)r=r%rrr �setShort�sz#FirewallClientZoneSettings.setShortcCs
|jdS)N�)r5)r=rrr �getDescription�sz)FirewallClientZoneSettings.getDescriptioncCs||jd<dS)NrU)r5)r=r&rrr �setDescription�sz)FirewallClientZoneSettings.setDescriptioncCs|jdtkr|jdSdS)N��default)r5r)r=rrr �	getTarget�sz$FirewallClientZoneSettings.getTargetcCs|dkr|nt|jd<dS)NrYrX)rr5)r=r(rrr �	setTarget�sz$FirewallClientZoneSettings.setTargetcCs
|jdS)N�)r5)r=rrr �getServices�sz&FirewallClientZoneSettings.getServicescCs||jd<dS)Nr\)r5)r=r)rrr �setServices�sz&FirewallClientZoneSettings.setServicescCs0||jdkr |jdj|�nttj|��dS)Nr\)r5�appendrr�ALREADY_ENABLED)r=�servicerrr �
addService�sz%FirewallClientZoneSettings.addServicecCs0||jdkr |jdj|�nttj|��dS)Nr\)r5�removerr�NOT_ENABLED)r=rarrr �
removeService�sz(FirewallClientZoneSettings.removeServicecCs||jdkS)Nr\)r5)r=rarrr �queryService�sz'FirewallClientZoneSettings.queryServicecCs
|jdS)N�)r5)r=rrr �getPorts�sz#FirewallClientZoneSettings.getPortscCs||jd<dS)Nrg)r5)r=r*rrr �setPorts�sz#FirewallClientZoneSettings.setPortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nrgz'%s:%s')r5r_rrr`)r=�port�protocolrrr �addPort�sz"FirewallClientZoneSettings.addPortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nrgz'%s:%s')r5rcrrrd)r=rjrkrrr �
removePort�sz%FirewallClientZoneSettings.removePortcCs||f|jdkS)Nrg)r5)r=rjrkrrr �	queryPort�sz$FirewallClientZoneSettings.queryPortcCs
|jdS)N�
)r5)r=rrr �getProtocols�sz'FirewallClientZoneSettings.getProtocolscCs||jd<dS)Nro)r5)r=r0rrr �setProtocols�sz'FirewallClientZoneSettings.setProtocolscCs0||jdkr |jdj|�nttj|��dS)Nro)r5r_rrr`)r=rkrrr �addProtocol�sz&FirewallClientZoneSettings.addProtocolcCs0||jdkr |jdj|�nttj|��dS)Nro)r5rcrrrd)r=rkrrr �removeProtocol�sz)FirewallClientZoneSettings.removeProtocolcCs||jdkS)Nro)r5)r=rkrrr �
queryProtocol�sz(FirewallClientZoneSettings.queryProtocolcCs
|jdS)N�)r5)r=rrr �getSourcePortssz)FirewallClientZoneSettings.getSourcePortscCs||jd<dS)Nru)r5)r=r*rrr �setSourcePortssz)FirewallClientZoneSettings.setSourcePortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nruz'%s:%s')r5r_rrr`)r=rjrkrrr �
addSourcePortsz(FirewallClientZoneSettings.addSourcePortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nruz'%s:%s')r5rcrrrd)r=rjrkrrr �removeSourcePortsz+FirewallClientZoneSettings.removeSourcePortcCs||f|jdkS)Nru)r5)r=rjrkrrr �querySourcePortsz*FirewallClientZoneSettings.querySourcePortcCs
|jdS)N�)r5)r=rrr �
getIcmpBlockssz(FirewallClientZoneSettings.getIcmpBlockscCs||jd<dS)Nr{)r5)r=�
icmpblocksrrr �
setIcmpBlockssz(FirewallClientZoneSettings.setIcmpBlockscCs0||jdkr |jdj|�nttj|��dS)Nr{)r5r_rrr`)r=�icmptyperrr �addIcmpBlock sz'FirewallClientZoneSettings.addIcmpBlockcCs0||jdkr |jdj|�nttj|��dS)Nr{)r5rcrrrd)r=rrrr �removeIcmpBlock&sz*FirewallClientZoneSettings.removeIcmpBlockcCs||jdkS)Nr{)r5)r=rrrr �queryIcmpBlock,sz)FirewallClientZoneSettings.queryIcmpBlockcCs
|jdS)N�)r5)r=rrr �getIcmpBlockInversion0sz0FirewallClientZoneSettings.getIcmpBlockInversioncCs||jd<dS)Nr�)r5)r=�flagrrr �setIcmpBlockInversion3sz0FirewallClientZoneSettings.setIcmpBlockInversioncCs&|jdsd|jd<nttjd�dS)Nr�Tzicmp-block-inversion)r5rrr`)r=rrr �addIcmpBlockInversion6s
z0FirewallClientZoneSettings.addIcmpBlockInversioncCs&|jdrd|jd<nttjd�dS)Nr�Fzicmp-block-inversion)r5rrrd)r=rrr �removeIcmpBlockInversion=s
z3FirewallClientZoneSettings.removeIcmpBlockInversioncCs
|jdS)Nr�)r5)r=rrr �queryIcmpBlockInversionDsz2FirewallClientZoneSettings.queryIcmpBlockInversioncCs
|jdS)N�)r5)r=rrr �
getForwardIsz%FirewallClientZoneSettings.getForwardcCs||jd<dS)Nr�)r5)r=r2rrr �
setForwardLsz%FirewallClientZoneSettings.setForwardcCs&|jdsd|jd<nttjd�dS)Nr�Tr2)r5rrr`)r=rrr �
addForwardOs
z%FirewallClientZoneSettings.addForwardcCs&|jdrd|jd<nttjd�dS)Nr�Fr2)r5rrrd)r=rrr �
removeForwardVs
z(FirewallClientZoneSettings.removeForwardcCs
|jdS)Nr�)r5)r=rrr �queryForward]sz'FirewallClientZoneSettings.queryForwardcCs
|jdS)N�)r5)r=rrr �
getMasqueradebsz(FirewallClientZoneSettings.getMasqueradecCs||jd<dS)Nr�)r5)r=r,rrr �
setMasqueradeesz(FirewallClientZoneSettings.setMasqueradecCs&|jdsd|jd<nttjd�dS)Nr�Tr,)r5rrr`)r=rrr �
addMasqueradehs
z(FirewallClientZoneSettings.addMasqueradecCs&|jdrd|jd<nttjd�dS)Nr�Fr,)r5rrrd)r=rrr �removeMasqueradeos
z+FirewallClientZoneSettings.removeMasqueradecCs
|jdS)Nr�)r5)r=rrr �queryMasqueradevsz*FirewallClientZoneSettings.queryMasqueradecCs
|jdS)N�	)r5)r=rrr �getForwardPorts{sz*FirewallClientZoneSettings.getForwardPortscCs||jd<dS)Nr�)r5)r=r*rrr �setForwardPorts~sz*FirewallClientZoneSettings.setForwardPortscCsd|dkrd}|dkrd}||||f|jdkrH|jdj||||f�nttjd||||f��dS)Nr#r�z
'%s:%s:%s:%s')r5r_rrr`)r=rjrk�to_port�to_addrrrr �addForwardPort�sz)FirewallClientZoneSettings.addForwardPortcCsd|dkrd}|dkrd}||||f|jdkrH|jdj||||f�nttjd||||f��dS)Nr#r�z
'%s:%s:%s:%s')r5rcrrrd)r=rjrkr�r�rrr �removeForwardPort�sz,FirewallClientZoneSettings.removeForwardPortcCs.|dkrd}|dkrd}||||f|jdkS)Nr#r�)r5)r=rjrkr�r�rrr �queryForwardPort�s
z+FirewallClientZoneSettings.queryForwardPortcCs
|jdS)N�
)r5)r=rrr �
getInterfaces�sz(FirewallClientZoneSettings.getInterfacescCs||jd<dS)Nr�)r5)r=r.rrr �
setInterfaces�sz(FirewallClientZoneSettings.setInterfacescCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�	interfacerrr �addInterface�sz'FirewallClientZoneSettings.addInterfacecCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=r�rrr �removeInterface�sz*FirewallClientZoneSettings.removeInterfacecCs||jdkS)Nr�)r5)r=r�rrr �queryInterface�sz)FirewallClientZoneSettings.queryInterfacecCs
|jdS)N�)r5)r=rrr �
getSources�sz%FirewallClientZoneSettings.getSourcescCs||jd<dS)Nr�)r5)r=r/rrr �
setSources�sz%FirewallClientZoneSettings.setSourcescCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�sourcerrr �	addSource�sz$FirewallClientZoneSettings.addSourcecCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=r�rrr �removeSource�sz'FirewallClientZoneSettings.removeSourcecCs||jdkS)Nr�)r5)r=r�rrr �querySource�sz&FirewallClientZoneSettings.querySourcecCs
|jdS)N�)r5)r=rrr �getRichRules�sz'FirewallClientZoneSettings.getRichRulescCsdd�|D�}||jd<dS)NcSsg|]}tt|d���qS))�rule_str)rr)�.0�rrrr �
<listcomp>�sz;FirewallClientZoneSettings.setRichRules.<locals>.<listcomp>r�)r5)r=�rulesrrr �setRichRules�sz'FirewallClientZoneSettings.setRichRulescCs>tt|d��}||jdkr.|jdj|�nttj|��dS)N)r�r�)rrr5r_rrr`)r=�rulerrr �addRichRule�sz&FirewallClientZoneSettings.addRichRulecCs>tt|d��}||jdkr.|jdj|�nttj|��dS)N)r�r�)rrr5rcrrrd)r=r�rrr �removeRichRule�sz)FirewallClientZoneSettings.removeRichRulecCstt|d��}||jdkS)N)r�r�)rrr5)r=r�rrr �
queryRichRule�sz(FirewallClientZoneSettings.queryRichRule)N)S�__name__�
__module__�__qualname__r!r@rBrFr<rMrNrOrPrQrSrTrVrWrZr[r]r^rbrerfrhrirlrmrnrprqrrrsrtrvrwrxryrzr|r~r�r�r�r�r��slipr�polkit�enable_proxyr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrr r"Ws�	
r"c@s�eZdZdd�Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zejjjed)d*���Zejjjed+d,���Zejjjed-d.���Zejjjed/d0���Zejjjed1d2���Z ejjjed3d4���Z!ejjjed5d6���Z"ejjjed7d8���Z#ejjjed9d:���Z$ejjjed;d<���Z%ejjjed=d>���Z&ejjjed?d@���Z'ejjjedAdB���Z(ejjjedCdD���Z)ejjjedEdF���Z*ejjjedGdH���Z+ejjjedIdJ���Z,ejjjedKdL���Z-ejjjedMdN���Z.ejjjedOdP���Z/ejjjedQdR���Z0ejjjedSdT���Z1ejjjedUdV���Z2ejjjedWdX���Z3ejjjedYdZ���Z4ejjjed[d\���Z5ejjjed]d^���Z6ejjjed_d`���Z7ejjjedadb���Z8ejjjedcdd���Z9ejjjededf���Z:ejjjedgdh���Z;ejjjedidj���Z<ejjjedkdl���Z=ejjjedmdn���Z>ejjjedodp���Z?ejjjedqdr���Z@ejjjedsdt���ZAejjjedudv���ZBejjjedwdx���ZCejjjedydz���ZDejjjed{d|���ZEejjjed}d~���ZFejjjedd����ZGejjjed�d����ZHejjjed�d����ZIejjjed�d����ZJejjjed�d����ZKejjjed�d����ZLejjjed�d����ZMejjjed�d����ZNejjjed�d����ZOejjjed�d����ZPejjjed�d����ZQejjjed�d����ZRejjjed�d����ZSejjjed�d����ZTd�S)��FirewallClientConfigZonecCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)�dbus_interfacezorg.freedesktop.DBus.Properties)�bus�path�
get_objectrr�DBUS_INTERFACE�dbus_obj�	Interface�DBUS_INTERFACE_CONFIG_ZONE�fw_zone�
fw_properties)r=r�r�rrr r@�sz!FirewallClientConfigZone.__init__cCst|jjtjj|��S)N)r	r��Getrrr�)r=�proprrr �get_property�sz%FirewallClientConfigZone.get_propertycCst|jjtjj��S)N)r	r��GetAllrrr�)r=rrr �get_properties�sz'FirewallClientConfigZone.get_propertiescCs|jjtjj||�dS)N)r��Setrrr�)r=r�rErrr �set_propertysz%FirewallClientConfigZone.set_propertycCstt|jj���S)N)r"r	r��getSettings2)r=rrr �getSettingssz$FirewallClientConfigZone.getSettingscCs|jj|j��dS)N)r��update2rM)r=r5rrr �updateszFirewallClientConfigZone.updatecCs|jj�dS)N)r��loadDefaults)r=rrr r�sz%FirewallClientConfigZone.loadDefaultscCs|jj�dS)N)r�rc)r=rrr rcszFirewallClientConfigZone.removecCs|jj|�dS)N)r��rename)r=�namerrr r�szFirewallClientConfigZone.renamecCs
|jj�S)N)r�rP)r=rrr rP"sz#FirewallClientConfigZone.getVersioncCs|jj|�dS)N)r�rQ)r=r$rrr rQ'sz#FirewallClientConfigZone.setVersioncCs
|jj�S)N)r�rS)r=rrr rS.sz!FirewallClientConfigZone.getShortcCs|jj|�dS)N)r�rT)r=r%rrr rT3sz!FirewallClientConfigZone.setShortcCs
|jj�S)N)r�rV)r=rrr rV:sz'FirewallClientConfigZone.getDescriptioncCs|jj|�dS)N)r�rW)r=r&rrr rW?sz'FirewallClientConfigZone.setDescriptioncCs
|jj�S)N)r�rZ)r=rrr rZFsz"FirewallClientConfigZone.getTargetcCs|jj|�dS)N)r�r[)r=r(rrr r[Ksz"FirewallClientConfigZone.setTargetcCs
|jj�S)N)r�r])r=rrr r]Rsz$FirewallClientConfigZone.getServicescCs|jj|�dS)N)r�r^)r=r)rrr r^Wsz$FirewallClientConfigZone.setServicescCs|jj|�dS)N)r�rb)r=rarrr rb\sz#FirewallClientConfigZone.addServicecCs|jj|�dS)N)r�re)r=rarrr reasz&FirewallClientConfigZone.removeServicecCs|jj|�S)N)r�rf)r=rarrr rffsz%FirewallClientConfigZone.queryServicecCs
|jj�S)N)r�rh)r=rrr rhmsz!FirewallClientConfigZone.getPortscCs|jj|�dS)N)r�ri)r=r*rrr rirsz!FirewallClientConfigZone.setPortscCs|jj||�dS)N)r�rl)r=rjrkrrr rlwsz FirewallClientConfigZone.addPortcCs|jj||�dS)N)r�rm)r=rjrkrrr rm|sz#FirewallClientConfigZone.removePortcCs|jj||�S)N)r�rn)r=rjrkrrr rn�sz"FirewallClientConfigZone.queryPortcCs
|jj�S)N)r�rp)r=rrr rp�sz%FirewallClientConfigZone.getProtocolscCs|jj|�dS)N)r�rq)r=r0rrr rq�sz%FirewallClientConfigZone.setProtocolscCs|jj|�dS)N)r�rr)r=rkrrr rr�sz$FirewallClientConfigZone.addProtocolcCs|jj|�dS)N)r�rs)r=rkrrr rs�sz'FirewallClientConfigZone.removeProtocolcCs|jj|�S)N)r�rt)r=rkrrr rt�sz&FirewallClientConfigZone.queryProtocolcCs
|jj�S)N)r�rv)r=rrr rv�sz'FirewallClientConfigZone.getSourcePortscCs|jj|�dS)N)r�rw)r=r*rrr rw�sz'FirewallClientConfigZone.setSourcePortscCs|jj||�dS)N)r�rx)r=rjrkrrr rx�sz&FirewallClientConfigZone.addSourcePortcCs|jj||�dS)N)r�ry)r=rjrkrrr ry�sz)FirewallClientConfigZone.removeSourcePortcCs|jj||�S)N)r�rz)r=rjrkrrr rz�sz(FirewallClientConfigZone.querySourcePortcCs
|jj�S)N)r�r|)r=rrr r|�sz&FirewallClientConfigZone.getIcmpBlockscCs|jj|�dS)N)r�r~)r=Z	icmptypesrrr r~�sz&FirewallClientConfigZone.setIcmpBlockscCs|jj|�dS)N)r�r�)r=rrrr r��sz%FirewallClientConfigZone.addIcmpBlockcCs|jj|�dS)N)r�r�)r=rrrr r��sz(FirewallClientConfigZone.removeIcmpBlockcCs|jj|�S)N)r�r�)r=rrrr r��sz'FirewallClientConfigZone.queryIcmpBlockcCs
|jj�S)N)r�r�)r=rrr r��sz.FirewallClientConfigZone.getIcmpBlockInversioncCs|jj|�dS)N)r�r�)r=Z	inversionrrr r��sz.FirewallClientConfigZone.setIcmpBlockInversioncCs|jj�dS)N)r�r�)r=rrr r��sz.FirewallClientConfigZone.addIcmpBlockInversioncCs|jj�dS)N)r�r�)r=rrr r��sz1FirewallClientConfigZone.removeIcmpBlockInversioncCs
|jj�S)N)r�r�)r=rrr r��sz0FirewallClientConfigZone.queryIcmpBlockInversioncCs|jj�dS)Nr2)r�r�)r=rrr r��sz#FirewallClientConfigZone.getForwardcCs|jjd|i�dS)Nr2)r�r�)r=r2rrr r��sz#FirewallClientConfigZone.setForwardcCs|jjddi�dS)Nr2T)r�r�)r=rrr r��sz#FirewallClientConfigZone.addForwardcCs|jjddi�dS)Nr2F)r�r�)r=rrr r�sz&FirewallClientConfigZone.removeForwardcCs|jj�dS)Nr2)r�r�)r=rrr r�sz%FirewallClientConfigZone.queryForwardcCs
|jj�S)N)r�r�)r=rrr r�sz&FirewallClientConfigZone.getMasqueradecCs|jj|�dS)N)r�r�)r=r,rrr r�sz&FirewallClientConfigZone.setMasqueradecCs|jj�dS)N)r�r�)r=rrr r�sz&FirewallClientConfigZone.addMasqueradecCs|jj�dS)N)r�r�)r=rrr r�sz)FirewallClientConfigZone.removeMasqueradecCs
|jj�S)N)r�r�)r=rrr r�#sz(FirewallClientConfigZone.queryMasqueradecCs
|jj�S)N)r�r�)r=rrr r�*sz(FirewallClientConfigZone.getForwardPortscCs|jj|�dS)N)r�r�)r=r*rrr r�/sz(FirewallClientConfigZone.setForwardPortscCs.|dkrd}|dkrd}|jj||||�dS)Nr#)r�r�)r=rjrk�toport�toaddrrrr r�4s
z'FirewallClientConfigZone.addForwardPortcCs.|dkrd}|dkrd}|jj||||�dS)Nr#)r�r�)r=rjrkr�r�rrr r�=s
z*FirewallClientConfigZone.removeForwardPortcCs*|dkrd}|dkrd}|jj||||�S)Nr#)r�r�)r=rjrkr�r�rrr r�Fs
z)FirewallClientConfigZone.queryForwardPortcCs
|jj�S)N)r�r�)r=rrr r�Qsz&FirewallClientConfigZone.getInterfacescCs|jj|�dS)N)r�r�)r=r.rrr r�Vsz&FirewallClientConfigZone.setInterfacescCs|jj|�dS)N)r�r�)r=r�rrr r�[sz%FirewallClientConfigZone.addInterfacecCs|jj|�dS)N)r�r�)r=r�rrr r�`sz(FirewallClientConfigZone.removeInterfacecCs|jj|�S)N)r�r�)r=r�rrr r�esz'FirewallClientConfigZone.queryInterfacecCs
|jj�S)N)r�r�)r=rrr r�lsz#FirewallClientConfigZone.getSourcescCs|jj|�dS)N)r�r�)r=r/rrr r�qsz#FirewallClientConfigZone.setSourcescCs|jj|�dS)N)r�r�)r=r�rrr r�vsz"FirewallClientConfigZone.addSourcecCs|jj|�dS)N)r�r�)r=r�rrr r�{sz%FirewallClientConfigZone.removeSourcecCs|jj|�S)N)r�r�)r=r�rrr r��sz$FirewallClientConfigZone.querySourcecCs
|jj�S)N)r�r�)r=rrr r��sz%FirewallClientConfigZone.getRichRulescCs|jj|�dS)N)r�r�)r=r�rrr r��sz%FirewallClientConfigZone.setRichRulescCs|jj|�dS)N)r�r�)r=r�rrr r��sz$FirewallClientConfigZone.addRichRulecCs|jj|�dS)N)r�r�)r=r�rrr r��sz'FirewallClientConfigZone.removeRichRulecCs|jj|�S)N)r�r�)r=r�rrr r��sz&FirewallClientConfigZone.queryRichRuleN)Ur�r�r�r@r�rr�r�r!r�r�r�r�r�r�rcr�rPrQrSrTrVrWrZr[r]r^rbrerfrhrirlrmrnrprqrrrsrtrvrwrxryrzr|r~r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrr r��s2
r�c@s@eZdZed�dd��Zedd��Zedd��Zedd	��Zed
d��Zdd
�Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��Zed*d+��Zed,d-��Zed.d/��Zed0d1��Zed2d3��Zed4d5��Zed6d7��Zed8d9��Zed:d;��Z ed<d=��Z!ed>d?��Z"ed@dA��Z#edBdC��Z$edDdE��Z%edFdG��Z&edHdI��Z'edJdK��Z(edLdM��Z)edNdO��Z*edPdQ��Z+edRdS��Z,e-j.j/j0edTdU���Z1e-j.j/j0edVdW���Z2e-j.j/j0edXdY���Z3edZd[��Z4ed\d]��Z5ed^d_��Z6ed`da��Z7edbdc��Z8eddde��Z9edfdg��Z:edhdi��Z;edjdk��Z<edldm��Z=edndo��Z>edpdq��Z?edrds��Z@edtdu��ZAedvdw��ZBedxdy��ZCedzd{��ZDed|d}��ZEed~d��ZFed�d���ZGed�d���ZHed�d���ZIdS)��FirewallClientPolicySettingsNcCs\dggggdgtgggdgtdd�|_dddddddddddddddg|_|rX|j|�dS)	Nr#F)r&�egress_zonesr-r+�
ingress_zonesr,r*�priorityr0�
rich_rulesr)r%r1r(r$r3z(ssss)r4z(ss)r>)rrr5r7r<)r=r5rrr r@�s,

z%FirewallClientPolicySettings.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rB�sz%FirewallClientPolicySettings.__repr__cCs|jS)N)r5)r=rrr rF�sz,FirewallClientPolicySettings.getSettingsDictcCs x|D]}|||j|<qWdS)N)r5)r=r5rDrrr r<�s
z,FirewallClientPolicySettings.setSettingsDictcCsvi}xlt|j|j�D]Z\}}|j|}t|�tkrFtj||d�||<qt|�tkrftj||d�||<q|||<qW|S)N)rH)	rCr5r7rIr9rrJr;rK)r=r5rDrLrErrr rM�s
z0FirewallClientPolicySettings.getSettingsDbusDictcCs |j�}xdD]
}||=qW|S)Nr$r%r&r()r$r%r&r()rM)r=r5rDrrr rO�s

z7FirewallClientPolicySettings.getRuntimeSettingsDbusDictcCs
|jdS)Nr$)r5)r=rrr rP�sz'FirewallClientPolicySettings.getVersioncCs||jd<dS)Nr$)r5)r=r$rrr rQ�sz'FirewallClientPolicySettings.setVersioncCs
|jdS)Nr%)r5)r=rrr rS�sz%FirewallClientPolicySettings.getShortcCs||jd<dS)Nr%)r5)r=r%rrr rT�sz%FirewallClientPolicySettings.setShortcCs
|jdS)Nr&)r5)r=rrr rV�sz+FirewallClientPolicySettings.getDescriptioncCs||jd<dS)Nr&)r5)r=r&rrr rW�sz+FirewallClientPolicySettings.setDescriptioncCs
|jdS)Nr()r5)r=rrr rZ�sz&FirewallClientPolicySettings.getTargetcCs||jd<dS)Nr()r5)r=r(rrr r[�sz&FirewallClientPolicySettings.setTargetcCs
|jdS)Nr))r5)r=rrr r]�sz(FirewallClientPolicySettings.getServicescCs||jd<dS)Nr))r5)r=r)rrr r^�sz(FirewallClientPolicySettings.setServicescCs0||jdkr |jdj|�nttj|��dS)Nr))r5r_rrr`)r=rarrr rb�sz'FirewallClientPolicySettings.addServicecCs0||jdkr |jdj|�nttj|��dS)Nr))r5rcrrrd)r=rarrr resz*FirewallClientPolicySettings.removeServicecCs||jdkS)Nr))r5)r=rarrr rfsz)FirewallClientPolicySettings.queryServicecCs
|jdS)Nr*)r5)r=rrr rh
sz%FirewallClientPolicySettings.getPortscCs||jd<dS)Nr*)r5)r=r*rrr ri
sz%FirewallClientPolicySettings.setPortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr*z'%s:%s')r5r_rrr`)r=rjrkrrr rlsz$FirewallClientPolicySettings.addPortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr*z'%s:%s')r5rcrrrd)r=rjrkrrr rmsz'FirewallClientPolicySettings.removePortcCs||f|jdkS)Nr*)r5)r=rjrkrrr rnsz&FirewallClientPolicySettings.queryPortcCs
|jdS)Nr0)r5)r=rrr rp"sz)FirewallClientPolicySettings.getProtocolscCs||jd<dS)Nr0)r5)r=r0rrr rq%sz)FirewallClientPolicySettings.setProtocolscCs0||jdkr |jdj|�nttj|��dS)Nr0)r5r_rrr`)r=rkrrr rr(sz(FirewallClientPolicySettings.addProtocolcCs0||jdkr |jdj|�nttj|��dS)Nr0)r5rcrrrd)r=rkrrr rs.sz+FirewallClientPolicySettings.removeProtocolcCs||jdkS)Nr0)r5)r=rkrrr rt4sz*FirewallClientPolicySettings.queryProtocolcCs
|jdS)Nr1)r5)r=rrr rv8sz+FirewallClientPolicySettings.getSourcePortscCs||jd<dS)Nr1)r5)r=r*rrr rw;sz+FirewallClientPolicySettings.setSourcePortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr1z'%s:%s')r5r_rrr`)r=rjrkrrr rx>sz*FirewallClientPolicySettings.addSourcePortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr1z'%s:%s')r5rcrrrd)r=rjrkrrr ryEsz-FirewallClientPolicySettings.removeSourcePortcCs||f|jdkS)Nr1)r5)r=rjrkrrr rzLsz,FirewallClientPolicySettings.querySourcePortcCs
|jdS)Nr+)r5)r=rrr r|Psz*FirewallClientPolicySettings.getIcmpBlockscCs||jd<dS)Nr+)r5)r=r}rrr r~Ssz*FirewallClientPolicySettings.setIcmpBlockscCs0||jdkr |jdj|�nttj|��dS)Nr+)r5r_rrr`)r=rrrr r�Vsz)FirewallClientPolicySettings.addIcmpBlockcCs0||jdkr |jdj|�nttj|��dS)Nr+)r5rcrrrd)r=rrrr r�\sz,FirewallClientPolicySettings.removeIcmpBlockcCs||jdkS)Nr+)r5)r=rrrr r�bsz+FirewallClientPolicySettings.queryIcmpBlockcCs
|jdS)Nr,)r5)r=rrr r�fsz*FirewallClientPolicySettings.getMasqueradecCs||jd<dS)Nr,)r5)r=r,rrr r�isz*FirewallClientPolicySettings.setMasqueradecCs&|jdsd|jd<nttjd�dS)Nr,T)r5rrr`)r=rrr r�ls
z*FirewallClientPolicySettings.addMasqueradecCs&|jdrd|jd<nttjd�dS)Nr,F)r5rrrd)r=rrr r�ss
z-FirewallClientPolicySettings.removeMasqueradecCs
|jdS)Nr,)r5)r=rrr r�zsz,FirewallClientPolicySettings.queryMasqueradecCs
|jdS)Nr-)r5)r=rrr r�sz,FirewallClientPolicySettings.getForwardPortscCs||jd<dS)Nr-)r5)r=r*rrr r��sz,FirewallClientPolicySettings.setForwardPortscCsd|dkrd}|dkrd}||||f|jdkrH|jdj||||f�nttjd||||f��dS)Nr#r-z
'%s:%s:%s:%s')r5r_rrr`)r=rjrkr�r�rrr r��sz+FirewallClientPolicySettings.addForwardPortcCsd|dkrd}|dkrd}||||f|jdkrH|jdj||||f�nttjd||||f��dS)Nr#r-z
'%s:%s:%s:%s')r5rcrrrd)r=rjrkr�r�rrr r��sz.FirewallClientPolicySettings.removeForwardPortcCs.|dkrd}|dkrd}||||f|jdkS)Nr#r-)r5)r=rjrkr�r�rrr r��s
z-FirewallClientPolicySettings.queryForwardPortcCs
|jdS)Nr�)r5)r=rrr r��sz)FirewallClientPolicySettings.getRichRulescCsdd�|D�}||jd<dS)NcSsg|]}tt|d���qS))r�)rr)r�r�rrr r��sz=FirewallClientPolicySettings.setRichRules.<locals>.<listcomp>r�)r5)r=r�rrr r��sz)FirewallClientPolicySettings.setRichRulescCs>tt|d��}||jdkr.|jdj|�nttj|��dS)N)r�r�)rrr5r_rrr`)r=r�rrr r��sz(FirewallClientPolicySettings.addRichRulecCs>tt|d��}||jdkr.|jdj|�nttj|��dS)N)r�r�)rrr5rcrrrd)r=r�rrr r��sz+FirewallClientPolicySettings.removeRichRulecCstt|d��}||jdkS)N)r�r�)rrr5)r=r�rrr r��sz*FirewallClientPolicySettings.queryRichRulecCs
|jdS)Nr�)r5)r=rrr �getIngressZones�sz,FirewallClientPolicySettings.getIngressZonescCs||jd<dS)Nr�)r5)r=r�rrr �setIngressZones�sz,FirewallClientPolicySettings.setIngressZonescCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�ingress_zonerrr �addIngressZone�sz+FirewallClientPolicySettings.addIngressZonecCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=r�rrr �removeIngressZone�sz.FirewallClientPolicySettings.removeIngressZonecCs||jdkS)Nr�)r5)r=r�rrr �queryIngressZone�sz-FirewallClientPolicySettings.queryIngressZonecCs
|jdS)Nr�)r5)r=rrr �getEgressZones�sz+FirewallClientPolicySettings.getEgressZonescCs||jd<dS)Nr�)r5)r=r�rrr �setEgressZones�sz+FirewallClientPolicySettings.setEgressZonescCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�egress_zonerrr �
addEgressZone�sz*FirewallClientPolicySettings.addEgressZonecCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=r�rrr �removeEgressZone�sz-FirewallClientPolicySettings.removeEgressZonecCs||jdkS)Nr�)r5)r=r�rrr �queryEgressZone�sz,FirewallClientPolicySettings.queryEgressZonecCs
|jdS)Nr�)r5)r=rrr �getPriority�sz(FirewallClientPolicySettings.getPrioritycCst|�|jd<dS)Nr�)�intr5)r=r�rrr �setPriority�sz(FirewallClientPolicySettings.setPriority)N)Jr�r�r�r!r@rBrFr<rMrOrPrQrSrTrVrWrZr[r]r^rbrerfrhrirlrmrnrprqrrrsrtrvrwrxryrzr|r~r�r�r�r�r�r�rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrr r��s�r�c@s�eZdZdd�Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���ZdS)�FirewallClientConfigPolicycCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)r�zorg.freedesktop.DBus.Properties)r�r�r�rrr�r�r��DBUS_INTERFACE_CONFIG_POLICY�	fw_policyr�)r=r�r�rrr r@�sz#FirewallClientConfigPolicy.__init__cCst|jjtjj|��S)N)r	r�r�rrr�)r=r�rrr r��sz'FirewallClientConfigPolicy.get_propertycCst|jjtjj��S)N)r	r�r�rrr�)r=rrr r�sz)FirewallClientConfigPolicy.get_propertiescCs|jjtjj||�dS)N)r�r�rrr�)r=r�rErrr r�sz'FirewallClientConfigPolicy.set_propertycCstt|jj���S)N)r�r	r�r�)r=rrr r�
sz&FirewallClientConfigPolicy.getSettingscCs|jj|j��dS)N)r�r�rM)r=r5rrr r�sz!FirewallClientConfigPolicy.updatecCs|jj�dS)N)r�r�)r=rrr r�sz'FirewallClientConfigPolicy.loadDefaultscCs|jj�dS)N)r�rc)r=rrr rcsz!FirewallClientConfigPolicy.removecCs|jj|�dS)N)r�r�)r=r�rrr r�!sz!FirewallClientConfigPolicy.renameN)r�r�r�r@r�rr�r�r!r�r�r�r�r�r�rcr�rrrr r��s"
r�c@s8eZdZed^dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��Zed*d+��Zed,d-��Zed.d/��Zed0d1��Zed2d3��Zed4d5��Zed6d7��Zed8d9��Zed:d;��Z ed<d=��Z!ed>d?��Z"ed@dA��Z#edBdC��Z$edDdE��Z%ed_dFdG��Z&edHdI��Z'edJdK��Z(edLdM��Z)edNdO��Z*edPdQ��Z+edRdS��Z,edTdU��Z-edVdW��Z.edXdY��Z/edZd[��Z0ed\d]��Z1dS)`�FirewallClientServiceSettingsNc
Cs�dddggiggggg
|_dddddddd	d
dg
|_dddd
dddd
ddg
|_|r�t|�tkr�x:t|�D]\}}|||j|<qhWnt|�tkr�|j|�dS)Nr#r$r%r&r*�modules�destinationr0r1�includes�helpersr3z(ss)Zss)r5r6r7rIr9r:r;r<)r=r5r>r?rrr r@)sz&FirewallClientServiceSettings.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rB9sz&FirewallClientServiceSettings.__repr__cCs,i}x"t|j|j�D]\}}|||<qW|S)N)rCr6r5)r=r5rDrErrr rF=sz-FirewallClientServiceSettings.getSettingsDictcCs(x"|D]}|||j|jj|�<qWdS)N)r5r6rG)r=r5rDrrr r<Cs
z-FirewallClientServiceSettings.setSettingsDictcCsri}xht|j|j|j�D]R\}}}t|�tkrBtj||d�||<qt|�tkrbtj	||d�||<q|||<qW|S)N)rH)
rCr6r5r7rIr9rrJr;rK)r=r5rDrErLrrr rMGsz1FirewallClientServiceSettings.getSettingsDbusDictcCs
|jdS)Nr)r5)r=rrr rPSsz(FirewallClientServiceSettings.getVersioncCs||jd<dS)Nr)r5)r=r$rrr rQVsz(FirewallClientServiceSettings.setVersioncCs
|jdS)NrR)r5)r=rrr rSZsz&FirewallClientServiceSettings.getShortcCs||jd<dS)NrR)r5)r=r%rrr rT]sz&FirewallClientServiceSettings.setShortcCs
|jdS)NrU)r5)r=rrr rVasz,FirewallClientServiceSettings.getDescriptioncCs||jd<dS)NrU)r5)r=r&rrr rWdsz,FirewallClientServiceSettings.setDescriptioncCs
|jdS)N�)r5)r=rrr rhhsz&FirewallClientServiceSettings.getPortscCs||jd<dS)Nr�)r5)r=r*rrr riksz&FirewallClientServiceSettings.setPortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr�z'%s:%s')r5r_rrr`)r=rjrkrrr rlnsz%FirewallClientServiceSettings.addPortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr�z'%s:%s')r5rcrrrd)r=rjrkrrr rmusz(FirewallClientServiceSettings.removePortcCs||f|jdkS)Nr�)r5)r=rjrkrrr rn|sz'FirewallClientServiceSettings.queryPortcCs
|jdS)Nrg)r5)r=rrr rp�sz*FirewallClientServiceSettings.getProtocolscCs||jd<dS)Nrg)r5)r=r0rrr rq�sz*FirewallClientServiceSettings.setProtocolscCs0||jdkr |jdj|�nttj|��dS)Nrg)r5r_rrr`)r=rkrrr rr�sz)FirewallClientServiceSettings.addProtocolcCs0||jdkr |jdj|�nttj|��dS)Nrg)r5rcrrrd)r=rkrrr rs�sz,FirewallClientServiceSettings.removeProtocolcCs||jdkS)Nrg)r5)r=rkrrr rt�sz+FirewallClientServiceSettings.queryProtocolcCs
|jdS)Nr{)r5)r=rrr rv�sz,FirewallClientServiceSettings.getSourcePortscCs||jd<dS)Nr{)r5)r=r*rrr rw�sz,FirewallClientServiceSettings.setSourcePortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr{z'%s:%s')r5r_rrr`)r=rjrkrrr rx�sz+FirewallClientServiceSettings.addSourcePortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr{z'%s:%s')r5rcrrrd)r=rjrkrrr ry�sz.FirewallClientServiceSettings.removeSourcePortcCs||f|jdkS)Nr{)r5)r=rjrkrrr rz�sz-FirewallClientServiceSettings.querySourcePortcCs
|jdS)NrX)r5)r=rrr �
getModules�sz(FirewallClientServiceSettings.getModulescCs||jd<dS)NrX)r5)r=r�rrr �
setModules�sz(FirewallClientServiceSettings.setModulescCs0||jdkr |jdj|�nttj|��dS)NrX)r5r_rrr`)r=�modulerrr �	addModule�sz'FirewallClientServiceSettings.addModulecCs0||jdkr |jdj|�nttj|��dS)NrX)r5rcrrrd)r=r�rrr �removeModule�sz*FirewallClientServiceSettings.removeModulecCs||jdkS)NrX)r5)r=r�rrr �queryModule�sz)FirewallClientServiceSettings.queryModulecCs
|jdS)Nr\)r5)r=rrr �getDestinations�sz-FirewallClientServiceSettings.getDestinationscCs||jd<dS)Nr\)r5)r=�destinationsrrr �setDestinations�sz-FirewallClientServiceSettings.setDestinationscCsH||jdks |jd||kr0||jd|<nttjd||f��dS)Nr\z'%s:%s')r5rrr`)r=�	dest_type�addressrrr �setDestination�s
z,FirewallClientServiceSettings.setDestinationcCs^||jdkrJ|dk	r<|jd||kr<ttjd||f��|jd|=nttjd|��dS)Nr\z'%s:%s'z'%s')r5rrrd)r=r�rrrr �removeDestination�sz/FirewallClientServiceSettings.removeDestinationcCs ||jdko||jd|kS)Nr\)r5)r=r�rrrr �queryDestination�sz.FirewallClientServiceSettings.queryDestinationcCs
|jdS)Nr�)r5)r=rrr �getIncludes�sz)FirewallClientServiceSettings.getIncludescCs||jd<dS)Nr�)r5)r=r�rrr �setIncludes�sz)FirewallClientServiceSettings.setIncludescCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�includerrr �
addInclude�sz(FirewallClientServiceSettings.addIncludecCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=rrrr �
removeInclude�sz+FirewallClientServiceSettings.removeIncludecCs||jdkS)Nr�)r5)r=rrrr �queryInclude�sz*FirewallClientServiceSettings.queryIncludecCs
|jdS)Nr�)r5)r=rrr �
getHelpers�sz(FirewallClientServiceSettings.getHelperscCs||jd<dS)Nr�)r5)r=r�rrr �
setHelpers�sz(FirewallClientServiceSettings.setHelperscCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�helperrrr �	addHelper�sz'FirewallClientServiceSettings.addHelpercCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=rrrr �removeHelpersz*FirewallClientServiceSettings.removeHelpercCs||jdkS)Nr�)r5)r=rrrr �queryHelpersz)FirewallClientServiceSettings.queryHelper)N)N)2r�r�r�r!r@rBrFr<rMrPrQrSrTrVrWrhrirlrmrnrprqrrrsrtrvrwrxryrzr�r�r�r�r�r�r�rrrrrrrr	r
rr
rrrrrr r�(s`r�c@s�eZdZed*dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��ZdS)+�FirewallClientIPSetSettingsNcCs"|r||_nddddigg|_dS)Nr#)r5)r=r5rrr r@sz$FirewallClientIPSetSettings.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rBsz$FirewallClientIPSetSettings.__repr__cCs
|jdS)Nr)r5)r=rrr rPsz&FirewallClientIPSetSettings.getVersioncCs||jd<dS)Nr)r5)r=r$rrr rQsz&FirewallClientIPSetSettings.setVersioncCs
|jdS)NrR)r5)r=rrr rS!sz$FirewallClientIPSetSettings.getShortcCs||jd<dS)NrR)r5)r=r%rrr rT$sz$FirewallClientIPSetSettings.setShortcCs
|jdS)NrU)r5)r=rrr rV(sz*FirewallClientIPSetSettings.getDescriptioncCs||jd<dS)NrU)r5)r=r&rrr rW+sz*FirewallClientIPSetSettings.setDescriptioncCs
|jdS)Nr�)r5)r=rrr �getType/sz#FirewallClientIPSetSettings.getTypecCs||jd<dS)Nr�)r5)r=Z
ipset_typerrr �setType2sz#FirewallClientIPSetSettings.setTypecCs
|jdS)NrX)r5)r=rrr �
getOptions6sz&FirewallClientIPSetSettings.getOptionscCs||jd<dS)NrX)r5)r=Zoptionsrrr �
setOptions9sz&FirewallClientIPSetSettings.setOptionscCsP||jdks |jd||kr0||jd|<nttj|rFd||fn|��dS)NrXz'%s=%s')r5rrr`)r=rDrErrr �	addOption<s z%FirewallClientIPSetSettings.addOptioncCs,||jdkr|jd|=nttj|��dS)NrX)r5rrrd)r=rDrrr �removeOptionCsz(FirewallClientIPSetSettings.removeOptioncCs ||jdko|jd||kS)NrX)r5)r=rDrErrr �queryOptionIsz'FirewallClientIPSetSettings.queryOptioncCs
|jdS)Nr\)r5)r=rrr �
getEntriesMsz&FirewallClientIPSetSettings.getEntriescCs@d|jdkr*|jdddkr*ttj��t|�||jd<dS)N�timeoutrX�0r\)r5rr�IPSET_WITH_TIMEOUTr)r=�entriesrrr �
setEntriesPs

z&FirewallClientIPSetSettings.setEntriescCsrd|jdkr*|jdddkr*ttj��t|�}||jdkrbt||jd�|jdj|�nttj|��dS)NrrXrr\)r5rrrrr
r_r`)r=�entryrrr �addEntryWs
z$FirewallClientIPSetSettings.addEntrycCsbd|jdkr*|jdddkr*ttj��t|�}||jdkrR|jdj|�nttj|��dS)NrrXrr\)r5rrrrrcrd)r=rrrr �removeEntrybs
z'FirewallClientIPSetSettings.removeEntrycCs@d|jdkr*|jdddkr*ttj��t|�}||jdkS)NrrXrr\)r5rrrr)r=rrrr �
queryEntryls

z&FirewallClientIPSetSettings.queryEntry)N)r�r�r�r!r@rBrPrQrSrTrVrWrrrrrrrrrrr r!rrrr rs*
rc@s�eZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zd)S)*�FirewallClientConfigIPSetcCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)r�zorg.freedesktop.DBus.Properties)r�r�r�rrr�r�r��DBUS_INTERFACE_CONFIG_IPSET�fw_ipsetr�)r=r�r�rrr r@wsz"FirewallClientConfigIPSet.__init__cCst|jjtjj|��S)N)r	r�r�rrr#)r=r�rrr r��sz&FirewallClientConfigIPSet.get_propertycCst|jjtjj��S)N)r	r�r�rrr#)r=rrr r��sz(FirewallClientConfigIPSet.get_propertiescCs|jjtjj||�dS)N)r�r�rrr#)r=r�rErrr r��sz&FirewallClientConfigIPSet.set_propertycCsttt|jj����S)N)rr9r	r$r�)r=rrr r��sz%FirewallClientConfigIPSet.getSettingscCs|jjt|j��dS)N)r$r��tupler5)r=r5rrr r��sz FirewallClientConfigIPSet.updatecCs|jj�dS)N)r$r�)r=rrr r��sz&FirewallClientConfigIPSet.loadDefaultscCs|jj�dS)N)r$rc)r=rrr rc�sz FirewallClientConfigIPSet.removecCs|jj|�dS)N)r$r�)r=r�rrr r��sz FirewallClientConfigIPSet.renamecCs
|jj�S)N)r$rP)r=rrr rP�sz$FirewallClientConfigIPSet.getVersioncCs|jj|�dS)N)r$rQ)r=r$rrr rQ�sz$FirewallClientConfigIPSet.setVersioncCs
|jj�S)N)r$rS)r=rrr rS�sz"FirewallClientConfigIPSet.getShortcCs|jj|�dS)N)r$rT)r=r%rrr rT�sz"FirewallClientConfigIPSet.setShortcCs
|jj�S)N)r$rV)r=rrr rV�sz(FirewallClientConfigIPSet.getDescriptioncCs|jj|�dS)N)r$rW)r=r&rrr rW�sz(FirewallClientConfigIPSet.setDescriptioncCs
|jj�S)N)r$r)r=rrr r�sz$FirewallClientConfigIPSet.getEntriescCs|jj|�dS)N)r$r)r=rrrr r�sz$FirewallClientConfigIPSet.setEntriescCs|jj|�dS)N)r$r)r=rrrr r�sz"FirewallClientConfigIPSet.addEntrycCs|jj|�dS)N)r$r )r=rrrr r �sz%FirewallClientConfigIPSet.removeEntrycCs|jj|�S)N)r$r!)r=rrrr r!�sz$FirewallClientConfigIPSet.queryEntryN)r�r�r�r!r@r�rr�r�r�r�r�r�r�r�rcr�rPrQrSrTrVrWrrrr r!rrrr r"vsNr"c@s�eZdZed$dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��ZdS)%�FirewallClientHelperSettingsNcCs"|r||_ndddddgg|_dS)Nr#)r5)r=r5rrr r@�sz%FirewallClientHelperSettings.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rB�sz%FirewallClientHelperSettings.__repr__cCs
|jdS)Nr)r5)r=rrr rP�sz'FirewallClientHelperSettings.getVersioncCs||jd<dS)Nr)r5)r=r$rrr rQ�sz'FirewallClientHelperSettings.setVersioncCs
|jdS)NrR)r5)r=rrr rSsz%FirewallClientHelperSettings.getShortcCs||jd<dS)NrR)r5)r=r%rrr rTsz%FirewallClientHelperSettings.setShortcCs
|jdS)NrU)r5)r=rrr rV	sz+FirewallClientHelperSettings.getDescriptioncCs||jd<dS)NrU)r5)r=r&rrr rWsz+FirewallClientHelperSettings.setDescriptioncCs
|jdS)Nr�)r5)r=rrr �	getFamilysz&FirewallClientHelperSettings.getFamilycCs |dkrd|jd<||jd<dS)Nr#r�)r5)r=�ipvrrr �	setFamilys
z&FirewallClientHelperSettings.setFamilycCs
|jdS)NrX)r5)r=rrr �	getModulesz&FirewallClientHelperSettings.getModulecCs||jd<dS)NrX)r5)r=r�rrr �	setModulesz&FirewallClientHelperSettings.setModulecCs
|jdS)Nr\)r5)r=rrr rh sz%FirewallClientHelperSettings.getPortscCs||jd<dS)Nr\)r5)r=r*rrr ri#sz%FirewallClientHelperSettings.setPortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr\z'%s:%s')r5r_rrr`)r=rjrkrrr rl&sz$FirewallClientHelperSettings.addPortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr\z'%s:%s')r5rcrrrd)r=rjrkrrr rm-sz'FirewallClientHelperSettings.removePortcCs||f|jdkS)Nr\)r5)r=rjrkrrr rn4sz&FirewallClientHelperSettings.queryPort)N)r�r�r�r!r@rBrPrQrSrTrVrWr'r)r*r+rhrirlrmrnrrrr r&�s$r&c@seZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zejjjed)d*���Zejjjed+d,���Zejjjed-d.���Zejjjed/d0���Zd1S)2�FirewallClientConfigHelpercCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)r�zorg.freedesktop.DBus.Properties)r�r�r�rrr�r�r��DBUS_INTERFACE_CONFIG_HELPER�	fw_helperr�)r=r�r�rrr r@;sz#FirewallClientConfigHelper.__init__cCst|jjtjj|��S)N)r	r�r�rrr-)r=r�rrr r�Fsz'FirewallClientConfigHelper.get_propertycCst|jjtjj��S)N)r	r�r�rrr-)r=rrr r�Lsz)FirewallClientConfigHelper.get_propertiescCs|jjtjj||�dS)N)r�r�rrr-)r=r�rErrr r�Rsz'FirewallClientConfigHelper.set_propertycCsttt|jj����S)N)r&r9r	r.r�)r=rrr r�Xsz&FirewallClientConfigHelper.getSettingscCs|jjt|j��dS)N)r.r�r%r5)r=r5rrr r�^sz!FirewallClientConfigHelper.updatecCs|jj�dS)N)r.r�)r=rrr r�csz'FirewallClientConfigHelper.loadDefaultscCs|jj�dS)N)r.rc)r=rrr rchsz!FirewallClientConfigHelper.removecCs|jj|�dS)N)r.r�)r=r�rrr r�msz!FirewallClientConfigHelper.renamecCs
|jj�S)N)r.rP)r=rrr rPtsz%FirewallClientConfigHelper.getVersioncCs|jj|�dS)N)r.rQ)r=r$rrr rQysz%FirewallClientConfigHelper.setVersioncCs
|jj�S)N)r.rS)r=rrr rS�sz#FirewallClientConfigHelper.getShortcCs|jj|�dS)N)r.rT)r=r%rrr rT�sz#FirewallClientConfigHelper.setShortcCs
|jj�S)N)r.rV)r=rrr rV�sz)FirewallClientConfigHelper.getDescriptioncCs|jj|�dS)N)r.rW)r=r&rrr rW�sz)FirewallClientConfigHelper.setDescriptioncCs
|jj�S)N)r.rh)r=rrr rh�sz#FirewallClientConfigHelper.getPortscCs|jj|�dS)N)r.ri)r=r*rrr ri�sz#FirewallClientConfigHelper.setPortscCs|jj||�dS)N)r.rl)r=rjrkrrr rl�sz"FirewallClientConfigHelper.addPortcCs|jj||�dS)N)r.rm)r=rjrkrrr rm�sz%FirewallClientConfigHelper.removePortcCs|jj||�S)N)r.rn)r=rjrkrrr rn�sz$FirewallClientConfigHelper.queryPortcCs
|jj�S)N)r.r')r=rrr r'�sz$FirewallClientConfigHelper.getFamilycCs$|dkr|jjd�|jj|�dS)Nr#)r.r))r=r(rrr r)�sz$FirewallClientConfigHelper.setFamilycCs
|jj�S)N)r.r*)r=rrr r*�sz$FirewallClientConfigHelper.getModulecCs|jj|�dS)N)r.r+)r=r�rrr r+�sz$FirewallClientConfigHelper.setModuleN) r�r�r�r!r@r�rr�r�r�r�r�r�r�r�rcr�rPrQrSrTrVrWrhrirlrmrnr'r)r*r+rrrr r,:s^r,c@s�eZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zejjjed)d*���Zejjjed+d,���Zejjjed-d.���Zejjjed/d0���Zejjjed1d2���Z ejjjed3d4���Z!ejjjed5d6���Z"ejjjed7d8���Z#ejjjed9d:���Z$ejjjed;d<���Z%ejjjed=d>���Z&ejjjed?d@���Z'ejjjedAdB���Z(ejjjedCdD���Z)ejjjedEdF���Z*ejjjedGdH���Z+ejjjedIdJ���Z,ejjjedKdL���Z-ejjjedMdN���Z.ejjjed^dPdQ���Z/ejjjedRdS���Z0ejjjedTdU���Z1ejjjedVdW���Z2ejjjedXdY���Z3ejjjedZd[���Z4ejjjed\d]���Z5dOS)_�FirewallClientConfigServicecCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)r�zorg.freedesktop.DBus.Properties)r�r�r�rrr�r�r��DBUS_INTERFACE_CONFIG_SERVICE�
fw_servicer�)r=r�r�rrr r@�sz$FirewallClientConfigService.__init__cCst|jjtjj|��S)N)r	r�r�rrr0)r=r�rrr r��sz(FirewallClientConfigService.get_propertycCst|jjtjj��S)N)r	r�r�rrr0)r=rrr r��sz*FirewallClientConfigService.get_propertiescCs|jjtjj||�dS)N)r�r�rrr0)r=r�rErrr r��sz(FirewallClientConfigService.set_propertycCstt|jj���S)N)r�r	r1r�)r=rrr r��sz'FirewallClientConfigService.getSettingscCs|jj|j��dS)N)r1r�rM)r=r5rrr r��sz"FirewallClientConfigService.updatecCs|jj�dS)N)r1r�)r=rrr r��sz(FirewallClientConfigService.loadDefaultscCs|jj�dS)N)r1rc)r=rrr rc�sz"FirewallClientConfigService.removecCs|jj|�dS)N)r1r�)r=r�rrr r�sz"FirewallClientConfigService.renamecCs
|jj�S)N)r1rP)r=rrr rPsz&FirewallClientConfigService.getVersioncCs|jj|�dS)N)r1rQ)r=r$rrr rQsz&FirewallClientConfigService.setVersioncCs
|jj�S)N)r1rS)r=rrr rSsz$FirewallClientConfigService.getShortcCs|jj|�dS)N)r1rT)r=r%rrr rTsz$FirewallClientConfigService.setShortcCs
|jj�S)N)r1rV)r=rrr rVsz*FirewallClientConfigService.getDescriptioncCs|jj|�dS)N)r1rW)r=r&rrr rW$sz*FirewallClientConfigService.setDescriptioncCs
|jj�S)N)r1rh)r=rrr rh+sz$FirewallClientConfigService.getPortscCs|jj|�dS)N)r1ri)r=r*rrr ri0sz$FirewallClientConfigService.setPortscCs|jj||�dS)N)r1rl)r=rjrkrrr rl5sz#FirewallClientConfigService.addPortcCs|jj||�dS)N)r1rm)r=rjrkrrr rm:sz&FirewallClientConfigService.removePortcCs|jj||�S)N)r1rn)r=rjrkrrr rn?sz%FirewallClientConfigService.queryPortcCs
|jj�S)N)r1rp)r=rrr rpFsz(FirewallClientConfigService.getProtocolscCs|jj|�dS)N)r1rq)r=r0rrr rqKsz(FirewallClientConfigService.setProtocolscCs|jj|�dS)N)r1rr)r=rkrrr rrPsz'FirewallClientConfigService.addProtocolcCs|jj|�dS)N)r1rs)r=rkrrr rsUsz*FirewallClientConfigService.removeProtocolcCs|jj|�S)N)r1rt)r=rkrrr rtZsz)FirewallClientConfigService.queryProtocolcCs
|jj�S)N)r1rv)r=rrr rvasz*FirewallClientConfigService.getSourcePortscCs|jj|�dS)N)r1rw)r=r*rrr rwfsz*FirewallClientConfigService.setSourcePortscCs|jj||�dS)N)r1rx)r=rjrkrrr rxksz)FirewallClientConfigService.addSourcePortcCs|jj||�dS)N)r1ry)r=rjrkrrr rypsz,FirewallClientConfigService.removeSourcePortcCs|jj||�S)N)r1rz)r=rjrkrrr rzusz+FirewallClientConfigService.querySourcePortcCs
|jj�S)N)r1r�)r=rrr r�|sz&FirewallClientConfigService.getModulescCs|jj|�dS)N)r1r�)r=r�rrr r��sz&FirewallClientConfigService.setModulescCs|jj|�dS)N)r1r�)r=r�rrr r��sz%FirewallClientConfigService.addModulecCs|jj|�dS)N)r1r�)r=r�rrr r��sz(FirewallClientConfigService.removeModulecCs|jj|�S)N)r1r�)r=r�rrr r��sz'FirewallClientConfigService.queryModulecCs
|jj�S)N)r1r�)r=rrr r��sz+FirewallClientConfigService.getDestinationscCs|jj|�dS)N)r1r�)r=r�rrr r��sz+FirewallClientConfigService.setDestinationscCs|jj|�S)N)r1�getDestination)r=r�rrr r2�sz*FirewallClientConfigService.getDestinationcCs|jj||�dS)N)r1r)r=r�rrrr r�sz*FirewallClientConfigService.setDestinationNcCs:|dk	r*|j|�|kr*ttjd||f��|jj|�dS)Nz'%s:%s')r2rrrdr1r)r=r�rrrr r�sz-FirewallClientConfigService.removeDestinationcCs|jj||�S)N)r1r)r=r�rrrr r�sz,FirewallClientConfigService.queryDestinationcCs
|jj�S)N)r1r)r=rrr r�sz'FirewallClientConfigService.getIncludescCs|jj|�dS)N)r1r)r=r�rrr r�sz'FirewallClientConfigService.setIncludescCs|jj|�dS)N)r1r)r=rrrr r�sz&FirewallClientConfigService.addIncludecCs|jj|�dS)N)r1r)r=rrrr r�sz)FirewallClientConfigService.removeIncludecCs|jj|�S)N)r1r	)r=rrrr r	�sz(FirewallClientConfigService.queryInclude)N)6r�r�r�r!r@r�rr�r�r�r�r�r�r�r�rcr�rPrQrSrTrVrWrhrirlrmrnrprqrrrsrtrvrwrxryrzr�r�r�r�r�r�r�r2rrrrrrrr	rrrr r/�s�r/c@s�eZdZeddd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��ZdS)�FirewallClientIcmpTypeSettingsNcCs|r||_ndddgg|_dS)Nr#)r5)r=r5rrr r@�sz'FirewallClientIcmpTypeSettings.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rB�sz'FirewallClientIcmpTypeSettings.__repr__cCs
|jdS)Nr)r5)r=rrr rP�sz)FirewallClientIcmpTypeSettings.getVersioncCs||jd<dS)Nr)r5)r=r$rrr rQ�sz)FirewallClientIcmpTypeSettings.setVersioncCs
|jdS)NrR)r5)r=rrr rS�sz'FirewallClientIcmpTypeSettings.getShortcCs||jd<dS)NrR)r5)r=r%rrr rT�sz'FirewallClientIcmpTypeSettings.setShortcCs
|jdS)NrU)r5)r=rrr rV�sz-FirewallClientIcmpTypeSettings.getDescriptioncCs||jd<dS)NrU)r5)r=r&rrr rW�sz-FirewallClientIcmpTypeSettings.setDescriptioncCs
|jdS)Nr�)r5)r=rrr r��sz.FirewallClientIcmpTypeSettings.getDestinationscCs||jd<dS)Nr�)r5)r=r�rrr r��sz.FirewallClientIcmpTypeSettings.setDestinationscCsH|jdsttj|��n,||jdkr8|jdj|�nttj|��dS)Nr�)r5rrr`r_)r=r�rrr �addDestination�s

z-FirewallClientIcmpTypeSettings.addDestinationcCs\||jdkr |jdj|�n8|jdsL|jttddg�t|g���nttj|��dS)Nr�Zipv4Zipv6)r5rcr�r9�setrrrd)r=r�rrr r	s
z0FirewallClientIcmpTypeSettings.removeDestinationcCs|jdp||jdkS)Nr�)r5)r=r�rrr r	sz/FirewallClientIcmpTypeSettings.queryDestination)N)r�r�r�r!r@rBrPrQrSrTrVrWr�r�r4rrrrrr r3�s	r3c@s�eZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zd)S)*�FirewallClientConfigIcmpTypecCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)r�zorg.freedesktop.DBus.Properties)r�r�r�rrr�r�r��DBUS_INTERFACE_CONFIG_ICMPTYPE�fw_icmptyper�)r=r�r�rrr r@	sz%FirewallClientConfigIcmpType.__init__cCst|jjtjj|��S)N)r	r�r�rrr7)r=r�rrr r�%	sz)FirewallClientConfigIcmpType.get_propertycCst|jjtjj��S)N)r	r�r�rrr7)r=rrr r�+	sz+FirewallClientConfigIcmpType.get_propertiescCs|jjtjj||�dS)N)r�r�rrr7)r=r�rErrr r�1	sz)FirewallClientConfigIcmpType.set_propertycCsttt|jj����S)N)r3r9r	r8r�)r=rrr r�7	sz(FirewallClientConfigIcmpType.getSettingscCs|jjt|j��dS)N)r8r�r%r5)r=r5rrr r�=	sz#FirewallClientConfigIcmpType.updatecCs|jj�dS)N)r8r�)r=rrr r�B	sz)FirewallClientConfigIcmpType.loadDefaultscCs|jj�dS)N)r8rc)r=rrr rcG	sz#FirewallClientConfigIcmpType.removecCs|jj|�dS)N)r8r�)r=r�rrr r�L	sz#FirewallClientConfigIcmpType.renamecCs
|jj�S)N)r8rP)r=rrr rPS	sz'FirewallClientConfigIcmpType.getVersioncCs|jj|�dS)N)r8rQ)r=r$rrr rQX	sz'FirewallClientConfigIcmpType.setVersioncCs
|jj�S)N)r8rS)r=rrr rS_	sz%FirewallClientConfigIcmpType.getShortcCs|jj|�dS)N)r8rT)r=r%rrr rTd	sz%FirewallClientConfigIcmpType.setShortcCs
|jj�S)N)r8rV)r=rrr rVk	sz+FirewallClientConfigIcmpType.getDescriptioncCs|jj|�dS)N)r8rW)r=r&rrr rWp	sz+FirewallClientConfigIcmpType.setDescriptioncCs
|jj�S)N)r8r�)r=rrr r�w	sz,FirewallClientConfigIcmpType.getDestinationscCs|jj|�dS)N)r8r�)r=r�rrr r�|	sz,FirewallClientConfigIcmpType.setDestinationscCs|jj|�dS)N)r8r4)r=r�rrr r4�	sz+FirewallClientConfigIcmpType.addDestinationcCs|jj|�dS)N)r8r)r=r�rrr r�	sz.FirewallClientConfigIcmpType.removeDestinationcCs|jj|�S)N)r8r)r=r�rrr r�	sz-FirewallClientConfigIcmpType.queryDestinationN)r�r�r�r!r@r�rr�r�r�r�r�r�r�r�rcr�rPrQrSrTrVrWr�r�r4rrrrrr r6	sNr6c@seZdZed.dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��Zed*d+��Zed,d-��ZdS)/�'FirewallClientPoliciesLockdownWhitelistNcCs|r||_nggggg|_dS)N)r5)r=r5rrr r@�	sz0FirewallClientPoliciesLockdownWhitelist.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rB�	sz0FirewallClientPoliciesLockdownWhitelist.__repr__cCs
|jdS)Nr)r5)r=rrr �getCommands�	sz3FirewallClientPoliciesLockdownWhitelist.getCommandscCs||jd<dS)Nr)r5)r=Zcommandsrrr �setCommands�	sz3FirewallClientPoliciesLockdownWhitelist.setCommandscCs"||jdkr|jdj|�dS)Nr)r5r_)r=�commandrrr �
addCommand�	sz2FirewallClientPoliciesLockdownWhitelist.addCommandcCs"||jdkr|jdj|�dS)Nr)r5rc)r=r<rrr �
removeCommand�	sz5FirewallClientPoliciesLockdownWhitelist.removeCommandcCs||jdkS)Nr)r5)r=r<rrr �queryCommand�	sz4FirewallClientPoliciesLockdownWhitelist.queryCommandcCs
|jdS)NrR)r5)r=rrr �getContexts�	sz3FirewallClientPoliciesLockdownWhitelist.getContextscCs||jd<dS)NrR)r5)r=Zcontextsrrr �setContexts�	sz3FirewallClientPoliciesLockdownWhitelist.setContextscCs"||jdkr|jdj|�dS)NrR)r5r_)r=�contextrrr �
addContext�	sz2FirewallClientPoliciesLockdownWhitelist.addContextcCs"||jdkr|jdj|�dS)NrR)r5rc)r=rBrrr �
removeContext�	sz5FirewallClientPoliciesLockdownWhitelist.removeContextcCs||jdkS)NrR)r5)r=rBrrr �queryContext�	sz4FirewallClientPoliciesLockdownWhitelist.queryContextcCs
|jdS)NrU)r5)r=rrr �getUsers�	sz0FirewallClientPoliciesLockdownWhitelist.getUserscCs||jd<dS)NrU)r5)r=Zusersrrr �setUsers�	sz0FirewallClientPoliciesLockdownWhitelist.setUserscCs"||jdkr|jdj|�dS)NrU)r5r_)r=�userrrr �addUser�	sz/FirewallClientPoliciesLockdownWhitelist.addUsercCs"||jdkr|jdj|�dS)NrU)r5rc)r=rHrrr �
removeUser�	sz2FirewallClientPoliciesLockdownWhitelist.removeUsercCs||jdkS)NrU)r5)r=rHrrr �	queryUser�	sz1FirewallClientPoliciesLockdownWhitelist.queryUsercCs
|jdS)Nr�)r5)r=rrr �getUids�	sz/FirewallClientPoliciesLockdownWhitelist.getUidscCs||jd<dS)Nr�)r5)r=�uidsrrr �setUids�	sz/FirewallClientPoliciesLockdownWhitelist.setUidscCs"||jdkr|jdj|�dS)Nr�)r5r_)r=�uidrrr �addUid�	sz.FirewallClientPoliciesLockdownWhitelist.addUidcCs"||jdkr|jdj|�dS)Nr�)r5rc)r=rOrrr �	removeUid�	sz1FirewallClientPoliciesLockdownWhitelist.removeUidcCs||jdkS)Nr�)r5)r=rOrrr �queryUid�	sz0FirewallClientPoliciesLockdownWhitelist.queryUid)N)r�r�r�r!r@rBr:r;r=r>r?r@rArCrDrErFrGrIrJrKrLrNrPrQrRrrrr r9�	s.r9c@s�eZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zd)S)*�FirewallClientConfigPoliciescCs8||_|jjtjjtjj�|_tj|jtjjd�|_	dS)N)r�)
r�r�rrr��DBUS_PATH_CONFIGr�r��DBUS_INTERFACE_CONFIG_POLICIES�fw_policies)r=r�rrr r@�	sz%FirewallClientConfigPolicies.__init__cCsttt|jj����S)N)r9r9r	rV�getLockdownWhitelist)r=rrr rW�	sz1FirewallClientConfigPolicies.getLockdownWhitelistcCs|jjt|j��dS)N)rV�setLockdownWhitelistr%r5)r=r5rrr rX�	sz1FirewallClientConfigPolicies.setLockdownWhitelistcCs|jj|�dS)N)rV�addLockdownWhitelistCommand)r=r<rrr rY
sz8FirewallClientConfigPolicies.addLockdownWhitelistCommandcCs|jj|�dS)N)rV�removeLockdownWhitelistCommand)r=r<rrr rZ
sz;FirewallClientConfigPolicies.removeLockdownWhitelistCommandcCst|jj|��S)N)r	rV�queryLockdownWhitelistCommand)r=r<rrr r[

sz:FirewallClientConfigPolicies.queryLockdownWhitelistCommandcCst|jj��S)N)r	rV�getLockdownWhitelistCommands)r=rrr r\
sz9FirewallClientConfigPolicies.getLockdownWhitelistCommandscCs|jj|�dS)N)rV�addLockdownWhitelistContext)r=rBrrr r]
sz8FirewallClientConfigPolicies.addLockdownWhitelistContextcCs|jj|�dS)N)rV�removeLockdownWhitelistContext)r=rBrrr r^
sz;FirewallClientConfigPolicies.removeLockdownWhitelistContextcCst|jj|��S)N)r	rV�queryLockdownWhitelistContext)r=rBrrr r_ 
sz:FirewallClientConfigPolicies.queryLockdownWhitelistContextcCst|jj��S)N)r	rV�getLockdownWhitelistContexts)r=rrr r`%
sz9FirewallClientConfigPolicies.getLockdownWhitelistContextscCs|jj|�dS)N)rV�addLockdownWhitelistUser)r=rHrrr ra,
sz5FirewallClientConfigPolicies.addLockdownWhitelistUsercCs|jj|�dS)N)rV�removeLockdownWhitelistUser)r=rHrrr rb1
sz8FirewallClientConfigPolicies.removeLockdownWhitelistUsercCst|jj|��S)N)r	rV�queryLockdownWhitelistUser)r=rHrrr rc6
sz7FirewallClientConfigPolicies.queryLockdownWhitelistUsercCst|jj��S)N)r	rV�getLockdownWhitelistUsers)r=rrr rd;
sz6FirewallClientConfigPolicies.getLockdownWhitelistUserscCst|jj��S)N)r	rV�getLockdownWhitelistUids)r=rrr reB
sz5FirewallClientConfigPolicies.getLockdownWhitelistUidscCs|jj|�dS)N)rV�setLockdownWhitelistUids)r=rMrrr rfG
sz5FirewallClientConfigPolicies.setLockdownWhitelistUidscCs|jj|�dS)N)rV�addLockdownWhitelistUid)r=rOrrr rgL
sz4FirewallClientConfigPolicies.addLockdownWhitelistUidcCs|jj|�dS)N)rV�removeLockdownWhitelistUid)r=rOrrr rhQ
sz7FirewallClientConfigPolicies.removeLockdownWhitelistUidcCst|jj|��S)N)r	rV�queryLockdownWhitelistUid)r=rOrrr riV
sz6FirewallClientConfigPolicies.queryLockdownWhitelistUidN)r�r�r�r!r@r�rr�r�rWrXrYrZr[r\r]r^r_r`rarbrcrdrerfrgrhrirrrr rS�	sN	rSc@seZdZed.dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��Zed*d+��Zed,d-��ZdS)/�FirewallClientDirectNcCs|r||_ngggg|_dS)N)r5)r=r5rrr r@^
szFirewallClientDirect.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rBe
szFirewallClientDirect.__repr__cCs
|jdS)Nr)r5)r=rrr �getAllChainsi
sz!FirewallClientDirect.getAllChainscs��fdd�|jdD�S)Ncs,g|]$}|d�kr|d�kr|d�qS)rrRrUr)r�r)r(�tablerr r�n
sz2FirewallClientDirect.getChains.<locals>.<listcomp>r)r5)r=r(rlr)r(rlr �	getChainsl
szFirewallClientDirect.getChainscCs||jd<dS)Nr)r5)r=Zchainsrrr �setAllChainsp
sz!FirewallClientDirect.setAllChainscCs,|||f}||jdkr(|jdj|�dS)Nr)r5r_)r=r(rl�chain�idxrrr �addChains
s
zFirewallClientDirect.addChaincCs,|||f}||jdkr(|jdj|�dS)Nr)r5rc)r=r(rlrorprrr �removeChainx
s
z FirewallClientDirect.removeChaincCs|||f}||jdkS)Nr)r5)r=r(rlrorprrr �
queryChain}
s
zFirewallClientDirect.queryChaincCs
|jdS)NrR)r5)r=rrr �getAllRules�
sz FirewallClientDirect.getAllRulescs���fdd�|jdD�S)Ncs<g|]4}|d�kr|d�kr|d�kr|dd��qS)rrRrUr�Nr)r�r)ror(rlrr r��
sz1FirewallClientDirect.getRules.<locals>.<listcomp>rR)r5)r=r(rlror)ror(rlr �getRules�
szFirewallClientDirect.getRulescCs||jd<dS)NrR)r5)r=r�rrr �setAllRules�
sz FirewallClientDirect.setAllRulescCs0|||||f}||jdkr,|jdj|�dS)NrR)r5r_)r=r(rlror�rrprrr �addRule�
szFirewallClientDirect.addRulecCs0|||||f}||jdkr,|jdj|�dS)NrR)r5rc)r=r(rlror�rrprrr �
removeRule�
szFirewallClientDirect.removeRulecCsPxJt|jd�D]8}|d|kr|d|kr|d|kr|jdj|�qWdS)NrRrrU)r9r5rc)r=r(rlrorprrr �removeRules�
s$z FirewallClientDirect.removeRulescCs|||||f}||jdkS)NrR)r5)r=r(rlror�rrprrr �	queryRule�
szFirewallClientDirect.queryRulecCs
|jdS)NrU)r5)r=rrr �getAllPassthroughs�
sz'FirewallClientDirect.getAllPassthroughscCs||jd<dS)NrU)r5)r=Zpassthroughsrrr �setAllPassthroughs�
sz'FirewallClientDirect.setAllPassthroughscCsg|jd<dS)NrU)r5)r=rrr �removeAllPassthroughs�
sz*FirewallClientDirect.removeAllPassthroughscs�fdd�|jdD�S)Ncs g|]}|d�kr|d�qS)rrRr)r�r)r(rr r��
sz8FirewallClientDirect.getPassthroughs.<locals>.<listcomp>rU)r5)r=r(r)r(r �getPassthroughs�
sz$FirewallClientDirect.getPassthroughscCs*||f}||jdkr&|jdj|�dS)NrU)r5r_)r=r(rrprrr �addPassthrough�
sz#FirewallClientDirect.addPassthroughcCs*||f}||jdkr&|jdj|�dS)NrU)r5rc)r=r(rrprrr �removePassthrough�
sz&FirewallClientDirect.removePassthroughcCs||f}||jdkS)NrU)r5)r=r(rrprrr �queryPassthrough�
sz%FirewallClientDirect.queryPassthrough)N)r�r�r�r!r@rBrkrmrnrqrrrsrtrurvrwrxryrzr{r|r}r~rr�r�rrrr rj]
s.rjc@s�eZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zd'S)(�FirewallClientConfigDirectcCs8||_|jjtjjtjj�|_tj|jtjjd�|_	dS)N)r�)
r�r�rrr�rTr�r��DBUS_INTERFACE_CONFIG_DIRECT�	fw_direct)r=r�rrr r@�
sz#FirewallClientConfigDirect.__init__cCsttt|jj����S)N)rjr9r	r�r�)r=rrr r��
sz&FirewallClientConfigDirect.getSettingscCs|jjt|j��dS)N)r�r�r%r5)r=r5rrr r��
sz!FirewallClientConfigDirect.updatecCs|jj|||�dS)N)r�rq)r=r(rlrorrr rq�
sz#FirewallClientConfigDirect.addChaincCs|jj|||�dS)N)r�rr)r=r(rlrorrr rr�
sz&FirewallClientConfigDirect.removeChaincCst|jj|||��S)N)r	r�rs)r=r(rlrorrr rs�
sz%FirewallClientConfigDirect.queryChaincCst|jj||��S)N)r	r�rm)r=r(rlrrr rm�
sz$FirewallClientConfigDirect.getChainscCst|jj��S)N)r	r�rk)r=rrr rk�
sz'FirewallClientConfigDirect.getAllChainscCs|jj|||||�dS)N)r�rw)r=r(rlror�rrrr rw�
sz"FirewallClientConfigDirect.addRulecCs|jj|||||�dS)N)r�rx)r=r(rlror�rrrr rx�
sz%FirewallClientConfigDirect.removeRulecCs|jj|||�dS)N)r�ry)r=r(rlrorrr ry�
sz&FirewallClientConfigDirect.removeRulescCst|jj|||||��S)N)r	r�rz)r=r(rlror�rrrr rzsz$FirewallClientConfigDirect.queryRulecCst|jj|||��S)N)r	r�ru)r=r(rlrorrr rusz#FirewallClientConfigDirect.getRulescCst|jj��S)N)r	r�rt)r=rrr rt
sz&FirewallClientConfigDirect.getAllRulescCs|jj||�dS)N)r�r)r=r(rrrr rsz)FirewallClientConfigDirect.addPassthroughcCs|jj||�dS)N)r�r�)r=r(rrrr r�sz,FirewallClientConfigDirect.removePassthroughcCst|jj||��S)N)r	r�r�)r=r(rrrr r�sz+FirewallClientConfigDirect.queryPassthroughcCst|jj|��S)N)r	r�r~)r=r(rrr r~ sz*FirewallClientConfigDirect.getPassthroughscCst|jj��S)N)r	r�r{)r=rrr r{%sz-FirewallClientConfigDirect.getAllPassthroughsN)r�r�r�r!r@r�rr�r�r�r�rqrrrsrmrkrwrxryrzrurtrr�r�r~r{rrrr r��
sJ	r�c@sFeZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zejjjed)d*���Zejjjed+d,���Zejjjed-d.���Zejjjed/d0���Zejjjed1d2���Z ejjjed3d4���Z!ejjjed5d6���Z"ejjjed7d8���Z#ejjjed9d:���Z$ejjjed;d<���Z%ejjjed=d>���Z&ejjjed?d@���Z'ejjjedAdB���Z(ejjjedCdD���Z)ejjjedEdF���Z*ejjjedGdH���Z+ejjjedIdJ���Z,ejjjedKdL���Z-dMS)N�FirewallClientConfigcCsb||_|jjtjjtjj�|_tj|jtjjd�|_	tj|jdd�|_
t|j�|_t
|j�|_dS)N)r�zorg.freedesktop.DBus.Properties)r�r�rrr�rTr�r��DBUS_INTERFACE_CONFIG�	fw_configr�rS�	_policiesr��_direct)r=r�rrr r@-szFirewallClientConfig.__init__cCst|jjtjj|��S)N)r	r�r�rrr�)r=r�rrr r�<sz!FirewallClientConfig.get_propertycCst|jjtjj��S)N)r	r�r�rrr�)r=rrr r�Bsz#FirewallClientConfig.get_propertiescCs|jjtjj||�dS)N)r�r�rrr�)r=r�rErrr r�Hsz!FirewallClientConfig.set_propertycCst|jj��S)N)r	r��
getIPSetNames)r=rrr r�Osz"FirewallClientConfig.getIPSetNamescCst|jj��S)N)r	r��
listIPSets)r=rrr r�TszFirewallClientConfig.listIPSetscCst|j|�S)N)r"r�)r=r�rrr �getIPSetYszFirewallClientConfig.getIPSetcCst|jj|��}t|j|�S)N)r	r��getIPSetByNamer"r�)r=r�r�rrr r�^sz#FirewallClientConfig.getIPSetByNamecCs>t|t�r |jj|t|j��}n|jj|t|��}t|j|�S)N)r8rr��addIPSetr%r5r"r�)r=r�r5r�rrr r�ds
zFirewallClientConfig.addIPSetcCst|jj��S)N)r	r��getZoneNames)r=rrr r�osz!FirewallClientConfig.getZoneNamescCst|jj��S)N)r	r��	listZones)r=rrr r�tszFirewallClientConfig.listZonescCst|j|�S)N)r�r�)r=r�rrr �getZoneyszFirewallClientConfig.getZonecCst|jj|��}t|j|�S)N)r	r��
getZoneByNamer�r�)r=r�r�rrr r�~sz"FirewallClientConfig.getZoneByNamecCst|jj|��S)N)r	r��getZoneOfInterface)r=Zifacerrr r��sz'FirewallClientConfig.getZoneOfInterfacecCst|jj|��S)N)r	r��getZoneOfSource)r=r�rrr r��sz$FirewallClientConfig.getZoneOfSourcecCs^t|t�r|jj||j��}n4t|t�r8|jj||�}n|jj|t|dd���}t|j	|�S)Nr�)
r8r"r�ZaddZone2rMr;�addZoner%r�r�)r=r�r5r�rrr r��s

zFirewallClientConfig.addZonecCst|jj��S)N)r	r��getPolicyNames)r=rrr r��sz#FirewallClientConfig.getPolicyNamescCst|jj��S)N)r	r��listPolicies)r=rrr r��sz!FirewallClientConfig.listPoliciescCst|j|�S)N)r�r�)r=r�rrr �	getPolicy�szFirewallClientConfig.getPolicycCst|jj|��}t|j|�S)N)r	r��getPolicyByNamer�r�)r=r�r�rrr r��sz$FirewallClientConfig.getPolicyByNamecCs8t|t�r|jj||j��}n|jj||�}t|j|�S)N)r8r�r��	addPolicyrMr�r�)r=r�r5r�rrr r��s
zFirewallClientConfig.addPolicycCst|jj��S)N)r	r��getServiceNames)r=rrr r��sz$FirewallClientConfig.getServiceNamescCst|jj��S)N)r	r��listServices)r=rrr r��sz!FirewallClientConfig.listServicescCst|j|�S)N)r/r�)r=r�rrr �
getService�szFirewallClientConfig.getServicecCst|jj|��}t|j|�S)N)r	r��getServiceByNamer/r�)r=r�r�rrr r��sz%FirewallClientConfig.getServiceByNamecCs`t|t�r|jj||j��}n6t|�tkr:|jj||�}n|jj|t|dd���}t	|j
|�S)Nr�)r8r�r�ZaddService2rMrIr;rbr%r/r�)r=r�r5r�rrr rb�s
zFirewallClientConfig.addServicecCst|jj��S)N)r	r��getIcmpTypeNames)r=rrr r��sz%FirewallClientConfig.getIcmpTypeNamescCst|jj��S)N)r	r��
listIcmpTypes)r=rrr r��sz"FirewallClientConfig.listIcmpTypescCst|j|�S)N)r6r�)r=r�rrr �getIcmpType�sz FirewallClientConfig.getIcmpTypecCst|jj|��}t|j|�S)N)r	r��getIcmpTypeByNamer6r�)r=r�r�rrr r��sz&FirewallClientConfig.getIcmpTypeByNamecCs>t|t�r |jj|t|j��}n|jj|t|��}t|j|�S)N)r8r3r��addIcmpTyper%r5r6r�)r=r�r5r�rrr r��s
z FirewallClientConfig.addIcmpTypecCs|jS)N)r�)r=rrr �policies�szFirewallClientConfig.policiescCs|jS)N)r�)r=rrr �directszFirewallClientConfig.directcCst|jj��S)N)r	r��getHelperNames)r=rrr r�sz#FirewallClientConfig.getHelperNamescCst|jj��S)N)r	r��listHelpers)r=rrr r�sz FirewallClientConfig.listHelperscCst|j|�S)N)r,r�)r=r�rrr �	getHelperszFirewallClientConfig.getHelpercCst|jj|��}t|j|�S)N)r	r��getHelperByNamer,r�)r=r�r�rrr r�sz$FirewallClientConfig.getHelperByNamecCs>t|t�r |jj|t|j��}n|jj|t|��}t|j|�S)N)r8r&r�r
r%r5r,r�)r=r�r5r�rrr r
 s
zFirewallClientConfig.addHelperN).r�r�r�r!r@r�rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rbr�r�r�r�r�r�r�r�r�r�r�r
rrrr r�,s�

r�c@s�eZdZe�ddd��Zedd��Zedd	��Zed
d��Zedd
��Zedd��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zejjjedd���Zejjjedd���Zejjjedd���Zejjjed d!���Zejjjed"d#���Zejjjed$d%���Zejjjed&d'���Zejjjed(d)���Zejjjed*d+���Zejjjed,d-���Zejjjed.d/���Zejjjed0d1���Zejjjed2d3���Zejjjed4d5���Z ejjjed6d7���Z!ejjjed8d9���Z"ejjjed:d;���Z#ejjjed<d=���Z$ejjjed>d?���Z%ejjjed@dA���Z&ejjjedBdC���Z'ejjjedDdE���Z(ejjjedFdG���Z)ejjjedHdI���Z*ejjjedJdK���Z+ejjjedLdM���Z,ejjjedNdO���Z-ejjjedPdQ���Z.ejjjedRdS���Z/ejjjedTdU���Z0ejjjedVdW���Z1ejjjedXdY���Z2ejjjedZd[���Z3ejjjed\d]���Z4ejjjed^d_���Z5ejjjed`da���Z6ejjjedbdc���Z7ejjjeddde���Z8ejjjedfdg���Z9ejjjedhdi���Z:ejjjedjdk���Z;ejjjedldm���Z<ejjjedndo���Z=ejjjedpdq���Z>ejjjedrds���Z?ejjjedtdu���Z@ejjjedvdw���ZAejjjedxdy���ZBejjjedzd{���ZCejjjed|d}���ZDejjjed~d���ZEejjjed�d����ZFejjjed�d����ZGejjje�dd�d����ZHejjjed�d����ZIejjjed�d����ZJejjjed�d����ZKejjje�dd�d����ZLejjjed�d����ZMejjjed�d����ZNejjjed�d����ZOejjje�dd�d����ZPejjjed�d����ZQejjjed�d����ZRejjjed�d����ZSejjje�dd�d����ZTejjjed�d����ZUejjjed�d����ZVejjjed�d����ZWejjjed�d����ZXejjjed�d����ZYejjjed�d����ZZejjje�dd�d����Z[ejjjed�d����Z\ejjjed�d����Z]ejjje�d d�d����Z^ejjjed�d����Z_ejjjed�d����Z`ejjjed�d����Zaejjje�d!d�d����Zbejjjed�d����Zcejjjed�d����Zdejjjed�d����Zeejjje�d"d�d����Zfejjjed�dÄ��Zgejjjed�dń��Zhejjjed�dDŽ��Ziejjjed�dɄ��Zjejjjed�d˄��Zkejjjed�d̈́��Zlejjjed�dτ��Zmejjjed�dф��Znejjjed�dӄ��Zoejjjed�dՄ��Zpejjjed�dׄ��Zqejjjed�dل��Zrejjjed�dۄ��Zsejjjed�d݄��Ztejjjed�d߄��Zuejjjed�d���Zvejjjed�d���Zwejjjed�d���Zxejjjed�d���Zyejjjed�d���Zzejjjed�d���Z{ejjjed�d���Z|ejjjed�d���Z}ejjjed�d���Z~ejjjed�d���Zejjjed�d����Z�ejjjed�d����Z�ejjjed�d����Z�ejjjed�d����Z�ejjjed�d����Z�ejjjed�d����Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d	���Z�ejjje�d
�d���Z�ejjje�d�d
���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�dS(#�FirewallClientNrTcdCs|s�tjjjdd�ytjj�|_d|j_Wq�tk
r�ytj�|_Wn6tj	j
k
r�}zttj
|j���WYdd}~Xn
Xtd�Yq�Xn||_|jj|jddtjjd�x�tjjtjjtjjtjjtjjtjjtjjtjjtjjtjjtjjtjjtjjtjj tjj!gD]}|jj|j"|ddd	d
��qWi|_#ddd
ddddddddddddddddddd d!d"d#d$d%d&d'd'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdY�O|_$|j%�||_&|dZk�rt'j(||j)�n|j)�dS)[NT)Zset_as_defaultzNot using slip.dbusZNameOwnerChangedzorg.freedesktop.DBus)Zhandler_functionZsignal_namer�Zarg0r��memberr�)r�Zinterface_keywordZmember_keywordZpath_keywordzconnection-changedzconnection-establishedzconnection-lostZLogDeniedChangedZDefaultZoneChangedZPanicModeEnabledZPanicModeDisabledZReloadedZServiceAddedZServiceRemovedZ	PortAddedZPortRemovedZSourcePortAddedZSourcePortRemovedZ
ProtocolAddedZProtocolRemovedZMasqueradeAddedZMasqueradeRemovedZForwardPortAddedZForwardPortRemovedZIcmpBlockAddedZIcmpBlockRemovedZIcmpBlockInversionAddedZIcmpBlockInversionRemovedZ
RichRuleAddedZRichRuleRemovedZInterfaceAddedZInterfaceRemovedZZoneOfInterfaceChangedZSourceAddedZ
SourceRemovedZZoneOfSourceChangedZZoneUpdatedZ
PolicyUpdatedZ
EntryAddedZEntryRemovedZ
ChainAddedZChainRemovedZ	RuleAddedZRuleRemovedZPassthroughAddedZPassthroughRemovedzconfig:direct:UpdatedZLockdownEnabledZLockdownDisabledZLockdownWhitelistCommandAddedZLockdownWhitelistCommandRemovedZLockdownWhitelistContextAddedZLockdownWhitelistContextRemovedZLockdownWhitelistUidAddedZLockdownWhitelistUidRemovedZLockdownWhitelistUserAddedZLockdownWhitelistUserRemovedz(config:policies:LockdownWhitelistUpdatedzconfig:IPSetAddedzconfig:IPSetUpdatedzconfig:IPSetRemovedzconfig:IPSetRenamedzconfig:ZoneAddedzconfig:ZoneUpdatedzconfig:ZoneRemovedzconfig:ZoneRenamedzconfig:PolicyAddedzconfig:PolicyUpdatedzconfig:PolicyRemovedzconfig:PolicyRenamedzconfig:ServiceAddedzconfig:ServiceUpdatedzconfig:ServiceRemovedzconfig:ServiceRenamedzconfig:IcmpTypeAddedzconfig:IcmpTypeUpdatedzconfig:IcmpTypeRemovedzconfig:IcmpTypeRenamedzconfig:HelperAddedzconfig:HelperUpdatedzconfig:HelperRemovedzconfig:HelperRenamed)Ozconnection-changedzconnection-establishedzconnection-lostzlog-denied-changedzdefault-zone-changedzpanic-mode-enabledzpanic-mode-disabledZreloadedz
service-addedzservice-removedz
port-addedzport-removedzsource-port-addedzsource-port-removedzprotocol-addedzprotocol-removedzmasquerade-addedzmasquerade-removedzforward-port-addedzforward-port-removedzicmp-block-addedzicmp-block-removedzicmp-block-inversion-addedzicmp-block-inversion-removedzrichrule-addedzrichrule-removedzinterface-addedzinterface-removedzzone-changedzzone-of-interface-changedzsource-addedzsource-removedzzone-of-source-changedzzone-updatedzpolicy-updatedzipset-entry-addedzipset-entry-removedzdirect:chain-addedzdirect:chain-removedzdirect:rule-addedzdirect:rule-removedzdirect:passthrough-addedzdirect:passthrough-removedzconfig:direct:updatedzlockdown-enabledzlockdown-disabledz lockdown-whitelist-command-addedz"lockdown-whitelist-command-removedz lockdown-whitelist-context-addedz"lockdown-whitelist-context-removedzlockdown-whitelist-uid-addedzlockdown-whitelist-uid-removedzlockdown-whitelist-user-addedzlockdown-whitelist-user-removedz*config:policies:lockdown-whitelist-updatedzconfig:ipset-addedzconfig:ipset-updatedzconfig:ipset-removedzconfig:ipset-renamedzconfig:zone-addedzconfig:zone-updatedzconfig:zone-removedzconfig:zone-renamedzconfig:policy-addedzconfig:policy-updatedzconfig:policy-removedzconfig:policy-renamedzconfig:service-addedzconfig:service-updatedzconfig:service-removedzconfig:service-renamedzconfig:icmptype-addedzconfig:icmptype-updatedzconfig:icmptype-removedzconfig:icmptype-renamedzconfig:helper-addedzconfig:helper-updatedzconfig:helper-removedzconfig:helper-renamedr)*rZmainloopZglibZ
DBusGMainLoopr�Z	SystemBusr�Zdefault_timeoutrrrrrZ
DBUS_ERRORr�printZadd_signal_receiver�_dbus_connection_changedrr��DBUS_INTERFACE_IPSET�DBUS_INTERFACE_ZONE�DBUS_INTERFACE_POLICY�DBUS_INTERFACE_DIRECT�DBUS_INTERFACE_POLICIESr�r#r�r�r0r-r�r7rU�_signal_receiver�	_callback�
_callbacks�
_init_vars�quietrZtimeout_add_seconds�_connection_established)r=r��waitr�rr�rrr r@,s�


zFirewallClient.__init__cCs:d|_d|_d|_d|_d|_d|_d|_d|_d|_dS)NF)	�fwr$r�r�r.r�r��_config�	connected)r=rrr r��szFirewallClient._init_varscCstS)N)r)r=rrr �getExceptionHandler�sz"FirewallClient.getExceptionHandlercCs|adS)N)r)r=Zhandlerrrr �setExceptionHandler�sz"FirewallClient.setExceptionHandlercCstS)N)r)r=rrr �getNotAuthorizedLoop�sz#FirewallClient.getNotAuthorizedLoopcCs|adS)N)r)r=�enablerrr �setNotAuthorizedLoop�sz#FirewallClient.setNotAuthorizedLoopcGs0||jkr ||f|j|j|<ntd|��dS)NzUnknown callback name '%s')r�r��
ValueError)r=r��callbackrrrr �connect�s
zFirewallClient.connectcCs*|tjjkrdS|r|j�n|j�dS)N)rrr�r��_connection_lost)r=r�Z	old_ownerZ	new_ownerrrr r��s

z'FirewallClient._dbus_connection_changedcCsXy�|jjtjjtjj�|_tj|jtjjd�|_tj|jtjj	d�|_
tj|jtjjd�|_tj|jtjj
d�|_tj|jtjjd�|_tj|jtjjd�|_tj|jdd�|_Wnjtjjk
r�}z|js�td|j��dSd}~Xn4tk
�r}z|j�std|�dSd}~XnXt|j�|_d|_|jdtjjd�|jdtjjd�dS)	N)r�zorg.freedesktop.DBus.PropertiesrrTzconnection-established)r�r�zconnection-changed)r�r�rrr�Z	DBUS_PATHr�r�r�r�r$r�r�r�r�r�r�r�rVr�rrr�r�rrr�r�r�r�)r=rrrr r��sD
z&FirewallClient._connection_establishedcCs0|j�|jdtjjd�|jdtjjd�dS)Nzconnection-lost)r�r�zconnection-changed)r�r�rrr�)r=rrr r�
s
zFirewallClient._connection_lostc	Os�d|ksd|krdS|d}|d}|jtjj�r:d|}|jtjj�rRd|}n�|jtjj�rjd|}n�|jtjj�r�d|}np|jtjj�r�d|}nX|jtjj�r�d|}n@|tjj	kr�d	|}n*|tjj
kr�d
|}n|tjjkr�d|}d}x<|jD]2}|j||kr�|j||j
kr�|j
|j|}q�W|dk�rBdSdd
�|D�}y(|d�rj|j|d�|d|�Wn,tk
�r�}zt|�WYdd}~XnXdS)Nr�r�zconfig:Zonez
config:Policyzconfig:IPSetzconfig:Servicezconfig:IcmpTypez
config:Helperzconfig:zconfig:policies:zconfig:direct:cSsg|]}t|��qSr)r	)r��argrrr r�C
sz3FirewallClient._signal_receiver.<locals>.<listcomp>rRr)�
startswithrrr�r�r#r0r7r-r�rUr�r�r��extendrr�)	r=rr�signalr��cbr�Zcb_args�msgrrr r�
sH








zFirewallClient._signal_receivercCs|jS)N)r�)r=rrr rM
szFirewallClient.configcCs|jj�dS)N)r��reload)r=rrr r�R
szFirewallClient.reloadcCs|jj�dS)N)r�ZcompleteReload)r=rrr �complete_reloadW
szFirewallClient.complete_reloadcCs|jj�dS)N)r��runtimeToPermanent)r=rrr r�\
sz!FirewallClient.runtimeToPermanentcCs|jj�dS)N)r��checkPermanentConfig)r=rrr r�a
sz#FirewallClient.checkPermanentConfigcCst|jjtjj|��S)N)r	r�r�rrr�)r=r�rrr r�f
szFirewallClient.get_propertycCst|jjtjj��S)N)r	r�r�rrr�)r=rrr r�l
szFirewallClient.get_propertiescCs|jjtjj||�dS)N)r�r�rrr�)r=r�rErrr r�r
szFirewallClient.set_propertycCs|jj�dS)N)r��enablePanicMode)r=rrr r�y
szFirewallClient.enablePanicModecCs|jj�dS)N)r��disablePanicMode)r=rrr r�~
szFirewallClient.disablePanicModecCst|jj��S)N)r	r��queryPanicMode)r=rrr r��
szFirewallClient.queryPanicModecCstt|jj|���S)N)r"r	r��getZoneSettings2)r=�zonerrr �getZoneSettings�
szFirewallClient.getZoneSettingscCst|jj��S)N)r	r$�	getIPSets)r=rrr r��
szFirewallClient.getIPSetscCsttt|jj|����S)N)rr9r	r$�getIPSetSettings)r=�ipsetrrr r��
szFirewallClient.getIPSetSettingscCs|jj||�dS)N)r$r)r=r�rrrr r�
szFirewallClient.addEntrycCs|jj|�S)N)r$r)r=r�rrr r�
szFirewallClient.getEntriescCs|jj||�S)N)r$r)r=r�rrrr r�
szFirewallClient.setEntriescCs|jj||�dS)N)r$r )r=r�rrrr r �
szFirewallClient.removeEntrycCst|jj||��S)N)r	r$r!)r=r�rrrr r!�
szFirewallClient.queryEntrycCst|jj��S)N)r	r�r�)r=rrr r��
szFirewallClient.listServicescCstt|jj|���S)N)r�r	r�ZgetServiceSettings2)r=rarrr �getServiceSettings�
sz!FirewallClient.getServiceSettingscCst|jj��S)N)r	r�r�)r=rrr r��
szFirewallClient.listIcmpTypescCsttt|jj|����S)N)r3r9r	r��getIcmpTypeSettings)r=rrrr r��
sz"FirewallClient.getIcmpTypeSettingscCst|jj��S)N)r	r�r
)r=rrr r
�
szFirewallClient.getHelperscCsttt|jj|����S)N)r&r9r	r��getHelperSettings)r=rrrr r��
sz FirewallClient.getHelperSettingscCst|jj��S)N)r	r��getAutomaticHelpers)r=rrr r��
sz"FirewallClient.getAutomaticHelperscCs|jj|�dS)N)r��setAutomaticHelpers)r=rErrr r��
sz"FirewallClient.setAutomaticHelperscCst|jj��S)N)r	r��getLogDenied)r=rrr r��
szFirewallClient.getLogDeniedcCs|jj|�dS)N)r��setLogDenied)r=rErrr r��
szFirewallClient.setLogDeniedcCst|jj��S)N)r	r��getDefaultZone)r=rrr r��
szFirewallClient.getDefaultZonecCs|jj|�dS)N)r��setDefaultZone)r=r�rrr r��
szFirewallClient.setDefaultZonecCs|jj||j��dS)N)r��setZoneSettings2rO)r=r�r5rrr �setZoneSettings�
szFirewallClient.setZoneSettingscCst|jj��S)N)r	r��getZones)r=rrr r��
szFirewallClient.getZonescCst|jj��S)N)r	r��getActiveZones)r=rrr r�szFirewallClient.getActiveZonescCst|jj|��S)N)r	r�r�)r=r�rrr r�	sz!FirewallClient.getZoneOfInterfacecCst|jj|��S)N)r	r�r�)r=r�rrr r�szFirewallClient.getZoneOfSourcecCst|jj|��S)N)r	r��isImmutable)r=r�rrr r�szFirewallClient.isImmutablecCstt|jj|���S)N)r�r	r��getPolicySettings)r=�policyrrr r�sz FirewallClient.getPolicySettingscCs|jj||j��dS)N)r��setPolicySettingsrO)r=r�r5rrr r�sz FirewallClient.setPolicySettingscCst|jj��S)N)r	r��getPolicies)r=rrr r�$szFirewallClient.getPoliciescCst|jj��S)N)r	r��getActivePolicies)r=rrr r�)sz FirewallClient.getActivePoliciescCst|jj|��S)N)r	r�r�)r=r�rrr �isPolicyImmutable.sz FirewallClient.isPolicyImmutablecCst|jj||��S)N)r	r�r�)r=r�r�rrr r�5szFirewallClient.addInterfacecCst|jj||��S)N)r	r��
changeZone)r=r�r�rrr r�:szFirewallClient.changeZonecCst|jj||��S)N)r	r��changeZoneOfInterface)r=r�r�rrr r�?s
z$FirewallClient.changeZoneOfInterfacecCst|jj|��S)N)r	r�r�)r=r�rrr r�EszFirewallClient.getInterfacescCst|jj||��S)N)r	r�r�)r=r�r�rrr r�JszFirewallClient.queryInterfacecCst|jj||��S)N)r	r�r�)r=r�r�rrr r�OszFirewallClient.removeInterfacecCst|jj||��S)N)r	r�r�)r=r�r�rrr r�VszFirewallClient.addSourcecCst|jj||��S)N)r	r��changeZoneOfSource)r=r�r�rrr r�[sz!FirewallClient.changeZoneOfSourcecCst|jj|��S)N)r	r�r�)r=r�rrr r�`szFirewallClient.getSourcescCst|jj||��S)N)r	r�r�)r=r�r�rrr r�eszFirewallClient.querySourcecCst|jj||��S)N)r	r�r�)r=r�r�rrr r�jszFirewallClient.removeSourcecCst|jj|||��S)N)r	r�r�)r=r�r�rrrr r�qszFirewallClient.addRichRulecCst|jj|��S)N)r	r�r�)r=r�rrr r�vszFirewallClient.getRichRulescCst|jj||��S)N)r	r�r�)r=r�r�rrr r�{szFirewallClient.queryRichRulecCst|jj||��S)N)r	r�r�)r=r�r�rrr r��szFirewallClient.removeRichRulecCst|jj|||��S)N)r	r�rb)r=r�rarrrr rb�szFirewallClient.addServicecCst|jj|��S)N)r	r�r])r=r�rrr r]�szFirewallClient.getServicescCst|jj||��S)N)r	r�rf)r=r�rarrr rf�szFirewallClient.queryServicecCst|jj||��S)N)r	r�re)r=r�rarrr re�szFirewallClient.removeServicecCst|jj||||��S)N)r	r�rl)r=r�rjrkrrrr rl�szFirewallClient.addPortcCst|jj|��S)N)r	r�rh)r=r�rrr rh�szFirewallClient.getPortscCst|jj|||��S)N)r	r�rn)r=r�rjrkrrr rn�szFirewallClient.queryPortcCst|jj|||��S)N)r	r�rm)r=r�rjrkrrr rm�szFirewallClient.removePortcCst|jj|||��S)N)r	r�rr)r=r�rkrrrr rr�szFirewallClient.addProtocolcCst|jj|��S)N)r	r�rp)r=r�rrr rp�szFirewallClient.getProtocolscCst|jj||��S)N)r	r�rt)r=r�rkrrr rt�szFirewallClient.queryProtocolcCst|jj||��S)N)r	r�rs)r=r�rkrrr rs�szFirewallClient.removeProtocolcCs|jj|ddi�dS)Nr2T)r�r�)r=r�rrr r��szFirewallClient.addForwardcCst|jj|��dS)Nr2)r	r�r�)r=r�rrr r��szFirewallClient.queryForwardcCs|jj|ddi�dS)Nr2F)r�r�)r=r�rrr r��szFirewallClient.removeForwardcCst|jj||��S)N)r	r�r�)r=r�rrrr r��szFirewallClient.addMasqueradecCst|jj|��S)N)r	r�r�)r=r�rrr r��szFirewallClient.queryMasqueradecCst|jj|��S)N)r	r�r�)r=r�rrr r��szFirewallClient.removeMasqueradecCs2|dkrd}|dkrd}t|jj||||||��S)Nr#)r	r�r�)r=r�rjrkr�r�rrrr r��szFirewallClient.addForwardPortcCst|jj|��S)N)r	r�r�)r=r�rrr r��szFirewallClient.getForwardPortscCs0|dkrd}|dkrd}t|jj|||||��S)Nr#)r	r�r�)r=r�rjrkr�r�rrr r��s
zFirewallClient.queryForwardPortcCs0|dkrd}|dkrd}t|jj|||||��S)Nr#)r	r�r�)r=r�rjrkr�r�rrr r�s
z FirewallClient.removeForwardPortcCst|jj||||��S)N)r	r�rx)r=r�rjrkrrrr rxszFirewallClient.addSourcePortcCst|jj|��S)N)r	r�rv)r=r�rrr rvszFirewallClient.getSourcePortscCst|jj|||��S)N)r	r�rz)r=r�rjrkrrr rzszFirewallClient.querySourcePortcCst|jj|||��S)N)r	r�ry)r=r�rjrkrrr ry$szFirewallClient.removeSourcePortcCst|jj|||��S)N)r	r�r�)r=r��icmprrrr r�,szFirewallClient.addIcmpBlockcCst|jj|��S)N)r	r�r|)r=r�rrr r|1szFirewallClient.getIcmpBlockscCst|jj||��S)N)r	r�r�)r=r�r�rrr r�6szFirewallClient.queryIcmpBlockcCst|jj||��S)N)r	r�r�)r=r�r�rrr r�;szFirewallClient.removeIcmpBlockcCst|jj|��S)N)r	r�r�)r=r�rrr r�Bsz$FirewallClient.addIcmpBlockInversioncCst|jj|��S)N)r	r�r�)r=r�rrr r�Gsz&FirewallClient.queryIcmpBlockInversioncCst|jj|��S)N)r	r�r�)r=r�rrr r�Lsz'FirewallClient.removeIcmpBlockInversioncCs|jj|||�dS)N)r�rq)r=r(rlrorrr rqSszFirewallClient.addChaincCs|jj|||�dS)N)r�rr)r=r(rlrorrr rrXszFirewallClient.removeChaincCst|jj|||��S)N)r	r�rs)r=r(rlrorrr rs]szFirewallClient.queryChaincCst|jj||��S)N)r	r�rm)r=r(rlrrr rmbszFirewallClient.getChainscCst|jj��S)N)r	r�rk)r=rrr rkgszFirewallClient.getAllChainscCs|jj|||||�dS)N)r�rw)r=r(rlror�rrrr rwnszFirewallClient.addRulecCs|jj|||||�dS)N)r�rx)r=r(rlror�rrrr rxsszFirewallClient.removeRulecCs|jj|||�dS)N)r�ry)r=r(rlrorrr ryxszFirewallClient.removeRulescCst|jj|||||��S)N)r	r�rz)r=r(rlror�rrrr rz}szFirewallClient.queryRulecCst|jj|||��S)N)r	r�ru)r=r(rlrorrr ru�szFirewallClient.getRulescCst|jj��S)N)r	r�rt)r=rrr rt�szFirewallClient.getAllRulescCst|jj||��S)N)r	r��passthrough)r=r(rrrr r��szFirewallClient.passthroughcCst|jj��S)N)r	r�r{)r=rrr r{�sz!FirewallClient.getAllPassthroughscCs|jj�dS)N)r�r})r=rrr r}�sz$FirewallClient.removeAllPassthroughscCst|jj|��S)N)r	r�r~)r=r(rrr r~�szFirewallClient.getPassthroughscCs|jj||�dS)N)r�r)r=r(rrrr r�szFirewallClient.addPassthroughcCs|jj||�dS)N)r�r�)r=r(rrrr r��sz FirewallClient.removePassthroughcCst|jj||��S)N)r	r�r�)r=r(rrrr r��szFirewallClient.queryPassthroughcCs|jj�dS)N)rV�enableLockdown)r=rrr r��szFirewallClient.enableLockdowncCs|jj�dS)N)rV�disableLockdown)r=rrr r��szFirewallClient.disableLockdowncCst|jj��S)N)r	rV�
queryLockdown)r=rrr r��szFirewallClient.queryLockdowncCs|jj|�dS)N)rVrY)r=r<rrr rY�sz*FirewallClient.addLockdownWhitelistCommandcCst|jj��S)N)r	rVr\)r=rrr r\�sz+FirewallClient.getLockdownWhitelistCommandscCst|jj|��S)N)r	rVr[)r=r<rrr r[�sz,FirewallClient.queryLockdownWhitelistCommandcCs|jj|�dS)N)rVrZ)r=r<rrr rZ�sz-FirewallClient.removeLockdownWhitelistCommandcCs|jj|�dS)N)rVr])r=rBrrr r]�sz*FirewallClient.addLockdownWhitelistContextcCst|jj��S)N)r	rVr`)r=rrr r`�sz+FirewallClient.getLockdownWhitelistContextscCst|jj|��S)N)r	rVr_)r=rBrrr r_�sz,FirewallClient.queryLockdownWhitelistContextcCs|jj|�dS)N)rVr^)r=rBrrr r^�sz-FirewallClient.removeLockdownWhitelistContextcCs|jj|�dS)N)rVrg)r=rOrrr rg�sz&FirewallClient.addLockdownWhitelistUidcCst|jj��S)N)r	rVre)r=rrr re�sz'FirewallClient.getLockdownWhitelistUidscCst|jj|��S)N)r	rVri)r=rOrrr ri�sz(FirewallClient.queryLockdownWhitelistUidcCs|jj|�dS)N)rVrh)r=rOrrr rhsz)FirewallClient.removeLockdownWhitelistUidcCs|jj|�dS)N)rVra)r=rHrrr ra
sz'FirewallClient.addLockdownWhitelistUsercCst|jj��S)N)r	rVrd)r=rrr rdsz(FirewallClient.getLockdownWhitelistUserscCst|jj|��S)N)r	rVrc)r=rHrrr rcsz)FirewallClient.queryLockdownWhitelistUsercCs|jj|�dS)N)rVrb)r=rHrrr rbsz*FirewallClient.removeLockdownWhitelistUsercCs|jj�dS)z( Authorize once for all polkit actions. N)r��authorizeAll)r=rrr r�szFirewallClient.authorizeAll)NrT)r)r)r)r)r)r)r)r)�r�r�r�r!r@r�r�r�r�r�r�r�r�r�r�r�rr�r�rr�r�r�r�r�r�r�r�r�r�r�r�r�rrrr r!r�r�r�r�r
r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rbr]rfrerlrhrnrmrrrprtrsr�r�r�r�r�r�r�r�r�r�rxrvrzryr�r|r�r�r�r�r�rqrrrsrmrkrwrxryrzrurtr�r{r}r~rr�r�r�r�r�rYr\r[rZr]r`r_r^rgrerirhrardrcrbr�rrrr r�+s*&0	
r�)4Z
gi.repositoryrr�sysr�Zdbus.mainloop.glibrZ	slip.dbusr�rZfirewallrZfirewall.core.baserrrZfirewall.dbus_utilsr	Zfirewall.functionsr
Zfirewall.core.richrZfirewall.core.ipsetrr
rrZfirewall.errorsrrrrr!�objectr"r�r�r�r�rr"r&r,r/r3r6r9rSrjr�r�r�rrrr �<module>sd
';R8ghyKCzVtbm__pycache__/fw_types.cpython-36.pyc000064400000005613150351351710013250 0ustar003

��g��@sdgZGdd�de�ZdS)�LastUpdatedOrderedDictc@sxeZdZddd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zddd�ZdS)rNcCsi|_g|_|r|j|�dS)N)�_dict�_list�update)�self�x�r�/usr/lib/python3.6/fw_types.py�__init__szLastUpdatedOrderedDict.__init__cCs|jdd�=|jj�dS)N)rr�clear)rrrrr
szLastUpdatedOrderedDict.clearcCs"x|j�D]\}}|||<q
WdS)N)�items)rr�key�valuerrrr#szLastUpdatedOrderedDict.updatecs�fdd��jD�S)Ncsg|]}|�|f�qSrr)�.0r)rrr�
<listcomp>(sz0LastUpdatedOrderedDict.items.<locals>.<listcomp>)r)rr)rrr'szLastUpdatedOrderedDict.itemscCs"||jkr|jj|�|j|=dS)N)rr�remove)rrrrr�__delitem__*s
z"LastUpdatedOrderedDict.__delitem__cs&d�jjdj�fdd��jD��fS)Nz%s([%s])z, csg|]}d|�|f�qS)z(%r, %r)r)rr)rrrr1sz3LastUpdatedOrderedDict.__repr__.<locals>.<listcomp>)�	__class__�__name__�joinr)rr)rr�__repr__/szLastUpdatedOrderedDict.__repr__cCs$||jkr|jj|�||j|<dS)N)rr�append)rrr
rrr�__setitem__3s
z"LastUpdatedOrderedDict.__setitem__cCs$t|�tkr|j|S|j|SdS)N)�type�intrr)rrrrr�__getitem__8s
z"LastUpdatedOrderedDict.__getitem__cCs
t|j�S)N)�lenr)rrrr�__len__>szLastUpdatedOrderedDict.__len__cCst|�S)N)r)rrrr�copyAszLastUpdatedOrderedDict.copycCs|jdd�S)N)r)rrrr�keysDszLastUpdatedOrderedDict.keyscs�fdd��jD�S)Ncsg|]}�|�qSrr)rr)rrrrHsz1LastUpdatedOrderedDict.values.<locals>.<listcomp>)r)rr)rr�valuesGszLastUpdatedOrderedDict.valuescCs ||kr||S|||<|SdS)Nr)rrr
rrr�
setdefaultJsz!LastUpdatedOrderedDict.setdefault)N)N)r�
__module__�__qualname__r	r
rrrrrrrrrrr rrrrrs
N)�__all__�objectrrrrr�<module>s__pycache__/client.cpython-36.opt-1.pyc000064400000426232150351351710013631 0ustar003

��g��@s�ddlmZmZddlZeejd<ddlZddlZddl	m	Z	ddl
mZddlm
Z
mZmZddlmZddlmZdd	lmZdd
lmZmZmZddl
mZddlmZddlZddlZdad
ae	dd��Z Gdd�de!�Z"Gdd�de!�Z#Gdd�de!�Z$Gdd�de!�Z%Gdd�de!�Z&Gdd�de!�Z'Gdd�de!�Z(Gdd�de!�Z)Gd d!�d!e!�Z*Gd"d#�d#e!�Z+Gd$d%�d%e!�Z,Gd&d'�d'e!�Z-Gd(d)�d)e!�Z.Gd*d+�d+e!�Z/Gd,d-�d-e!�Z0Gd.d/�d/e!�Z1Gd0d1�d1e!�Z2Gd2d3�d3e!�Z3dS)4�)�GLib�GObjectNZgobject)�	decorator)�config)�DEFAULT_ZONE_TARGET�DEFAULT_POLICY_TARGET�DEFAULT_POLICY_PRIORITY)�dbus_to_python)�b2u)�	Rich_Rule)�normalize_ipset_entry�check_entry_overlaps_existing�check_for_overlapping_entries)�errors)�
FirewallErrorFcOsd}�x|�sy
|||�Stjjk
r�}zb|j�}|j�}tsD�d|krVtd�n4d|krht|�n"d}|rzt|�nttt|���WYdd}~Xnftk
r�}zts��nttt|���WYdd}~Xn.t	k
�r�ts�nttt
j���YnXtsPqWdS)z#Decorator to handle exceptions
    FZNotAuthorizedExceptionzorg.freedesktop.DBus.ErrorTN)
�dbus�
exceptions�
DBusException�get_dbus_messageZ
get_dbus_name�exception_handlerr
�strr�	Exception�	traceback�
format_exc�not_authorized_loop)�func�args�kwargsZ
authorized�eZdbus_messageZ	dbus_name�r�/usr/lib/python3.6/client.py�handle_exceptions0s6




  r!c@s�eZdZed�dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��Zed*d+��Zed,d-��Zed.d/��Zed0d1��Zed2d3��Zed4d5��Zed6d7��Zed8d9��Zed:d;��Z ed<d=��Z!ed>d?��Z"ed@dA��Z#edBdC��Z$edDdE��Z%edFdG��Z&edHdI��Z'edJdK��Z(edLdM��Z)edNdO��Z*edPdQ��Z+edRdS��Z,edTdU��Z-e.j/j0j1edVdW���Z2e.j/j0j1edXdY���Z3e.j/j0j1edZd[���Z4ed\d]��Z5ed^d_��Z6e.j/j0j1ed`da���Z7e.j/j0j1edbdc���Z8e.j/j0j1eddde���Z9edfdg��Z:edhdi��Z;e.j/j0j1edjdk���Z<e.j/j0j1edldm���Z=e.j/j0j1edndo���Z>edpdq��Z?edrds��Z@edtdu��ZAedvdw��ZBedxdy��ZCedzd{��ZDed|d}��ZEed~d��ZFed�d���ZGed�d���ZHed�d���ZIed�d���ZJed�d���ZKed�d���ZLed�d���ZMed�d���ZNed�d���ZOed�d���ZPed�d���ZQed�d���ZRdS)��FirewallClientZoneSettingsNcCs�ddddtgggdggggggddg|_ddddddd	d
ddd
ddddddg|_dddddddddddddddddg|_|r�t|t�r�x"t|�D]\}}|||j|<q�Wt|t�r�|j|�dS)N�F�version�short�description�UNUSED�target�services�ports�icmp_blocks�
masquerade�
forward_ports�
interfaces�sourcesZ	rules_str�	protocols�source_portsZicmp_block_inversion�forward�s�bz(ss)z(ssss))	r�settings�
settings_name�settings_dbus_type�
isinstance�list�	enumerate�dict�setSettingsDict)�selfr5�i�vrrr �__init__Xs(

z#FirewallClientZoneSettings.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r5)r=rrr �__repr__osz#FirewallClientZoneSettings.__repr__cCs6i}x,t|j|j�D]\}}|dkr&q|||<qW|S)Nr')�zipr6r5)r=r5�key�valuerrr �getSettingsDictssz*FirewallClientZoneSettings.getSettingsDictcCs(x"|D]}|||j|jj|�<qWdS)N)r5r6�index)r=r5rDrrr r<{s
z*FirewallClientZoneSettings.setSettingsDictcCs|i}xrt|j|j|j�D]\\}}}|dkr,qt|�tkrLtj||d�||<qt|�tkrltj	||d�||<q|||<qW|S)Nr')�	signature)
rCr6r5r7�typer9r�Arrayr;�
Dictionary)r=r5rDrE�sigrrr �getSettingsDbusDictsz.FirewallClientZoneSettings.getSettingsDbusDictcCs$|j�}|d=|d=|d=|d=|S)Nr$r%r&r()rF)r=r5rrr �getRuntimeSettingsDict�sz1FirewallClientZoneSettings.getRuntimeSettingsDictcCs$|j�}|d=|d=|d=|d=|S)Nr$r%r&r()rM)r=r5rrr �getRuntimeSettingsDbusDict�sz5FirewallClientZoneSettings.getRuntimeSettingsDbusDictcCs
|jdS)Nr)r5)r=rrr �
getVersion�sz%FirewallClientZoneSettings.getVersioncCs||jd<dS)Nr)r5)r=r$rrr �
setVersion�sz%FirewallClientZoneSettings.setVersioncCs
|jdS)N�)r5)r=rrr �getShort�sz#FirewallClientZoneSettings.getShortcCs||jd<dS)NrR)r5)r=r%rrr �setShort�sz#FirewallClientZoneSettings.setShortcCs
|jdS)N�)r5)r=rrr �getDescription�sz)FirewallClientZoneSettings.getDescriptioncCs||jd<dS)NrU)r5)r=r&rrr �setDescription�sz)FirewallClientZoneSettings.setDescriptioncCs|jdtkr|jdSdS)N��default)r5r)r=rrr �	getTarget�sz$FirewallClientZoneSettings.getTargetcCs|dkr|nt|jd<dS)NrYrX)rr5)r=r(rrr �	setTarget�sz$FirewallClientZoneSettings.setTargetcCs
|jdS)N�)r5)r=rrr �getServices�sz&FirewallClientZoneSettings.getServicescCs||jd<dS)Nr\)r5)r=r)rrr �setServices�sz&FirewallClientZoneSettings.setServicescCs0||jdkr |jdj|�nttj|��dS)Nr\)r5�appendrr�ALREADY_ENABLED)r=�servicerrr �
addService�sz%FirewallClientZoneSettings.addServicecCs0||jdkr |jdj|�nttj|��dS)Nr\)r5�removerr�NOT_ENABLED)r=rarrr �
removeService�sz(FirewallClientZoneSettings.removeServicecCs||jdkS)Nr\)r5)r=rarrr �queryService�sz'FirewallClientZoneSettings.queryServicecCs
|jdS)N�)r5)r=rrr �getPorts�sz#FirewallClientZoneSettings.getPortscCs||jd<dS)Nrg)r5)r=r*rrr �setPorts�sz#FirewallClientZoneSettings.setPortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nrgz'%s:%s')r5r_rrr`)r=�port�protocolrrr �addPort�sz"FirewallClientZoneSettings.addPortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nrgz'%s:%s')r5rcrrrd)r=rjrkrrr �
removePort�sz%FirewallClientZoneSettings.removePortcCs||f|jdkS)Nrg)r5)r=rjrkrrr �	queryPort�sz$FirewallClientZoneSettings.queryPortcCs
|jdS)N�
)r5)r=rrr �getProtocols�sz'FirewallClientZoneSettings.getProtocolscCs||jd<dS)Nro)r5)r=r0rrr �setProtocols�sz'FirewallClientZoneSettings.setProtocolscCs0||jdkr |jdj|�nttj|��dS)Nro)r5r_rrr`)r=rkrrr �addProtocol�sz&FirewallClientZoneSettings.addProtocolcCs0||jdkr |jdj|�nttj|��dS)Nro)r5rcrrrd)r=rkrrr �removeProtocol�sz)FirewallClientZoneSettings.removeProtocolcCs||jdkS)Nro)r5)r=rkrrr �
queryProtocol�sz(FirewallClientZoneSettings.queryProtocolcCs
|jdS)N�)r5)r=rrr �getSourcePortssz)FirewallClientZoneSettings.getSourcePortscCs||jd<dS)Nru)r5)r=r*rrr �setSourcePortssz)FirewallClientZoneSettings.setSourcePortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nruz'%s:%s')r5r_rrr`)r=rjrkrrr �
addSourcePortsz(FirewallClientZoneSettings.addSourcePortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nruz'%s:%s')r5rcrrrd)r=rjrkrrr �removeSourcePortsz+FirewallClientZoneSettings.removeSourcePortcCs||f|jdkS)Nru)r5)r=rjrkrrr �querySourcePortsz*FirewallClientZoneSettings.querySourcePortcCs
|jdS)N�)r5)r=rrr �
getIcmpBlockssz(FirewallClientZoneSettings.getIcmpBlockscCs||jd<dS)Nr{)r5)r=�
icmpblocksrrr �
setIcmpBlockssz(FirewallClientZoneSettings.setIcmpBlockscCs0||jdkr |jdj|�nttj|��dS)Nr{)r5r_rrr`)r=�icmptyperrr �addIcmpBlock sz'FirewallClientZoneSettings.addIcmpBlockcCs0||jdkr |jdj|�nttj|��dS)Nr{)r5rcrrrd)r=rrrr �removeIcmpBlock&sz*FirewallClientZoneSettings.removeIcmpBlockcCs||jdkS)Nr{)r5)r=rrrr �queryIcmpBlock,sz)FirewallClientZoneSettings.queryIcmpBlockcCs
|jdS)N�)r5)r=rrr �getIcmpBlockInversion0sz0FirewallClientZoneSettings.getIcmpBlockInversioncCs||jd<dS)Nr�)r5)r=�flagrrr �setIcmpBlockInversion3sz0FirewallClientZoneSettings.setIcmpBlockInversioncCs&|jdsd|jd<nttjd�dS)Nr�Tzicmp-block-inversion)r5rrr`)r=rrr �addIcmpBlockInversion6s
z0FirewallClientZoneSettings.addIcmpBlockInversioncCs&|jdrd|jd<nttjd�dS)Nr�Fzicmp-block-inversion)r5rrrd)r=rrr �removeIcmpBlockInversion=s
z3FirewallClientZoneSettings.removeIcmpBlockInversioncCs
|jdS)Nr�)r5)r=rrr �queryIcmpBlockInversionDsz2FirewallClientZoneSettings.queryIcmpBlockInversioncCs
|jdS)N�)r5)r=rrr �
getForwardIsz%FirewallClientZoneSettings.getForwardcCs||jd<dS)Nr�)r5)r=r2rrr �
setForwardLsz%FirewallClientZoneSettings.setForwardcCs&|jdsd|jd<nttjd�dS)Nr�Tr2)r5rrr`)r=rrr �
addForwardOs
z%FirewallClientZoneSettings.addForwardcCs&|jdrd|jd<nttjd�dS)Nr�Fr2)r5rrrd)r=rrr �
removeForwardVs
z(FirewallClientZoneSettings.removeForwardcCs
|jdS)Nr�)r5)r=rrr �queryForward]sz'FirewallClientZoneSettings.queryForwardcCs
|jdS)N�)r5)r=rrr �
getMasqueradebsz(FirewallClientZoneSettings.getMasqueradecCs||jd<dS)Nr�)r5)r=r,rrr �
setMasqueradeesz(FirewallClientZoneSettings.setMasqueradecCs&|jdsd|jd<nttjd�dS)Nr�Tr,)r5rrr`)r=rrr �
addMasqueradehs
z(FirewallClientZoneSettings.addMasqueradecCs&|jdrd|jd<nttjd�dS)Nr�Fr,)r5rrrd)r=rrr �removeMasqueradeos
z+FirewallClientZoneSettings.removeMasqueradecCs
|jdS)Nr�)r5)r=rrr �queryMasqueradevsz*FirewallClientZoneSettings.queryMasqueradecCs
|jdS)N�	)r5)r=rrr �getForwardPorts{sz*FirewallClientZoneSettings.getForwardPortscCs||jd<dS)Nr�)r5)r=r*rrr �setForwardPorts~sz*FirewallClientZoneSettings.setForwardPortscCsd|dkrd}|dkrd}||||f|jdkrH|jdj||||f�nttjd||||f��dS)Nr#r�z
'%s:%s:%s:%s')r5r_rrr`)r=rjrk�to_port�to_addrrrr �addForwardPort�sz)FirewallClientZoneSettings.addForwardPortcCsd|dkrd}|dkrd}||||f|jdkrH|jdj||||f�nttjd||||f��dS)Nr#r�z
'%s:%s:%s:%s')r5rcrrrd)r=rjrkr�r�rrr �removeForwardPort�sz,FirewallClientZoneSettings.removeForwardPortcCs.|dkrd}|dkrd}||||f|jdkS)Nr#r�)r5)r=rjrkr�r�rrr �queryForwardPort�s
z+FirewallClientZoneSettings.queryForwardPortcCs
|jdS)N�
)r5)r=rrr �
getInterfaces�sz(FirewallClientZoneSettings.getInterfacescCs||jd<dS)Nr�)r5)r=r.rrr �
setInterfaces�sz(FirewallClientZoneSettings.setInterfacescCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�	interfacerrr �addInterface�sz'FirewallClientZoneSettings.addInterfacecCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=r�rrr �removeInterface�sz*FirewallClientZoneSettings.removeInterfacecCs||jdkS)Nr�)r5)r=r�rrr �queryInterface�sz)FirewallClientZoneSettings.queryInterfacecCs
|jdS)N�)r5)r=rrr �
getSources�sz%FirewallClientZoneSettings.getSourcescCs||jd<dS)Nr�)r5)r=r/rrr �
setSources�sz%FirewallClientZoneSettings.setSourcescCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�sourcerrr �	addSource�sz$FirewallClientZoneSettings.addSourcecCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=r�rrr �removeSource�sz'FirewallClientZoneSettings.removeSourcecCs||jdkS)Nr�)r5)r=r�rrr �querySource�sz&FirewallClientZoneSettings.querySourcecCs
|jdS)N�)r5)r=rrr �getRichRules�sz'FirewallClientZoneSettings.getRichRulescCsdd�|D�}||jd<dS)NcSsg|]}tt|d���qS))�rule_str)rr)�.0�rrrr �
<listcomp>�sz;FirewallClientZoneSettings.setRichRules.<locals>.<listcomp>r�)r5)r=�rulesrrr �setRichRules�sz'FirewallClientZoneSettings.setRichRulescCs>tt|d��}||jdkr.|jdj|�nttj|��dS)N)r�r�)rrr5r_rrr`)r=�rulerrr �addRichRule�sz&FirewallClientZoneSettings.addRichRulecCs>tt|d��}||jdkr.|jdj|�nttj|��dS)N)r�r�)rrr5rcrrrd)r=r�rrr �removeRichRule�sz)FirewallClientZoneSettings.removeRichRulecCstt|d��}||jdkS)N)r�r�)rrr5)r=r�rrr �
queryRichRule�sz(FirewallClientZoneSettings.queryRichRule)N)S�__name__�
__module__�__qualname__r!r@rBrFr<rMrNrOrPrQrSrTrVrWrZr[r]r^rbrerfrhrirlrmrnrprqrrrsrtrvrwrxryrzr|r~r�r�r�r�r��slipr�polkit�enable_proxyr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrr r"Ws�	
r"c@s�eZdZdd�Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zejjjed)d*���Zejjjed+d,���Zejjjed-d.���Zejjjed/d0���Zejjjed1d2���Z ejjjed3d4���Z!ejjjed5d6���Z"ejjjed7d8���Z#ejjjed9d:���Z$ejjjed;d<���Z%ejjjed=d>���Z&ejjjed?d@���Z'ejjjedAdB���Z(ejjjedCdD���Z)ejjjedEdF���Z*ejjjedGdH���Z+ejjjedIdJ���Z,ejjjedKdL���Z-ejjjedMdN���Z.ejjjedOdP���Z/ejjjedQdR���Z0ejjjedSdT���Z1ejjjedUdV���Z2ejjjedWdX���Z3ejjjedYdZ���Z4ejjjed[d\���Z5ejjjed]d^���Z6ejjjed_d`���Z7ejjjedadb���Z8ejjjedcdd���Z9ejjjededf���Z:ejjjedgdh���Z;ejjjedidj���Z<ejjjedkdl���Z=ejjjedmdn���Z>ejjjedodp���Z?ejjjedqdr���Z@ejjjedsdt���ZAejjjedudv���ZBejjjedwdx���ZCejjjedydz���ZDejjjed{d|���ZEejjjed}d~���ZFejjjedd����ZGejjjed�d����ZHejjjed�d����ZIejjjed�d����ZJejjjed�d����ZKejjjed�d����ZLejjjed�d����ZMejjjed�d����ZNejjjed�d����ZOejjjed�d����ZPejjjed�d����ZQejjjed�d����ZRejjjed�d����ZSejjjed�d����ZTd�S)��FirewallClientConfigZonecCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)�dbus_interfacezorg.freedesktop.DBus.Properties)�bus�path�
get_objectrr�DBUS_INTERFACE�dbus_obj�	Interface�DBUS_INTERFACE_CONFIG_ZONE�fw_zone�
fw_properties)r=r�r�rrr r@�sz!FirewallClientConfigZone.__init__cCst|jjtjj|��S)N)r	r��Getrrr�)r=�proprrr �get_property�sz%FirewallClientConfigZone.get_propertycCst|jjtjj��S)N)r	r��GetAllrrr�)r=rrr �get_properties�sz'FirewallClientConfigZone.get_propertiescCs|jjtjj||�dS)N)r��Setrrr�)r=r�rErrr �set_propertysz%FirewallClientConfigZone.set_propertycCstt|jj���S)N)r"r	r��getSettings2)r=rrr �getSettingssz$FirewallClientConfigZone.getSettingscCs|jj|j��dS)N)r��update2rM)r=r5rrr �updateszFirewallClientConfigZone.updatecCs|jj�dS)N)r��loadDefaults)r=rrr r�sz%FirewallClientConfigZone.loadDefaultscCs|jj�dS)N)r�rc)r=rrr rcszFirewallClientConfigZone.removecCs|jj|�dS)N)r��rename)r=�namerrr r�szFirewallClientConfigZone.renamecCs
|jj�S)N)r�rP)r=rrr rP"sz#FirewallClientConfigZone.getVersioncCs|jj|�dS)N)r�rQ)r=r$rrr rQ'sz#FirewallClientConfigZone.setVersioncCs
|jj�S)N)r�rS)r=rrr rS.sz!FirewallClientConfigZone.getShortcCs|jj|�dS)N)r�rT)r=r%rrr rT3sz!FirewallClientConfigZone.setShortcCs
|jj�S)N)r�rV)r=rrr rV:sz'FirewallClientConfigZone.getDescriptioncCs|jj|�dS)N)r�rW)r=r&rrr rW?sz'FirewallClientConfigZone.setDescriptioncCs
|jj�S)N)r�rZ)r=rrr rZFsz"FirewallClientConfigZone.getTargetcCs|jj|�dS)N)r�r[)r=r(rrr r[Ksz"FirewallClientConfigZone.setTargetcCs
|jj�S)N)r�r])r=rrr r]Rsz$FirewallClientConfigZone.getServicescCs|jj|�dS)N)r�r^)r=r)rrr r^Wsz$FirewallClientConfigZone.setServicescCs|jj|�dS)N)r�rb)r=rarrr rb\sz#FirewallClientConfigZone.addServicecCs|jj|�dS)N)r�re)r=rarrr reasz&FirewallClientConfigZone.removeServicecCs|jj|�S)N)r�rf)r=rarrr rffsz%FirewallClientConfigZone.queryServicecCs
|jj�S)N)r�rh)r=rrr rhmsz!FirewallClientConfigZone.getPortscCs|jj|�dS)N)r�ri)r=r*rrr rirsz!FirewallClientConfigZone.setPortscCs|jj||�dS)N)r�rl)r=rjrkrrr rlwsz FirewallClientConfigZone.addPortcCs|jj||�dS)N)r�rm)r=rjrkrrr rm|sz#FirewallClientConfigZone.removePortcCs|jj||�S)N)r�rn)r=rjrkrrr rn�sz"FirewallClientConfigZone.queryPortcCs
|jj�S)N)r�rp)r=rrr rp�sz%FirewallClientConfigZone.getProtocolscCs|jj|�dS)N)r�rq)r=r0rrr rq�sz%FirewallClientConfigZone.setProtocolscCs|jj|�dS)N)r�rr)r=rkrrr rr�sz$FirewallClientConfigZone.addProtocolcCs|jj|�dS)N)r�rs)r=rkrrr rs�sz'FirewallClientConfigZone.removeProtocolcCs|jj|�S)N)r�rt)r=rkrrr rt�sz&FirewallClientConfigZone.queryProtocolcCs
|jj�S)N)r�rv)r=rrr rv�sz'FirewallClientConfigZone.getSourcePortscCs|jj|�dS)N)r�rw)r=r*rrr rw�sz'FirewallClientConfigZone.setSourcePortscCs|jj||�dS)N)r�rx)r=rjrkrrr rx�sz&FirewallClientConfigZone.addSourcePortcCs|jj||�dS)N)r�ry)r=rjrkrrr ry�sz)FirewallClientConfigZone.removeSourcePortcCs|jj||�S)N)r�rz)r=rjrkrrr rz�sz(FirewallClientConfigZone.querySourcePortcCs
|jj�S)N)r�r|)r=rrr r|�sz&FirewallClientConfigZone.getIcmpBlockscCs|jj|�dS)N)r�r~)r=Z	icmptypesrrr r~�sz&FirewallClientConfigZone.setIcmpBlockscCs|jj|�dS)N)r�r�)r=rrrr r��sz%FirewallClientConfigZone.addIcmpBlockcCs|jj|�dS)N)r�r�)r=rrrr r��sz(FirewallClientConfigZone.removeIcmpBlockcCs|jj|�S)N)r�r�)r=rrrr r��sz'FirewallClientConfigZone.queryIcmpBlockcCs
|jj�S)N)r�r�)r=rrr r��sz.FirewallClientConfigZone.getIcmpBlockInversioncCs|jj|�dS)N)r�r�)r=Z	inversionrrr r��sz.FirewallClientConfigZone.setIcmpBlockInversioncCs|jj�dS)N)r�r�)r=rrr r��sz.FirewallClientConfigZone.addIcmpBlockInversioncCs|jj�dS)N)r�r�)r=rrr r��sz1FirewallClientConfigZone.removeIcmpBlockInversioncCs
|jj�S)N)r�r�)r=rrr r��sz0FirewallClientConfigZone.queryIcmpBlockInversioncCs|jj�dS)Nr2)r�r�)r=rrr r��sz#FirewallClientConfigZone.getForwardcCs|jjd|i�dS)Nr2)r�r�)r=r2rrr r��sz#FirewallClientConfigZone.setForwardcCs|jjddi�dS)Nr2T)r�r�)r=rrr r��sz#FirewallClientConfigZone.addForwardcCs|jjddi�dS)Nr2F)r�r�)r=rrr r�sz&FirewallClientConfigZone.removeForwardcCs|jj�dS)Nr2)r�r�)r=rrr r�sz%FirewallClientConfigZone.queryForwardcCs
|jj�S)N)r�r�)r=rrr r�sz&FirewallClientConfigZone.getMasqueradecCs|jj|�dS)N)r�r�)r=r,rrr r�sz&FirewallClientConfigZone.setMasqueradecCs|jj�dS)N)r�r�)r=rrr r�sz&FirewallClientConfigZone.addMasqueradecCs|jj�dS)N)r�r�)r=rrr r�sz)FirewallClientConfigZone.removeMasqueradecCs
|jj�S)N)r�r�)r=rrr r�#sz(FirewallClientConfigZone.queryMasqueradecCs
|jj�S)N)r�r�)r=rrr r�*sz(FirewallClientConfigZone.getForwardPortscCs|jj|�dS)N)r�r�)r=r*rrr r�/sz(FirewallClientConfigZone.setForwardPortscCs.|dkrd}|dkrd}|jj||||�dS)Nr#)r�r�)r=rjrk�toport�toaddrrrr r�4s
z'FirewallClientConfigZone.addForwardPortcCs.|dkrd}|dkrd}|jj||||�dS)Nr#)r�r�)r=rjrkr�r�rrr r�=s
z*FirewallClientConfigZone.removeForwardPortcCs*|dkrd}|dkrd}|jj||||�S)Nr#)r�r�)r=rjrkr�r�rrr r�Fs
z)FirewallClientConfigZone.queryForwardPortcCs
|jj�S)N)r�r�)r=rrr r�Qsz&FirewallClientConfigZone.getInterfacescCs|jj|�dS)N)r�r�)r=r.rrr r�Vsz&FirewallClientConfigZone.setInterfacescCs|jj|�dS)N)r�r�)r=r�rrr r�[sz%FirewallClientConfigZone.addInterfacecCs|jj|�dS)N)r�r�)r=r�rrr r�`sz(FirewallClientConfigZone.removeInterfacecCs|jj|�S)N)r�r�)r=r�rrr r�esz'FirewallClientConfigZone.queryInterfacecCs
|jj�S)N)r�r�)r=rrr r�lsz#FirewallClientConfigZone.getSourcescCs|jj|�dS)N)r�r�)r=r/rrr r�qsz#FirewallClientConfigZone.setSourcescCs|jj|�dS)N)r�r�)r=r�rrr r�vsz"FirewallClientConfigZone.addSourcecCs|jj|�dS)N)r�r�)r=r�rrr r�{sz%FirewallClientConfigZone.removeSourcecCs|jj|�S)N)r�r�)r=r�rrr r��sz$FirewallClientConfigZone.querySourcecCs
|jj�S)N)r�r�)r=rrr r��sz%FirewallClientConfigZone.getRichRulescCs|jj|�dS)N)r�r�)r=r�rrr r��sz%FirewallClientConfigZone.setRichRulescCs|jj|�dS)N)r�r�)r=r�rrr r��sz$FirewallClientConfigZone.addRichRulecCs|jj|�dS)N)r�r�)r=r�rrr r��sz'FirewallClientConfigZone.removeRichRulecCs|jj|�S)N)r�r�)r=r�rrr r��sz&FirewallClientConfigZone.queryRichRuleN)Ur�r�r�r@r�rr�r�r!r�r�r�r�r�r�rcr�rPrQrSrTrVrWrZr[r]r^rbrerfrhrirlrmrnrprqrrrsrtrvrwrxryrzr|r~r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrr r��s2
r�c@s@eZdZed�dd��Zedd��Zedd��Zedd	��Zed
d��Zdd
�Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��Zed*d+��Zed,d-��Zed.d/��Zed0d1��Zed2d3��Zed4d5��Zed6d7��Zed8d9��Zed:d;��Z ed<d=��Z!ed>d?��Z"ed@dA��Z#edBdC��Z$edDdE��Z%edFdG��Z&edHdI��Z'edJdK��Z(edLdM��Z)edNdO��Z*edPdQ��Z+edRdS��Z,e-j.j/j0edTdU���Z1e-j.j/j0edVdW���Z2e-j.j/j0edXdY���Z3edZd[��Z4ed\d]��Z5ed^d_��Z6ed`da��Z7edbdc��Z8eddde��Z9edfdg��Z:edhdi��Z;edjdk��Z<edldm��Z=edndo��Z>edpdq��Z?edrds��Z@edtdu��ZAedvdw��ZBedxdy��ZCedzd{��ZDed|d}��ZEed~d��ZFed�d���ZGed�d���ZHed�d���ZIdS)��FirewallClientPolicySettingsNcCs\dggggdgtgggdgtdd�|_dddddddddddddddg|_|rX|j|�dS)	Nr#F)r&�egress_zonesr-r+�
ingress_zonesr,r*�priorityr0�
rich_rulesr)r%r1r(r$r3z(ssss)r4z(ss)r>)rrr5r7r<)r=r5rrr r@�s,

z%FirewallClientPolicySettings.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rB�sz%FirewallClientPolicySettings.__repr__cCs|jS)N)r5)r=rrr rF�sz,FirewallClientPolicySettings.getSettingsDictcCs x|D]}|||j|<qWdS)N)r5)r=r5rDrrr r<�s
z,FirewallClientPolicySettings.setSettingsDictcCsvi}xlt|j|j�D]Z\}}|j|}t|�tkrFtj||d�||<qt|�tkrftj||d�||<q|||<qW|S)N)rH)	rCr5r7rIr9rrJr;rK)r=r5rDrLrErrr rM�s
z0FirewallClientPolicySettings.getSettingsDbusDictcCs |j�}xdD]
}||=qW|S)Nr$r%r&r()r$r%r&r()rM)r=r5rDrrr rO�s

z7FirewallClientPolicySettings.getRuntimeSettingsDbusDictcCs
|jdS)Nr$)r5)r=rrr rP�sz'FirewallClientPolicySettings.getVersioncCs||jd<dS)Nr$)r5)r=r$rrr rQ�sz'FirewallClientPolicySettings.setVersioncCs
|jdS)Nr%)r5)r=rrr rS�sz%FirewallClientPolicySettings.getShortcCs||jd<dS)Nr%)r5)r=r%rrr rT�sz%FirewallClientPolicySettings.setShortcCs
|jdS)Nr&)r5)r=rrr rV�sz+FirewallClientPolicySettings.getDescriptioncCs||jd<dS)Nr&)r5)r=r&rrr rW�sz+FirewallClientPolicySettings.setDescriptioncCs
|jdS)Nr()r5)r=rrr rZ�sz&FirewallClientPolicySettings.getTargetcCs||jd<dS)Nr()r5)r=r(rrr r[�sz&FirewallClientPolicySettings.setTargetcCs
|jdS)Nr))r5)r=rrr r]�sz(FirewallClientPolicySettings.getServicescCs||jd<dS)Nr))r5)r=r)rrr r^�sz(FirewallClientPolicySettings.setServicescCs0||jdkr |jdj|�nttj|��dS)Nr))r5r_rrr`)r=rarrr rb�sz'FirewallClientPolicySettings.addServicecCs0||jdkr |jdj|�nttj|��dS)Nr))r5rcrrrd)r=rarrr resz*FirewallClientPolicySettings.removeServicecCs||jdkS)Nr))r5)r=rarrr rfsz)FirewallClientPolicySettings.queryServicecCs
|jdS)Nr*)r5)r=rrr rh
sz%FirewallClientPolicySettings.getPortscCs||jd<dS)Nr*)r5)r=r*rrr ri
sz%FirewallClientPolicySettings.setPortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr*z'%s:%s')r5r_rrr`)r=rjrkrrr rlsz$FirewallClientPolicySettings.addPortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr*z'%s:%s')r5rcrrrd)r=rjrkrrr rmsz'FirewallClientPolicySettings.removePortcCs||f|jdkS)Nr*)r5)r=rjrkrrr rnsz&FirewallClientPolicySettings.queryPortcCs
|jdS)Nr0)r5)r=rrr rp"sz)FirewallClientPolicySettings.getProtocolscCs||jd<dS)Nr0)r5)r=r0rrr rq%sz)FirewallClientPolicySettings.setProtocolscCs0||jdkr |jdj|�nttj|��dS)Nr0)r5r_rrr`)r=rkrrr rr(sz(FirewallClientPolicySettings.addProtocolcCs0||jdkr |jdj|�nttj|��dS)Nr0)r5rcrrrd)r=rkrrr rs.sz+FirewallClientPolicySettings.removeProtocolcCs||jdkS)Nr0)r5)r=rkrrr rt4sz*FirewallClientPolicySettings.queryProtocolcCs
|jdS)Nr1)r5)r=rrr rv8sz+FirewallClientPolicySettings.getSourcePortscCs||jd<dS)Nr1)r5)r=r*rrr rw;sz+FirewallClientPolicySettings.setSourcePortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr1z'%s:%s')r5r_rrr`)r=rjrkrrr rx>sz*FirewallClientPolicySettings.addSourcePortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr1z'%s:%s')r5rcrrrd)r=rjrkrrr ryEsz-FirewallClientPolicySettings.removeSourcePortcCs||f|jdkS)Nr1)r5)r=rjrkrrr rzLsz,FirewallClientPolicySettings.querySourcePortcCs
|jdS)Nr+)r5)r=rrr r|Psz*FirewallClientPolicySettings.getIcmpBlockscCs||jd<dS)Nr+)r5)r=r}rrr r~Ssz*FirewallClientPolicySettings.setIcmpBlockscCs0||jdkr |jdj|�nttj|��dS)Nr+)r5r_rrr`)r=rrrr r�Vsz)FirewallClientPolicySettings.addIcmpBlockcCs0||jdkr |jdj|�nttj|��dS)Nr+)r5rcrrrd)r=rrrr r�\sz,FirewallClientPolicySettings.removeIcmpBlockcCs||jdkS)Nr+)r5)r=rrrr r�bsz+FirewallClientPolicySettings.queryIcmpBlockcCs
|jdS)Nr,)r5)r=rrr r�fsz*FirewallClientPolicySettings.getMasqueradecCs||jd<dS)Nr,)r5)r=r,rrr r�isz*FirewallClientPolicySettings.setMasqueradecCs&|jdsd|jd<nttjd�dS)Nr,T)r5rrr`)r=rrr r�ls
z*FirewallClientPolicySettings.addMasqueradecCs&|jdrd|jd<nttjd�dS)Nr,F)r5rrrd)r=rrr r�ss
z-FirewallClientPolicySettings.removeMasqueradecCs
|jdS)Nr,)r5)r=rrr r�zsz,FirewallClientPolicySettings.queryMasqueradecCs
|jdS)Nr-)r5)r=rrr r�sz,FirewallClientPolicySettings.getForwardPortscCs||jd<dS)Nr-)r5)r=r*rrr r��sz,FirewallClientPolicySettings.setForwardPortscCsd|dkrd}|dkrd}||||f|jdkrH|jdj||||f�nttjd||||f��dS)Nr#r-z
'%s:%s:%s:%s')r5r_rrr`)r=rjrkr�r�rrr r��sz+FirewallClientPolicySettings.addForwardPortcCsd|dkrd}|dkrd}||||f|jdkrH|jdj||||f�nttjd||||f��dS)Nr#r-z
'%s:%s:%s:%s')r5rcrrrd)r=rjrkr�r�rrr r��sz.FirewallClientPolicySettings.removeForwardPortcCs.|dkrd}|dkrd}||||f|jdkS)Nr#r-)r5)r=rjrkr�r�rrr r��s
z-FirewallClientPolicySettings.queryForwardPortcCs
|jdS)Nr�)r5)r=rrr r��sz)FirewallClientPolicySettings.getRichRulescCsdd�|D�}||jd<dS)NcSsg|]}tt|d���qS))r�)rr)r�r�rrr r��sz=FirewallClientPolicySettings.setRichRules.<locals>.<listcomp>r�)r5)r=r�rrr r��sz)FirewallClientPolicySettings.setRichRulescCs>tt|d��}||jdkr.|jdj|�nttj|��dS)N)r�r�)rrr5r_rrr`)r=r�rrr r��sz(FirewallClientPolicySettings.addRichRulecCs>tt|d��}||jdkr.|jdj|�nttj|��dS)N)r�r�)rrr5rcrrrd)r=r�rrr r��sz+FirewallClientPolicySettings.removeRichRulecCstt|d��}||jdkS)N)r�r�)rrr5)r=r�rrr r��sz*FirewallClientPolicySettings.queryRichRulecCs
|jdS)Nr�)r5)r=rrr �getIngressZones�sz,FirewallClientPolicySettings.getIngressZonescCs||jd<dS)Nr�)r5)r=r�rrr �setIngressZones�sz,FirewallClientPolicySettings.setIngressZonescCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�ingress_zonerrr �addIngressZone�sz+FirewallClientPolicySettings.addIngressZonecCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=r�rrr �removeIngressZone�sz.FirewallClientPolicySettings.removeIngressZonecCs||jdkS)Nr�)r5)r=r�rrr �queryIngressZone�sz-FirewallClientPolicySettings.queryIngressZonecCs
|jdS)Nr�)r5)r=rrr �getEgressZones�sz+FirewallClientPolicySettings.getEgressZonescCs||jd<dS)Nr�)r5)r=r�rrr �setEgressZones�sz+FirewallClientPolicySettings.setEgressZonescCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�egress_zonerrr �
addEgressZone�sz*FirewallClientPolicySettings.addEgressZonecCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=r�rrr �removeEgressZone�sz-FirewallClientPolicySettings.removeEgressZonecCs||jdkS)Nr�)r5)r=r�rrr �queryEgressZone�sz,FirewallClientPolicySettings.queryEgressZonecCs
|jdS)Nr�)r5)r=rrr �getPriority�sz(FirewallClientPolicySettings.getPrioritycCst|�|jd<dS)Nr�)�intr5)r=r�rrr �setPriority�sz(FirewallClientPolicySettings.setPriority)N)Jr�r�r�r!r@rBrFr<rMrOrPrQrSrTrVrWrZr[r]r^rbrerfrhrirlrmrnrprqrrrsrtrvrwrxryrzr|r~r�r�r�r�r�r�rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrr r��s�r�c@s�eZdZdd�Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���ZdS)�FirewallClientConfigPolicycCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)r�zorg.freedesktop.DBus.Properties)r�r�r�rrr�r�r��DBUS_INTERFACE_CONFIG_POLICY�	fw_policyr�)r=r�r�rrr r@�sz#FirewallClientConfigPolicy.__init__cCst|jjtjj|��S)N)r	r�r�rrr�)r=r�rrr r��sz'FirewallClientConfigPolicy.get_propertycCst|jjtjj��S)N)r	r�r�rrr�)r=rrr r�sz)FirewallClientConfigPolicy.get_propertiescCs|jjtjj||�dS)N)r�r�rrr�)r=r�rErrr r�sz'FirewallClientConfigPolicy.set_propertycCstt|jj���S)N)r�r	r�r�)r=rrr r�
sz&FirewallClientConfigPolicy.getSettingscCs|jj|j��dS)N)r�r�rM)r=r5rrr r�sz!FirewallClientConfigPolicy.updatecCs|jj�dS)N)r�r�)r=rrr r�sz'FirewallClientConfigPolicy.loadDefaultscCs|jj�dS)N)r�rc)r=rrr rcsz!FirewallClientConfigPolicy.removecCs|jj|�dS)N)r�r�)r=r�rrr r�!sz!FirewallClientConfigPolicy.renameN)r�r�r�r@r�rr�r�r!r�r�r�r�r�r�rcr�rrrr r��s"
r�c@s8eZdZed^dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��Zed*d+��Zed,d-��Zed.d/��Zed0d1��Zed2d3��Zed4d5��Zed6d7��Zed8d9��Zed:d;��Z ed<d=��Z!ed>d?��Z"ed@dA��Z#edBdC��Z$edDdE��Z%ed_dFdG��Z&edHdI��Z'edJdK��Z(edLdM��Z)edNdO��Z*edPdQ��Z+edRdS��Z,edTdU��Z-edVdW��Z.edXdY��Z/edZd[��Z0ed\d]��Z1dS)`�FirewallClientServiceSettingsNc
Cs�dddggiggggg
|_dddddddd	d
dg
|_dddd
dddd
ddg
|_|r�t|�tkr�x:t|�D]\}}|||j|<qhWnt|�tkr�|j|�dS)Nr#r$r%r&r*�modules�destinationr0r1�includes�helpersr3z(ss)Zss)r5r6r7rIr9r:r;r<)r=r5r>r?rrr r@)sz&FirewallClientServiceSettings.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rB9sz&FirewallClientServiceSettings.__repr__cCs,i}x"t|j|j�D]\}}|||<qW|S)N)rCr6r5)r=r5rDrErrr rF=sz-FirewallClientServiceSettings.getSettingsDictcCs(x"|D]}|||j|jj|�<qWdS)N)r5r6rG)r=r5rDrrr r<Cs
z-FirewallClientServiceSettings.setSettingsDictcCsri}xht|j|j|j�D]R\}}}t|�tkrBtj||d�||<qt|�tkrbtj	||d�||<q|||<qW|S)N)rH)
rCr6r5r7rIr9rrJr;rK)r=r5rDrErLrrr rMGsz1FirewallClientServiceSettings.getSettingsDbusDictcCs
|jdS)Nr)r5)r=rrr rPSsz(FirewallClientServiceSettings.getVersioncCs||jd<dS)Nr)r5)r=r$rrr rQVsz(FirewallClientServiceSettings.setVersioncCs
|jdS)NrR)r5)r=rrr rSZsz&FirewallClientServiceSettings.getShortcCs||jd<dS)NrR)r5)r=r%rrr rT]sz&FirewallClientServiceSettings.setShortcCs
|jdS)NrU)r5)r=rrr rVasz,FirewallClientServiceSettings.getDescriptioncCs||jd<dS)NrU)r5)r=r&rrr rWdsz,FirewallClientServiceSettings.setDescriptioncCs
|jdS)N�)r5)r=rrr rhhsz&FirewallClientServiceSettings.getPortscCs||jd<dS)Nr�)r5)r=r*rrr riksz&FirewallClientServiceSettings.setPortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr�z'%s:%s')r5r_rrr`)r=rjrkrrr rlnsz%FirewallClientServiceSettings.addPortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr�z'%s:%s')r5rcrrrd)r=rjrkrrr rmusz(FirewallClientServiceSettings.removePortcCs||f|jdkS)Nr�)r5)r=rjrkrrr rn|sz'FirewallClientServiceSettings.queryPortcCs
|jdS)Nrg)r5)r=rrr rp�sz*FirewallClientServiceSettings.getProtocolscCs||jd<dS)Nrg)r5)r=r0rrr rq�sz*FirewallClientServiceSettings.setProtocolscCs0||jdkr |jdj|�nttj|��dS)Nrg)r5r_rrr`)r=rkrrr rr�sz)FirewallClientServiceSettings.addProtocolcCs0||jdkr |jdj|�nttj|��dS)Nrg)r5rcrrrd)r=rkrrr rs�sz,FirewallClientServiceSettings.removeProtocolcCs||jdkS)Nrg)r5)r=rkrrr rt�sz+FirewallClientServiceSettings.queryProtocolcCs
|jdS)Nr{)r5)r=rrr rv�sz,FirewallClientServiceSettings.getSourcePortscCs||jd<dS)Nr{)r5)r=r*rrr rw�sz,FirewallClientServiceSettings.setSourcePortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr{z'%s:%s')r5r_rrr`)r=rjrkrrr rx�sz+FirewallClientServiceSettings.addSourcePortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr{z'%s:%s')r5rcrrrd)r=rjrkrrr ry�sz.FirewallClientServiceSettings.removeSourcePortcCs||f|jdkS)Nr{)r5)r=rjrkrrr rz�sz-FirewallClientServiceSettings.querySourcePortcCs
|jdS)NrX)r5)r=rrr �
getModules�sz(FirewallClientServiceSettings.getModulescCs||jd<dS)NrX)r5)r=r�rrr �
setModules�sz(FirewallClientServiceSettings.setModulescCs0||jdkr |jdj|�nttj|��dS)NrX)r5r_rrr`)r=�modulerrr �	addModule�sz'FirewallClientServiceSettings.addModulecCs0||jdkr |jdj|�nttj|��dS)NrX)r5rcrrrd)r=r�rrr �removeModule�sz*FirewallClientServiceSettings.removeModulecCs||jdkS)NrX)r5)r=r�rrr �queryModule�sz)FirewallClientServiceSettings.queryModulecCs
|jdS)Nr\)r5)r=rrr �getDestinations�sz-FirewallClientServiceSettings.getDestinationscCs||jd<dS)Nr\)r5)r=�destinationsrrr �setDestinations�sz-FirewallClientServiceSettings.setDestinationscCsH||jdks |jd||kr0||jd|<nttjd||f��dS)Nr\z'%s:%s')r5rrr`)r=�	dest_type�addressrrr �setDestination�s
z,FirewallClientServiceSettings.setDestinationcCs^||jdkrJ|dk	r<|jd||kr<ttjd||f��|jd|=nttjd|��dS)Nr\z'%s:%s'z'%s')r5rrrd)r=r�rrrr �removeDestination�sz/FirewallClientServiceSettings.removeDestinationcCs ||jdko||jd|kS)Nr\)r5)r=r�rrrr �queryDestination�sz.FirewallClientServiceSettings.queryDestinationcCs
|jdS)Nr�)r5)r=rrr �getIncludes�sz)FirewallClientServiceSettings.getIncludescCs||jd<dS)Nr�)r5)r=r�rrr �setIncludes�sz)FirewallClientServiceSettings.setIncludescCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�includerrr �
addInclude�sz(FirewallClientServiceSettings.addIncludecCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=rrrr �
removeInclude�sz+FirewallClientServiceSettings.removeIncludecCs||jdkS)Nr�)r5)r=rrrr �queryInclude�sz*FirewallClientServiceSettings.queryIncludecCs
|jdS)Nr�)r5)r=rrr �
getHelpers�sz(FirewallClientServiceSettings.getHelperscCs||jd<dS)Nr�)r5)r=r�rrr �
setHelpers�sz(FirewallClientServiceSettings.setHelperscCs0||jdkr |jdj|�nttj|��dS)Nr�)r5r_rrr`)r=�helperrrr �	addHelper�sz'FirewallClientServiceSettings.addHelpercCs0||jdkr |jdj|�nttj|��dS)Nr�)r5rcrrrd)r=rrrr �removeHelpersz*FirewallClientServiceSettings.removeHelpercCs||jdkS)Nr�)r5)r=rrrr �queryHelpersz)FirewallClientServiceSettings.queryHelper)N)N)2r�r�r�r!r@rBrFr<rMrPrQrSrTrVrWrhrirlrmrnrprqrrrsrtrvrwrxryrzr�r�r�r�r�r�r�rrrrrrrr	r
rr
rrrrrr r�(s`r�c@s�eZdZed*dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��ZdS)+�FirewallClientIPSetSettingsNcCs"|r||_nddddigg|_dS)Nr#)r5)r=r5rrr r@sz$FirewallClientIPSetSettings.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rBsz$FirewallClientIPSetSettings.__repr__cCs
|jdS)Nr)r5)r=rrr rPsz&FirewallClientIPSetSettings.getVersioncCs||jd<dS)Nr)r5)r=r$rrr rQsz&FirewallClientIPSetSettings.setVersioncCs
|jdS)NrR)r5)r=rrr rS!sz$FirewallClientIPSetSettings.getShortcCs||jd<dS)NrR)r5)r=r%rrr rT$sz$FirewallClientIPSetSettings.setShortcCs
|jdS)NrU)r5)r=rrr rV(sz*FirewallClientIPSetSettings.getDescriptioncCs||jd<dS)NrU)r5)r=r&rrr rW+sz*FirewallClientIPSetSettings.setDescriptioncCs
|jdS)Nr�)r5)r=rrr �getType/sz#FirewallClientIPSetSettings.getTypecCs||jd<dS)Nr�)r5)r=Z
ipset_typerrr �setType2sz#FirewallClientIPSetSettings.setTypecCs
|jdS)NrX)r5)r=rrr �
getOptions6sz&FirewallClientIPSetSettings.getOptionscCs||jd<dS)NrX)r5)r=Zoptionsrrr �
setOptions9sz&FirewallClientIPSetSettings.setOptionscCsP||jdks |jd||kr0||jd|<nttj|rFd||fn|��dS)NrXz'%s=%s')r5rrr`)r=rDrErrr �	addOption<s z%FirewallClientIPSetSettings.addOptioncCs,||jdkr|jd|=nttj|��dS)NrX)r5rrrd)r=rDrrr �removeOptionCsz(FirewallClientIPSetSettings.removeOptioncCs ||jdko|jd||kS)NrX)r5)r=rDrErrr �queryOptionIsz'FirewallClientIPSetSettings.queryOptioncCs
|jdS)Nr\)r5)r=rrr �
getEntriesMsz&FirewallClientIPSetSettings.getEntriescCs@d|jdkr*|jdddkr*ttj��t|�||jd<dS)N�timeoutrX�0r\)r5rr�IPSET_WITH_TIMEOUTr)r=�entriesrrr �
setEntriesPs

z&FirewallClientIPSetSettings.setEntriescCsrd|jdkr*|jdddkr*ttj��t|�}||jdkrbt||jd�|jdj|�nttj|��dS)NrrXrr\)r5rrrrr
r_r`)r=�entryrrr �addEntryWs
z$FirewallClientIPSetSettings.addEntrycCsbd|jdkr*|jdddkr*ttj��t|�}||jdkrR|jdj|�nttj|��dS)NrrXrr\)r5rrrrrcrd)r=rrrr �removeEntrybs
z'FirewallClientIPSetSettings.removeEntrycCs@d|jdkr*|jdddkr*ttj��t|�}||jdkS)NrrXrr\)r5rrrr)r=rrrr �
queryEntryls

z&FirewallClientIPSetSettings.queryEntry)N)r�r�r�r!r@rBrPrQrSrTrVrWrrrrrrrrrrr r!rrrr rs*
rc@s�eZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zd)S)*�FirewallClientConfigIPSetcCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)r�zorg.freedesktop.DBus.Properties)r�r�r�rrr�r�r��DBUS_INTERFACE_CONFIG_IPSET�fw_ipsetr�)r=r�r�rrr r@wsz"FirewallClientConfigIPSet.__init__cCst|jjtjj|��S)N)r	r�r�rrr#)r=r�rrr r��sz&FirewallClientConfigIPSet.get_propertycCst|jjtjj��S)N)r	r�r�rrr#)r=rrr r��sz(FirewallClientConfigIPSet.get_propertiescCs|jjtjj||�dS)N)r�r�rrr#)r=r�rErrr r��sz&FirewallClientConfigIPSet.set_propertycCsttt|jj����S)N)rr9r	r$r�)r=rrr r��sz%FirewallClientConfigIPSet.getSettingscCs|jjt|j��dS)N)r$r��tupler5)r=r5rrr r��sz FirewallClientConfigIPSet.updatecCs|jj�dS)N)r$r�)r=rrr r��sz&FirewallClientConfigIPSet.loadDefaultscCs|jj�dS)N)r$rc)r=rrr rc�sz FirewallClientConfigIPSet.removecCs|jj|�dS)N)r$r�)r=r�rrr r��sz FirewallClientConfigIPSet.renamecCs
|jj�S)N)r$rP)r=rrr rP�sz$FirewallClientConfigIPSet.getVersioncCs|jj|�dS)N)r$rQ)r=r$rrr rQ�sz$FirewallClientConfigIPSet.setVersioncCs
|jj�S)N)r$rS)r=rrr rS�sz"FirewallClientConfigIPSet.getShortcCs|jj|�dS)N)r$rT)r=r%rrr rT�sz"FirewallClientConfigIPSet.setShortcCs
|jj�S)N)r$rV)r=rrr rV�sz(FirewallClientConfigIPSet.getDescriptioncCs|jj|�dS)N)r$rW)r=r&rrr rW�sz(FirewallClientConfigIPSet.setDescriptioncCs
|jj�S)N)r$r)r=rrr r�sz$FirewallClientConfigIPSet.getEntriescCs|jj|�dS)N)r$r)r=rrrr r�sz$FirewallClientConfigIPSet.setEntriescCs|jj|�dS)N)r$r)r=rrrr r�sz"FirewallClientConfigIPSet.addEntrycCs|jj|�dS)N)r$r )r=rrrr r �sz%FirewallClientConfigIPSet.removeEntrycCs|jj|�S)N)r$r!)r=rrrr r!�sz$FirewallClientConfigIPSet.queryEntryN)r�r�r�r!r@r�rr�r�r�r�r�r�r�r�rcr�rPrQrSrTrVrWrrrr r!rrrr r"vsNr"c@s�eZdZed$dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��ZdS)%�FirewallClientHelperSettingsNcCs"|r||_ndddddgg|_dS)Nr#)r5)r=r5rrr r@�sz%FirewallClientHelperSettings.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rB�sz%FirewallClientHelperSettings.__repr__cCs
|jdS)Nr)r5)r=rrr rP�sz'FirewallClientHelperSettings.getVersioncCs||jd<dS)Nr)r5)r=r$rrr rQ�sz'FirewallClientHelperSettings.setVersioncCs
|jdS)NrR)r5)r=rrr rSsz%FirewallClientHelperSettings.getShortcCs||jd<dS)NrR)r5)r=r%rrr rTsz%FirewallClientHelperSettings.setShortcCs
|jdS)NrU)r5)r=rrr rV	sz+FirewallClientHelperSettings.getDescriptioncCs||jd<dS)NrU)r5)r=r&rrr rWsz+FirewallClientHelperSettings.setDescriptioncCs
|jdS)Nr�)r5)r=rrr �	getFamilysz&FirewallClientHelperSettings.getFamilycCs |dkrd|jd<||jd<dS)Nr#r�)r5)r=�ipvrrr �	setFamilys
z&FirewallClientHelperSettings.setFamilycCs
|jdS)NrX)r5)r=rrr �	getModulesz&FirewallClientHelperSettings.getModulecCs||jd<dS)NrX)r5)r=r�rrr �	setModulesz&FirewallClientHelperSettings.setModulecCs
|jdS)Nr\)r5)r=rrr rh sz%FirewallClientHelperSettings.getPortscCs||jd<dS)Nr\)r5)r=r*rrr ri#sz%FirewallClientHelperSettings.setPortscCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr\z'%s:%s')r5r_rrr`)r=rjrkrrr rl&sz$FirewallClientHelperSettings.addPortcCs@||f|jdkr(|jdj||f�nttjd||f��dS)Nr\z'%s:%s')r5rcrrrd)r=rjrkrrr rm-sz'FirewallClientHelperSettings.removePortcCs||f|jdkS)Nr\)r5)r=rjrkrrr rn4sz&FirewallClientHelperSettings.queryPort)N)r�r�r�r!r@rBrPrQrSrTrVrWr'r)r*r+rhrirlrmrnrrrr r&�s$r&c@seZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zejjjed)d*���Zejjjed+d,���Zejjjed-d.���Zejjjed/d0���Zd1S)2�FirewallClientConfigHelpercCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)r�zorg.freedesktop.DBus.Properties)r�r�r�rrr�r�r��DBUS_INTERFACE_CONFIG_HELPER�	fw_helperr�)r=r�r�rrr r@;sz#FirewallClientConfigHelper.__init__cCst|jjtjj|��S)N)r	r�r�rrr-)r=r�rrr r�Fsz'FirewallClientConfigHelper.get_propertycCst|jjtjj��S)N)r	r�r�rrr-)r=rrr r�Lsz)FirewallClientConfigHelper.get_propertiescCs|jjtjj||�dS)N)r�r�rrr-)r=r�rErrr r�Rsz'FirewallClientConfigHelper.set_propertycCsttt|jj����S)N)r&r9r	r.r�)r=rrr r�Xsz&FirewallClientConfigHelper.getSettingscCs|jjt|j��dS)N)r.r�r%r5)r=r5rrr r�^sz!FirewallClientConfigHelper.updatecCs|jj�dS)N)r.r�)r=rrr r�csz'FirewallClientConfigHelper.loadDefaultscCs|jj�dS)N)r.rc)r=rrr rchsz!FirewallClientConfigHelper.removecCs|jj|�dS)N)r.r�)r=r�rrr r�msz!FirewallClientConfigHelper.renamecCs
|jj�S)N)r.rP)r=rrr rPtsz%FirewallClientConfigHelper.getVersioncCs|jj|�dS)N)r.rQ)r=r$rrr rQysz%FirewallClientConfigHelper.setVersioncCs
|jj�S)N)r.rS)r=rrr rS�sz#FirewallClientConfigHelper.getShortcCs|jj|�dS)N)r.rT)r=r%rrr rT�sz#FirewallClientConfigHelper.setShortcCs
|jj�S)N)r.rV)r=rrr rV�sz)FirewallClientConfigHelper.getDescriptioncCs|jj|�dS)N)r.rW)r=r&rrr rW�sz)FirewallClientConfigHelper.setDescriptioncCs
|jj�S)N)r.rh)r=rrr rh�sz#FirewallClientConfigHelper.getPortscCs|jj|�dS)N)r.ri)r=r*rrr ri�sz#FirewallClientConfigHelper.setPortscCs|jj||�dS)N)r.rl)r=rjrkrrr rl�sz"FirewallClientConfigHelper.addPortcCs|jj||�dS)N)r.rm)r=rjrkrrr rm�sz%FirewallClientConfigHelper.removePortcCs|jj||�S)N)r.rn)r=rjrkrrr rn�sz$FirewallClientConfigHelper.queryPortcCs
|jj�S)N)r.r')r=rrr r'�sz$FirewallClientConfigHelper.getFamilycCs$|dkr|jjd�|jj|�dS)Nr#)r.r))r=r(rrr r)�sz$FirewallClientConfigHelper.setFamilycCs
|jj�S)N)r.r*)r=rrr r*�sz$FirewallClientConfigHelper.getModulecCs|jj|�dS)N)r.r+)r=r�rrr r+�sz$FirewallClientConfigHelper.setModuleN) r�r�r�r!r@r�rr�r�r�r�r�r�r�r�rcr�rPrQrSrTrVrWrhrirlrmrnr'r)r*r+rrrr r,:s^r,c@s�eZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zejjjed)d*���Zejjjed+d,���Zejjjed-d.���Zejjjed/d0���Zejjjed1d2���Z ejjjed3d4���Z!ejjjed5d6���Z"ejjjed7d8���Z#ejjjed9d:���Z$ejjjed;d<���Z%ejjjed=d>���Z&ejjjed?d@���Z'ejjjedAdB���Z(ejjjedCdD���Z)ejjjedEdF���Z*ejjjedGdH���Z+ejjjedIdJ���Z,ejjjedKdL���Z-ejjjedMdN���Z.ejjjed^dPdQ���Z/ejjjedRdS���Z0ejjjedTdU���Z1ejjjedVdW���Z2ejjjedXdY���Z3ejjjedZd[���Z4ejjjed\d]���Z5dOS)_�FirewallClientConfigServicecCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)r�zorg.freedesktop.DBus.Properties)r�r�r�rrr�r�r��DBUS_INTERFACE_CONFIG_SERVICE�
fw_servicer�)r=r�r�rrr r@�sz$FirewallClientConfigService.__init__cCst|jjtjj|��S)N)r	r�r�rrr0)r=r�rrr r��sz(FirewallClientConfigService.get_propertycCst|jjtjj��S)N)r	r�r�rrr0)r=rrr r��sz*FirewallClientConfigService.get_propertiescCs|jjtjj||�dS)N)r�r�rrr0)r=r�rErrr r��sz(FirewallClientConfigService.set_propertycCstt|jj���S)N)r�r	r1r�)r=rrr r��sz'FirewallClientConfigService.getSettingscCs|jj|j��dS)N)r1r�rM)r=r5rrr r��sz"FirewallClientConfigService.updatecCs|jj�dS)N)r1r�)r=rrr r��sz(FirewallClientConfigService.loadDefaultscCs|jj�dS)N)r1rc)r=rrr rc�sz"FirewallClientConfigService.removecCs|jj|�dS)N)r1r�)r=r�rrr r�sz"FirewallClientConfigService.renamecCs
|jj�S)N)r1rP)r=rrr rPsz&FirewallClientConfigService.getVersioncCs|jj|�dS)N)r1rQ)r=r$rrr rQsz&FirewallClientConfigService.setVersioncCs
|jj�S)N)r1rS)r=rrr rSsz$FirewallClientConfigService.getShortcCs|jj|�dS)N)r1rT)r=r%rrr rTsz$FirewallClientConfigService.setShortcCs
|jj�S)N)r1rV)r=rrr rVsz*FirewallClientConfigService.getDescriptioncCs|jj|�dS)N)r1rW)r=r&rrr rW$sz*FirewallClientConfigService.setDescriptioncCs
|jj�S)N)r1rh)r=rrr rh+sz$FirewallClientConfigService.getPortscCs|jj|�dS)N)r1ri)r=r*rrr ri0sz$FirewallClientConfigService.setPortscCs|jj||�dS)N)r1rl)r=rjrkrrr rl5sz#FirewallClientConfigService.addPortcCs|jj||�dS)N)r1rm)r=rjrkrrr rm:sz&FirewallClientConfigService.removePortcCs|jj||�S)N)r1rn)r=rjrkrrr rn?sz%FirewallClientConfigService.queryPortcCs
|jj�S)N)r1rp)r=rrr rpFsz(FirewallClientConfigService.getProtocolscCs|jj|�dS)N)r1rq)r=r0rrr rqKsz(FirewallClientConfigService.setProtocolscCs|jj|�dS)N)r1rr)r=rkrrr rrPsz'FirewallClientConfigService.addProtocolcCs|jj|�dS)N)r1rs)r=rkrrr rsUsz*FirewallClientConfigService.removeProtocolcCs|jj|�S)N)r1rt)r=rkrrr rtZsz)FirewallClientConfigService.queryProtocolcCs
|jj�S)N)r1rv)r=rrr rvasz*FirewallClientConfigService.getSourcePortscCs|jj|�dS)N)r1rw)r=r*rrr rwfsz*FirewallClientConfigService.setSourcePortscCs|jj||�dS)N)r1rx)r=rjrkrrr rxksz)FirewallClientConfigService.addSourcePortcCs|jj||�dS)N)r1ry)r=rjrkrrr rypsz,FirewallClientConfigService.removeSourcePortcCs|jj||�S)N)r1rz)r=rjrkrrr rzusz+FirewallClientConfigService.querySourcePortcCs
|jj�S)N)r1r�)r=rrr r�|sz&FirewallClientConfigService.getModulescCs|jj|�dS)N)r1r�)r=r�rrr r��sz&FirewallClientConfigService.setModulescCs|jj|�dS)N)r1r�)r=r�rrr r��sz%FirewallClientConfigService.addModulecCs|jj|�dS)N)r1r�)r=r�rrr r��sz(FirewallClientConfigService.removeModulecCs|jj|�S)N)r1r�)r=r�rrr r��sz'FirewallClientConfigService.queryModulecCs
|jj�S)N)r1r�)r=rrr r��sz+FirewallClientConfigService.getDestinationscCs|jj|�dS)N)r1r�)r=r�rrr r��sz+FirewallClientConfigService.setDestinationscCs|jj|�S)N)r1�getDestination)r=r�rrr r2�sz*FirewallClientConfigService.getDestinationcCs|jj||�dS)N)r1r)r=r�rrrr r�sz*FirewallClientConfigService.setDestinationNcCs:|dk	r*|j|�|kr*ttjd||f��|jj|�dS)Nz'%s:%s')r2rrrdr1r)r=r�rrrr r�sz-FirewallClientConfigService.removeDestinationcCs|jj||�S)N)r1r)r=r�rrrr r�sz,FirewallClientConfigService.queryDestinationcCs
|jj�S)N)r1r)r=rrr r�sz'FirewallClientConfigService.getIncludescCs|jj|�dS)N)r1r)r=r�rrr r�sz'FirewallClientConfigService.setIncludescCs|jj|�dS)N)r1r)r=rrrr r�sz&FirewallClientConfigService.addIncludecCs|jj|�dS)N)r1r)r=rrrr r�sz)FirewallClientConfigService.removeIncludecCs|jj|�S)N)r1r	)r=rrrr r	�sz(FirewallClientConfigService.queryInclude)N)6r�r�r�r!r@r�rr�r�r�r�r�r�r�r�rcr�rPrQrSrTrVrWrhrirlrmrnrprqrrrsrtrvrwrxryrzr�r�r�r�r�r�r�r2rrrrrrrr	rrrr r/�s�r/c@s�eZdZeddd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��ZdS)�FirewallClientIcmpTypeSettingsNcCs|r||_ndddgg|_dS)Nr#)r5)r=r5rrr r@�sz'FirewallClientIcmpTypeSettings.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rB�sz'FirewallClientIcmpTypeSettings.__repr__cCs
|jdS)Nr)r5)r=rrr rP�sz)FirewallClientIcmpTypeSettings.getVersioncCs||jd<dS)Nr)r5)r=r$rrr rQ�sz)FirewallClientIcmpTypeSettings.setVersioncCs
|jdS)NrR)r5)r=rrr rS�sz'FirewallClientIcmpTypeSettings.getShortcCs||jd<dS)NrR)r5)r=r%rrr rT�sz'FirewallClientIcmpTypeSettings.setShortcCs
|jdS)NrU)r5)r=rrr rV�sz-FirewallClientIcmpTypeSettings.getDescriptioncCs||jd<dS)NrU)r5)r=r&rrr rW�sz-FirewallClientIcmpTypeSettings.setDescriptioncCs
|jdS)Nr�)r5)r=rrr r��sz.FirewallClientIcmpTypeSettings.getDestinationscCs||jd<dS)Nr�)r5)r=r�rrr r��sz.FirewallClientIcmpTypeSettings.setDestinationscCsH|jdsttj|��n,||jdkr8|jdj|�nttj|��dS)Nr�)r5rrr`r_)r=r�rrr �addDestination�s

z-FirewallClientIcmpTypeSettings.addDestinationcCs\||jdkr |jdj|�n8|jdsL|jttddg�t|g���nttj|��dS)Nr�Zipv4Zipv6)r5rcr�r9�setrrrd)r=r�rrr r	s
z0FirewallClientIcmpTypeSettings.removeDestinationcCs|jdp||jdkS)Nr�)r5)r=r�rrr r	sz/FirewallClientIcmpTypeSettings.queryDestination)N)r�r�r�r!r@rBrPrQrSrTrVrWr�r�r4rrrrrr r3�s	r3c@s�eZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zd)S)*�FirewallClientConfigIcmpTypecCsL||_||_|jjtjj|�|_tj|jtjjd�|_	tj|jdd�|_
dS)N)r�zorg.freedesktop.DBus.Properties)r�r�r�rrr�r�r��DBUS_INTERFACE_CONFIG_ICMPTYPE�fw_icmptyper�)r=r�r�rrr r@	sz%FirewallClientConfigIcmpType.__init__cCst|jjtjj|��S)N)r	r�r�rrr7)r=r�rrr r�%	sz)FirewallClientConfigIcmpType.get_propertycCst|jjtjj��S)N)r	r�r�rrr7)r=rrr r�+	sz+FirewallClientConfigIcmpType.get_propertiescCs|jjtjj||�dS)N)r�r�rrr7)r=r�rErrr r�1	sz)FirewallClientConfigIcmpType.set_propertycCsttt|jj����S)N)r3r9r	r8r�)r=rrr r�7	sz(FirewallClientConfigIcmpType.getSettingscCs|jjt|j��dS)N)r8r�r%r5)r=r5rrr r�=	sz#FirewallClientConfigIcmpType.updatecCs|jj�dS)N)r8r�)r=rrr r�B	sz)FirewallClientConfigIcmpType.loadDefaultscCs|jj�dS)N)r8rc)r=rrr rcG	sz#FirewallClientConfigIcmpType.removecCs|jj|�dS)N)r8r�)r=r�rrr r�L	sz#FirewallClientConfigIcmpType.renamecCs
|jj�S)N)r8rP)r=rrr rPS	sz'FirewallClientConfigIcmpType.getVersioncCs|jj|�dS)N)r8rQ)r=r$rrr rQX	sz'FirewallClientConfigIcmpType.setVersioncCs
|jj�S)N)r8rS)r=rrr rS_	sz%FirewallClientConfigIcmpType.getShortcCs|jj|�dS)N)r8rT)r=r%rrr rTd	sz%FirewallClientConfigIcmpType.setShortcCs
|jj�S)N)r8rV)r=rrr rVk	sz+FirewallClientConfigIcmpType.getDescriptioncCs|jj|�dS)N)r8rW)r=r&rrr rWp	sz+FirewallClientConfigIcmpType.setDescriptioncCs
|jj�S)N)r8r�)r=rrr r�w	sz,FirewallClientConfigIcmpType.getDestinationscCs|jj|�dS)N)r8r�)r=r�rrr r�|	sz,FirewallClientConfigIcmpType.setDestinationscCs|jj|�dS)N)r8r4)r=r�rrr r4�	sz+FirewallClientConfigIcmpType.addDestinationcCs|jj|�dS)N)r8r)r=r�rrr r�	sz.FirewallClientConfigIcmpType.removeDestinationcCs|jj|�S)N)r8r)r=r�rrr r�	sz-FirewallClientConfigIcmpType.queryDestinationN)r�r�r�r!r@r�rr�r�r�r�r�r�r�r�rcr�rPrQrSrTrVrWr�r�r4rrrrrr r6	sNr6c@seZdZed.dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��Zed*d+��Zed,d-��ZdS)/�'FirewallClientPoliciesLockdownWhitelistNcCs|r||_nggggg|_dS)N)r5)r=r5rrr r@�	sz0FirewallClientPoliciesLockdownWhitelist.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rB�	sz0FirewallClientPoliciesLockdownWhitelist.__repr__cCs
|jdS)Nr)r5)r=rrr �getCommands�	sz3FirewallClientPoliciesLockdownWhitelist.getCommandscCs||jd<dS)Nr)r5)r=Zcommandsrrr �setCommands�	sz3FirewallClientPoliciesLockdownWhitelist.setCommandscCs"||jdkr|jdj|�dS)Nr)r5r_)r=�commandrrr �
addCommand�	sz2FirewallClientPoliciesLockdownWhitelist.addCommandcCs"||jdkr|jdj|�dS)Nr)r5rc)r=r<rrr �
removeCommand�	sz5FirewallClientPoliciesLockdownWhitelist.removeCommandcCs||jdkS)Nr)r5)r=r<rrr �queryCommand�	sz4FirewallClientPoliciesLockdownWhitelist.queryCommandcCs
|jdS)NrR)r5)r=rrr �getContexts�	sz3FirewallClientPoliciesLockdownWhitelist.getContextscCs||jd<dS)NrR)r5)r=Zcontextsrrr �setContexts�	sz3FirewallClientPoliciesLockdownWhitelist.setContextscCs"||jdkr|jdj|�dS)NrR)r5r_)r=�contextrrr �
addContext�	sz2FirewallClientPoliciesLockdownWhitelist.addContextcCs"||jdkr|jdj|�dS)NrR)r5rc)r=rBrrr �
removeContext�	sz5FirewallClientPoliciesLockdownWhitelist.removeContextcCs||jdkS)NrR)r5)r=rBrrr �queryContext�	sz4FirewallClientPoliciesLockdownWhitelist.queryContextcCs
|jdS)NrU)r5)r=rrr �getUsers�	sz0FirewallClientPoliciesLockdownWhitelist.getUserscCs||jd<dS)NrU)r5)r=Zusersrrr �setUsers�	sz0FirewallClientPoliciesLockdownWhitelist.setUserscCs"||jdkr|jdj|�dS)NrU)r5r_)r=�userrrr �addUser�	sz/FirewallClientPoliciesLockdownWhitelist.addUsercCs"||jdkr|jdj|�dS)NrU)r5rc)r=rHrrr �
removeUser�	sz2FirewallClientPoliciesLockdownWhitelist.removeUsercCs||jdkS)NrU)r5)r=rHrrr �	queryUser�	sz1FirewallClientPoliciesLockdownWhitelist.queryUsercCs
|jdS)Nr�)r5)r=rrr �getUids�	sz/FirewallClientPoliciesLockdownWhitelist.getUidscCs||jd<dS)Nr�)r5)r=�uidsrrr �setUids�	sz/FirewallClientPoliciesLockdownWhitelist.setUidscCs"||jdkr|jdj|�dS)Nr�)r5r_)r=�uidrrr �addUid�	sz.FirewallClientPoliciesLockdownWhitelist.addUidcCs"||jdkr|jdj|�dS)Nr�)r5rc)r=rOrrr �	removeUid�	sz1FirewallClientPoliciesLockdownWhitelist.removeUidcCs||jdkS)Nr�)r5)r=rOrrr �queryUid�	sz0FirewallClientPoliciesLockdownWhitelist.queryUid)N)r�r�r�r!r@rBr:r;r=r>r?r@rArCrDrErFrGrIrJrKrLrNrPrQrRrrrr r9�	s.r9c@s�eZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zd)S)*�FirewallClientConfigPoliciescCs8||_|jjtjjtjj�|_tj|jtjjd�|_	dS)N)r�)
r�r�rrr��DBUS_PATH_CONFIGr�r��DBUS_INTERFACE_CONFIG_POLICIES�fw_policies)r=r�rrr r@�	sz%FirewallClientConfigPolicies.__init__cCsttt|jj����S)N)r9r9r	rV�getLockdownWhitelist)r=rrr rW�	sz1FirewallClientConfigPolicies.getLockdownWhitelistcCs|jjt|j��dS)N)rV�setLockdownWhitelistr%r5)r=r5rrr rX�	sz1FirewallClientConfigPolicies.setLockdownWhitelistcCs|jj|�dS)N)rV�addLockdownWhitelistCommand)r=r<rrr rY
sz8FirewallClientConfigPolicies.addLockdownWhitelistCommandcCs|jj|�dS)N)rV�removeLockdownWhitelistCommand)r=r<rrr rZ
sz;FirewallClientConfigPolicies.removeLockdownWhitelistCommandcCst|jj|��S)N)r	rV�queryLockdownWhitelistCommand)r=r<rrr r[

sz:FirewallClientConfigPolicies.queryLockdownWhitelistCommandcCst|jj��S)N)r	rV�getLockdownWhitelistCommands)r=rrr r\
sz9FirewallClientConfigPolicies.getLockdownWhitelistCommandscCs|jj|�dS)N)rV�addLockdownWhitelistContext)r=rBrrr r]
sz8FirewallClientConfigPolicies.addLockdownWhitelistContextcCs|jj|�dS)N)rV�removeLockdownWhitelistContext)r=rBrrr r^
sz;FirewallClientConfigPolicies.removeLockdownWhitelistContextcCst|jj|��S)N)r	rV�queryLockdownWhitelistContext)r=rBrrr r_ 
sz:FirewallClientConfigPolicies.queryLockdownWhitelistContextcCst|jj��S)N)r	rV�getLockdownWhitelistContexts)r=rrr r`%
sz9FirewallClientConfigPolicies.getLockdownWhitelistContextscCs|jj|�dS)N)rV�addLockdownWhitelistUser)r=rHrrr ra,
sz5FirewallClientConfigPolicies.addLockdownWhitelistUsercCs|jj|�dS)N)rV�removeLockdownWhitelistUser)r=rHrrr rb1
sz8FirewallClientConfigPolicies.removeLockdownWhitelistUsercCst|jj|��S)N)r	rV�queryLockdownWhitelistUser)r=rHrrr rc6
sz7FirewallClientConfigPolicies.queryLockdownWhitelistUsercCst|jj��S)N)r	rV�getLockdownWhitelistUsers)r=rrr rd;
sz6FirewallClientConfigPolicies.getLockdownWhitelistUserscCst|jj��S)N)r	rV�getLockdownWhitelistUids)r=rrr reB
sz5FirewallClientConfigPolicies.getLockdownWhitelistUidscCs|jj|�dS)N)rV�setLockdownWhitelistUids)r=rMrrr rfG
sz5FirewallClientConfigPolicies.setLockdownWhitelistUidscCs|jj|�dS)N)rV�addLockdownWhitelistUid)r=rOrrr rgL
sz4FirewallClientConfigPolicies.addLockdownWhitelistUidcCs|jj|�dS)N)rV�removeLockdownWhitelistUid)r=rOrrr rhQ
sz7FirewallClientConfigPolicies.removeLockdownWhitelistUidcCst|jj|��S)N)r	rV�queryLockdownWhitelistUid)r=rOrrr riV
sz6FirewallClientConfigPolicies.queryLockdownWhitelistUidN)r�r�r�r!r@r�rr�r�rWrXrYrZr[r\r]r^r_r`rarbrcrdrerfrgrhrirrrr rS�	sN	rSc@seZdZed.dd��Zedd��Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zed d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��Zed*d+��Zed,d-��ZdS)/�FirewallClientDirectNcCs|r||_ngggg|_dS)N)r5)r=r5rrr r@^
szFirewallClientDirect.__init__cCsd|j|jfS)Nz%s(%r))rAr5)r=rrr rBe
szFirewallClientDirect.__repr__cCs
|jdS)Nr)r5)r=rrr �getAllChainsi
sz!FirewallClientDirect.getAllChainscs��fdd�|jdD�S)Ncs,g|]$}|d�kr|d�kr|d�qS)rrRrUr)r�r)r(�tablerr r�n
sz2FirewallClientDirect.getChains.<locals>.<listcomp>r)r5)r=r(rlr)r(rlr �	getChainsl
szFirewallClientDirect.getChainscCs||jd<dS)Nr)r5)r=Zchainsrrr �setAllChainsp
sz!FirewallClientDirect.setAllChainscCs,|||f}||jdkr(|jdj|�dS)Nr)r5r_)r=r(rl�chain�idxrrr �addChains
s
zFirewallClientDirect.addChaincCs,|||f}||jdkr(|jdj|�dS)Nr)r5rc)r=r(rlrorprrr �removeChainx
s
z FirewallClientDirect.removeChaincCs|||f}||jdkS)Nr)r5)r=r(rlrorprrr �
queryChain}
s
zFirewallClientDirect.queryChaincCs
|jdS)NrR)r5)r=rrr �getAllRules�
sz FirewallClientDirect.getAllRulescs���fdd�|jdD�S)Ncs<g|]4}|d�kr|d�kr|d�kr|dd��qS)rrRrUr�Nr)r�r)ror(rlrr r��
sz1FirewallClientDirect.getRules.<locals>.<listcomp>rR)r5)r=r(rlror)ror(rlr �getRules�
szFirewallClientDirect.getRulescCs||jd<dS)NrR)r5)r=r�rrr �setAllRules�
sz FirewallClientDirect.setAllRulescCs0|||||f}||jdkr,|jdj|�dS)NrR)r5r_)r=r(rlror�rrprrr �addRule�
szFirewallClientDirect.addRulecCs0|||||f}||jdkr,|jdj|�dS)NrR)r5rc)r=r(rlror�rrprrr �
removeRule�
szFirewallClientDirect.removeRulecCsPxJt|jd�D]8}|d|kr|d|kr|d|kr|jdj|�qWdS)NrRrrU)r9r5rc)r=r(rlrorprrr �removeRules�
s$z FirewallClientDirect.removeRulescCs|||||f}||jdkS)NrR)r5)r=r(rlror�rrprrr �	queryRule�
szFirewallClientDirect.queryRulecCs
|jdS)NrU)r5)r=rrr �getAllPassthroughs�
sz'FirewallClientDirect.getAllPassthroughscCs||jd<dS)NrU)r5)r=Zpassthroughsrrr �setAllPassthroughs�
sz'FirewallClientDirect.setAllPassthroughscCsg|jd<dS)NrU)r5)r=rrr �removeAllPassthroughs�
sz*FirewallClientDirect.removeAllPassthroughscs�fdd�|jdD�S)Ncs g|]}|d�kr|d�qS)rrRr)r�r)r(rr r��
sz8FirewallClientDirect.getPassthroughs.<locals>.<listcomp>rU)r5)r=r(r)r(r �getPassthroughs�
sz$FirewallClientDirect.getPassthroughscCs*||f}||jdkr&|jdj|�dS)NrU)r5r_)r=r(rrprrr �addPassthrough�
sz#FirewallClientDirect.addPassthroughcCs*||f}||jdkr&|jdj|�dS)NrU)r5rc)r=r(rrprrr �removePassthrough�
sz&FirewallClientDirect.removePassthroughcCs||f}||jdkS)NrU)r5)r=r(rrprrr �queryPassthrough�
sz%FirewallClientDirect.queryPassthrough)N)r�r�r�r!r@rBrkrmrnrqrrrsrtrurvrwrxryrzr{r|r}r~rr�r�rrrr rj]
s.rjc@s�eZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zd'S)(�FirewallClientConfigDirectcCs8||_|jjtjjtjj�|_tj|jtjjd�|_	dS)N)r�)
r�r�rrr�rTr�r��DBUS_INTERFACE_CONFIG_DIRECT�	fw_direct)r=r�rrr r@�
sz#FirewallClientConfigDirect.__init__cCsttt|jj����S)N)rjr9r	r�r�)r=rrr r��
sz&FirewallClientConfigDirect.getSettingscCs|jjt|j��dS)N)r�r�r%r5)r=r5rrr r��
sz!FirewallClientConfigDirect.updatecCs|jj|||�dS)N)r�rq)r=r(rlrorrr rq�
sz#FirewallClientConfigDirect.addChaincCs|jj|||�dS)N)r�rr)r=r(rlrorrr rr�
sz&FirewallClientConfigDirect.removeChaincCst|jj|||��S)N)r	r�rs)r=r(rlrorrr rs�
sz%FirewallClientConfigDirect.queryChaincCst|jj||��S)N)r	r�rm)r=r(rlrrr rm�
sz$FirewallClientConfigDirect.getChainscCst|jj��S)N)r	r�rk)r=rrr rk�
sz'FirewallClientConfigDirect.getAllChainscCs|jj|||||�dS)N)r�rw)r=r(rlror�rrrr rw�
sz"FirewallClientConfigDirect.addRulecCs|jj|||||�dS)N)r�rx)r=r(rlror�rrrr rx�
sz%FirewallClientConfigDirect.removeRulecCs|jj|||�dS)N)r�ry)r=r(rlrorrr ry�
sz&FirewallClientConfigDirect.removeRulescCst|jj|||||��S)N)r	r�rz)r=r(rlror�rrrr rzsz$FirewallClientConfigDirect.queryRulecCst|jj|||��S)N)r	r�ru)r=r(rlrorrr rusz#FirewallClientConfigDirect.getRulescCst|jj��S)N)r	r�rt)r=rrr rt
sz&FirewallClientConfigDirect.getAllRulescCs|jj||�dS)N)r�r)r=r(rrrr rsz)FirewallClientConfigDirect.addPassthroughcCs|jj||�dS)N)r�r�)r=r(rrrr r�sz,FirewallClientConfigDirect.removePassthroughcCst|jj||��S)N)r	r�r�)r=r(rrrr r�sz+FirewallClientConfigDirect.queryPassthroughcCst|jj|��S)N)r	r�r~)r=r(rrr r~ sz*FirewallClientConfigDirect.getPassthroughscCst|jj��S)N)r	r�r{)r=rrr r{%sz-FirewallClientConfigDirect.getAllPassthroughsN)r�r�r�r!r@r�rr�r�r�r�rqrrrsrmrkrwrxryrzrurtrr�r�r~r{rrrr r��
sJ	r�c@sFeZdZedd��Zejjjedd���Z	ejjjedd���Z
ejjjedd���Zejjjed	d
���Zejjjedd���Z
ejjjed
d���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd���Zejjjedd ���Zejjjed!d"���Zejjjed#d$���Zejjjed%d&���Zejjjed'd(���Zejjjed)d*���Zejjjed+d,���Zejjjed-d.���Zejjjed/d0���Zejjjed1d2���Z ejjjed3d4���Z!ejjjed5d6���Z"ejjjed7d8���Z#ejjjed9d:���Z$ejjjed;d<���Z%ejjjed=d>���Z&ejjjed?d@���Z'ejjjedAdB���Z(ejjjedCdD���Z)ejjjedEdF���Z*ejjjedGdH���Z+ejjjedIdJ���Z,ejjjedKdL���Z-dMS)N�FirewallClientConfigcCsb||_|jjtjjtjj�|_tj|jtjjd�|_	tj|jdd�|_
t|j�|_t
|j�|_dS)N)r�zorg.freedesktop.DBus.Properties)r�r�rrr�rTr�r��DBUS_INTERFACE_CONFIG�	fw_configr�rS�	_policiesr��_direct)r=r�rrr r@-szFirewallClientConfig.__init__cCst|jjtjj|��S)N)r	r�r�rrr�)r=r�rrr r�<sz!FirewallClientConfig.get_propertycCst|jjtjj��S)N)r	r�r�rrr�)r=rrr r�Bsz#FirewallClientConfig.get_propertiescCs|jjtjj||�dS)N)r�r�rrr�)r=r�rErrr r�Hsz!FirewallClientConfig.set_propertycCst|jj��S)N)r	r��
getIPSetNames)r=rrr r�Osz"FirewallClientConfig.getIPSetNamescCst|jj��S)N)r	r��
listIPSets)r=rrr r�TszFirewallClientConfig.listIPSetscCst|j|�S)N)r"r�)r=r�rrr �getIPSetYszFirewallClientConfig.getIPSetcCst|jj|��}t|j|�S)N)r	r��getIPSetByNamer"r�)r=r�r�rrr r�^sz#FirewallClientConfig.getIPSetByNamecCs>t|t�r |jj|t|j��}n|jj|t|��}t|j|�S)N)r8rr��addIPSetr%r5r"r�)r=r�r5r�rrr r�ds
zFirewallClientConfig.addIPSetcCst|jj��S)N)r	r��getZoneNames)r=rrr r�osz!FirewallClientConfig.getZoneNamescCst|jj��S)N)r	r��	listZones)r=rrr r�tszFirewallClientConfig.listZonescCst|j|�S)N)r�r�)r=r�rrr �getZoneyszFirewallClientConfig.getZonecCst|jj|��}t|j|�S)N)r	r��
getZoneByNamer�r�)r=r�r�rrr r�~sz"FirewallClientConfig.getZoneByNamecCst|jj|��S)N)r	r��getZoneOfInterface)r=Zifacerrr r��sz'FirewallClientConfig.getZoneOfInterfacecCst|jj|��S)N)r	r��getZoneOfSource)r=r�rrr r��sz$FirewallClientConfig.getZoneOfSourcecCs^t|t�r|jj||j��}n4t|t�r8|jj||�}n|jj|t|dd���}t|j	|�S)Nr�)
r8r"r�ZaddZone2rMr;�addZoner%r�r�)r=r�r5r�rrr r��s

zFirewallClientConfig.addZonecCst|jj��S)N)r	r��getPolicyNames)r=rrr r��sz#FirewallClientConfig.getPolicyNamescCst|jj��S)N)r	r��listPolicies)r=rrr r��sz!FirewallClientConfig.listPoliciescCst|j|�S)N)r�r�)r=r�rrr �	getPolicy�szFirewallClientConfig.getPolicycCst|jj|��}t|j|�S)N)r	r��getPolicyByNamer�r�)r=r�r�rrr r��sz$FirewallClientConfig.getPolicyByNamecCs8t|t�r|jj||j��}n|jj||�}t|j|�S)N)r8r�r��	addPolicyrMr�r�)r=r�r5r�rrr r��s
zFirewallClientConfig.addPolicycCst|jj��S)N)r	r��getServiceNames)r=rrr r��sz$FirewallClientConfig.getServiceNamescCst|jj��S)N)r	r��listServices)r=rrr r��sz!FirewallClientConfig.listServicescCst|j|�S)N)r/r�)r=r�rrr �
getService�szFirewallClientConfig.getServicecCst|jj|��}t|j|�S)N)r	r��getServiceByNamer/r�)r=r�r�rrr r��sz%FirewallClientConfig.getServiceByNamecCs`t|t�r|jj||j��}n6t|�tkr:|jj||�}n|jj|t|dd���}t	|j
|�S)Nr�)r8r�r�ZaddService2rMrIr;rbr%r/r�)r=r�r5r�rrr rb�s
zFirewallClientConfig.addServicecCst|jj��S)N)r	r��getIcmpTypeNames)r=rrr r��sz%FirewallClientConfig.getIcmpTypeNamescCst|jj��S)N)r	r��
listIcmpTypes)r=rrr r��sz"FirewallClientConfig.listIcmpTypescCst|j|�S)N)r6r�)r=r�rrr �getIcmpType�sz FirewallClientConfig.getIcmpTypecCst|jj|��}t|j|�S)N)r	r��getIcmpTypeByNamer6r�)r=r�r�rrr r��sz&FirewallClientConfig.getIcmpTypeByNamecCs>t|t�r |jj|t|j��}n|jj|t|��}t|j|�S)N)r8r3r��addIcmpTyper%r5r6r�)r=r�r5r�rrr r��s
z FirewallClientConfig.addIcmpTypecCs|jS)N)r�)r=rrr �policies�szFirewallClientConfig.policiescCs|jS)N)r�)r=rrr �directszFirewallClientConfig.directcCst|jj��S)N)r	r��getHelperNames)r=rrr r�sz#FirewallClientConfig.getHelperNamescCst|jj��S)N)r	r��listHelpers)r=rrr r�sz FirewallClientConfig.listHelperscCst|j|�S)N)r,r�)r=r�rrr �	getHelperszFirewallClientConfig.getHelpercCst|jj|��}t|j|�S)N)r	r��getHelperByNamer,r�)r=r�r�rrr r�sz$FirewallClientConfig.getHelperByNamecCs>t|t�r |jj|t|j��}n|jj|t|��}t|j|�S)N)r8r&r�r
r%r5r,r�)r=r�r5r�rrr r
 s
zFirewallClientConfig.addHelperN).r�r�r�r!r@r�rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rbr�r�r�r�r�r�r�r�r�r�r�r
rrrr r�,s�

r�c@s�eZdZe�ddd��Zedd��Zedd	��Zed
d��Zedd
��Zedd��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zejjjedd���Zejjjedd���Zejjjedd���Zejjjed d!���Zejjjed"d#���Zejjjed$d%���Zejjjed&d'���Zejjjed(d)���Zejjjed*d+���Zejjjed,d-���Zejjjed.d/���Zejjjed0d1���Zejjjed2d3���Zejjjed4d5���Z ejjjed6d7���Z!ejjjed8d9���Z"ejjjed:d;���Z#ejjjed<d=���Z$ejjjed>d?���Z%ejjjed@dA���Z&ejjjedBdC���Z'ejjjedDdE���Z(ejjjedFdG���Z)ejjjedHdI���Z*ejjjedJdK���Z+ejjjedLdM���Z,ejjjedNdO���Z-ejjjedPdQ���Z.ejjjedRdS���Z/ejjjedTdU���Z0ejjjedVdW���Z1ejjjedXdY���Z2ejjjedZd[���Z3ejjjed\d]���Z4ejjjed^d_���Z5ejjjed`da���Z6ejjjedbdc���Z7ejjjeddde���Z8ejjjedfdg���Z9ejjjedhdi���Z:ejjjedjdk���Z;ejjjedldm���Z<ejjjedndo���Z=ejjjedpdq���Z>ejjjedrds���Z?ejjjedtdu���Z@ejjjedvdw���ZAejjjedxdy���ZBejjjedzd{���ZCejjjed|d}���ZDejjjed~d���ZEejjjed�d����ZFejjjed�d����ZGejjje�dd�d����ZHejjjed�d����ZIejjjed�d����ZJejjjed�d����ZKejjje�dd�d����ZLejjjed�d����ZMejjjed�d����ZNejjjed�d����ZOejjje�dd�d����ZPejjjed�d����ZQejjjed�d����ZRejjjed�d����ZSejjje�dd�d����ZTejjjed�d����ZUejjjed�d����ZVejjjed�d����ZWejjjed�d����ZXejjjed�d����ZYejjjed�d����ZZejjje�dd�d����Z[ejjjed�d����Z\ejjjed�d����Z]ejjje�d d�d����Z^ejjjed�d����Z_ejjjed�d����Z`ejjjed�d����Zaejjje�d!d�d����Zbejjjed�d����Zcejjjed�d����Zdejjjed�d����Zeejjje�d"d�d����Zfejjjed�dÄ��Zgejjjed�dń��Zhejjjed�dDŽ��Ziejjjed�dɄ��Zjejjjed�d˄��Zkejjjed�d̈́��Zlejjjed�dτ��Zmejjjed�dф��Znejjjed�dӄ��Zoejjjed�dՄ��Zpejjjed�dׄ��Zqejjjed�dل��Zrejjjed�dۄ��Zsejjjed�d݄��Ztejjjed�d߄��Zuejjjed�d���Zvejjjed�d���Zwejjjed�d���Zxejjjed�d���Zyejjjed�d���Zzejjjed�d���Z{ejjjed�d���Z|ejjjed�d���Z}ejjjed�d���Z~ejjjed�d���Zejjjed�d����Z�ejjjed�d����Z�ejjjed�d����Z�ejjjed�d����Z�ejjjed�d����Z�ejjjed�d����Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d	���Z�ejjje�d
�d���Z�ejjje�d�d
���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�ejjje�d�d���Z�dS(#�FirewallClientNrTcdCs|s�tjjjdd�ytjj�|_d|j_Wq�tk
r�ytj�|_Wn6tj	j
k
r�}zttj
|j���WYdd}~Xn
Xtd�Yq�Xn||_|jj|jddtjjd�x�tjjtjjtjjtjjtjjtjjtjjtjjtjjtjjtjjtjjtjjtjj tjj!gD]}|jj|j"|ddd	d
��qWi|_#ddd
ddddddddddddddddddd d!d"d#d$d%d&d'd'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdY�O|_$|j%�||_&|dZk�rt'j(||j)�n|j)�dS)[NT)Zset_as_defaultzNot using slip.dbusZNameOwnerChangedzorg.freedesktop.DBus)Zhandler_functionZsignal_namer�Zarg0r��memberr�)r�Zinterface_keywordZmember_keywordZpath_keywordzconnection-changedzconnection-establishedzconnection-lostZLogDeniedChangedZDefaultZoneChangedZPanicModeEnabledZPanicModeDisabledZReloadedZServiceAddedZServiceRemovedZ	PortAddedZPortRemovedZSourcePortAddedZSourcePortRemovedZ
ProtocolAddedZProtocolRemovedZMasqueradeAddedZMasqueradeRemovedZForwardPortAddedZForwardPortRemovedZIcmpBlockAddedZIcmpBlockRemovedZIcmpBlockInversionAddedZIcmpBlockInversionRemovedZ
RichRuleAddedZRichRuleRemovedZInterfaceAddedZInterfaceRemovedZZoneOfInterfaceChangedZSourceAddedZ
SourceRemovedZZoneOfSourceChangedZZoneUpdatedZ
PolicyUpdatedZ
EntryAddedZEntryRemovedZ
ChainAddedZChainRemovedZ	RuleAddedZRuleRemovedZPassthroughAddedZPassthroughRemovedzconfig:direct:UpdatedZLockdownEnabledZLockdownDisabledZLockdownWhitelistCommandAddedZLockdownWhitelistCommandRemovedZLockdownWhitelistContextAddedZLockdownWhitelistContextRemovedZLockdownWhitelistUidAddedZLockdownWhitelistUidRemovedZLockdownWhitelistUserAddedZLockdownWhitelistUserRemovedz(config:policies:LockdownWhitelistUpdatedzconfig:IPSetAddedzconfig:IPSetUpdatedzconfig:IPSetRemovedzconfig:IPSetRenamedzconfig:ZoneAddedzconfig:ZoneUpdatedzconfig:ZoneRemovedzconfig:ZoneRenamedzconfig:PolicyAddedzconfig:PolicyUpdatedzconfig:PolicyRemovedzconfig:PolicyRenamedzconfig:ServiceAddedzconfig:ServiceUpdatedzconfig:ServiceRemovedzconfig:ServiceRenamedzconfig:IcmpTypeAddedzconfig:IcmpTypeUpdatedzconfig:IcmpTypeRemovedzconfig:IcmpTypeRenamedzconfig:HelperAddedzconfig:HelperUpdatedzconfig:HelperRemovedzconfig:HelperRenamed)Ozconnection-changedzconnection-establishedzconnection-lostzlog-denied-changedzdefault-zone-changedzpanic-mode-enabledzpanic-mode-disabledZreloadedz
service-addedzservice-removedz
port-addedzport-removedzsource-port-addedzsource-port-removedzprotocol-addedzprotocol-removedzmasquerade-addedzmasquerade-removedzforward-port-addedzforward-port-removedzicmp-block-addedzicmp-block-removedzicmp-block-inversion-addedzicmp-block-inversion-removedzrichrule-addedzrichrule-removedzinterface-addedzinterface-removedzzone-changedzzone-of-interface-changedzsource-addedzsource-removedzzone-of-source-changedzzone-updatedzpolicy-updatedzipset-entry-addedzipset-entry-removedzdirect:chain-addedzdirect:chain-removedzdirect:rule-addedzdirect:rule-removedzdirect:passthrough-addedzdirect:passthrough-removedzconfig:direct:updatedzlockdown-enabledzlockdown-disabledz lockdown-whitelist-command-addedz"lockdown-whitelist-command-removedz lockdown-whitelist-context-addedz"lockdown-whitelist-context-removedzlockdown-whitelist-uid-addedzlockdown-whitelist-uid-removedzlockdown-whitelist-user-addedzlockdown-whitelist-user-removedz*config:policies:lockdown-whitelist-updatedzconfig:ipset-addedzconfig:ipset-updatedzconfig:ipset-removedzconfig:ipset-renamedzconfig:zone-addedzconfig:zone-updatedzconfig:zone-removedzconfig:zone-renamedzconfig:policy-addedzconfig:policy-updatedzconfig:policy-removedzconfig:policy-renamedzconfig:service-addedzconfig:service-updatedzconfig:service-removedzconfig:service-renamedzconfig:icmptype-addedzconfig:icmptype-updatedzconfig:icmptype-removedzconfig:icmptype-renamedzconfig:helper-addedzconfig:helper-updatedzconfig:helper-removedzconfig:helper-renamedr)*rZmainloopZglibZ
DBusGMainLoopr�Z	SystemBusr�Zdefault_timeoutrrrrrZ
DBUS_ERRORr�printZadd_signal_receiver�_dbus_connection_changedrr��DBUS_INTERFACE_IPSET�DBUS_INTERFACE_ZONE�DBUS_INTERFACE_POLICY�DBUS_INTERFACE_DIRECT�DBUS_INTERFACE_POLICIESr�r#r�r�r0r-r�r7rU�_signal_receiver�	_callback�
_callbacks�
_init_vars�quietrZtimeout_add_seconds�_connection_established)r=r��waitr�rr�rrr r@,s�


zFirewallClient.__init__cCs:d|_d|_d|_d|_d|_d|_d|_d|_d|_dS)NF)	�fwr$r�r�r.r�r��_config�	connected)r=rrr r��szFirewallClient._init_varscCstS)N)r)r=rrr �getExceptionHandler�sz"FirewallClient.getExceptionHandlercCs|adS)N)r)r=Zhandlerrrr �setExceptionHandler�sz"FirewallClient.setExceptionHandlercCstS)N)r)r=rrr �getNotAuthorizedLoop�sz#FirewallClient.getNotAuthorizedLoopcCs|adS)N)r)r=�enablerrr �setNotAuthorizedLoop�sz#FirewallClient.setNotAuthorizedLoopcGs0||jkr ||f|j|j|<ntd|��dS)NzUnknown callback name '%s')r�r��
ValueError)r=r��callbackrrrr �connect�s
zFirewallClient.connectcCs*|tjjkrdS|r|j�n|j�dS)N)rrr�r��_connection_lost)r=r�Z	old_ownerZ	new_ownerrrr r��s

z'FirewallClient._dbus_connection_changedcCsXy�|jjtjjtjj�|_tj|jtjjd�|_tj|jtjj	d�|_
tj|jtjjd�|_tj|jtjj
d�|_tj|jtjjd�|_tj|jtjjd�|_tj|jdd�|_Wnjtjjk
r�}z|js�td|j��dSd}~Xn4tk
�r}z|j�std|�dSd}~XnXt|j�|_d|_|jdtjjd�|jdtjjd�dS)	N)r�zorg.freedesktop.DBus.PropertiesrrTzconnection-established)r�r�zconnection-changed)r�r�rrr�Z	DBUS_PATHr�r�r�r�r$r�r�r�r�r�r�r�rVr�rrr�r�rrr�r�r�r�)r=rrrr r��sD
z&FirewallClient._connection_establishedcCs0|j�|jdtjjd�|jdtjjd�dS)Nzconnection-lost)r�r�zconnection-changed)r�r�rrr�)r=rrr r�
s
zFirewallClient._connection_lostc	Os�d|ksd|krdS|d}|d}|jtjj�r:d|}|jtjj�rRd|}n�|jtjj�rjd|}n�|jtjj�r�d|}np|jtjj�r�d|}nX|jtjj�r�d|}n@|tjj	kr�d	|}n*|tjj
kr�d
|}n|tjjkr�d|}d}x<|jD]2}|j||kr�|j||j
kr�|j
|j|}q�W|dk�rBdSdd
�|D�}y(|d�rj|j|d�|d|�Wn,tk
�r�}zt|�WYdd}~XnXdS)Nr�r�zconfig:Zonez
config:Policyzconfig:IPSetzconfig:Servicezconfig:IcmpTypez
config:Helperzconfig:zconfig:policies:zconfig:direct:cSsg|]}t|��qSr)r	)r��argrrr r�C
sz3FirewallClient._signal_receiver.<locals>.<listcomp>rRr)�
startswithrrr�r�r#r0r7r-r�rUr�r�r��extendrr�)	r=rr�signalr��cbr�Zcb_args�msgrrr r�
sH








zFirewallClient._signal_receivercCs|jS)N)r�)r=rrr rM
szFirewallClient.configcCs|jj�dS)N)r��reload)r=rrr r�R
szFirewallClient.reloadcCs|jj�dS)N)r�ZcompleteReload)r=rrr �complete_reloadW
szFirewallClient.complete_reloadcCs|jj�dS)N)r��runtimeToPermanent)r=rrr r�\
sz!FirewallClient.runtimeToPermanentcCs|jj�dS)N)r��checkPermanentConfig)r=rrr r�a
sz#FirewallClient.checkPermanentConfigcCst|jjtjj|��S)N)r	r�r�rrr�)r=r�rrr r�f
szFirewallClient.get_propertycCst|jjtjj��S)N)r	r�r�rrr�)r=rrr r�l
szFirewallClient.get_propertiescCs|jjtjj||�dS)N)r�r�rrr�)r=r�rErrr r�r
szFirewallClient.set_propertycCs|jj�dS)N)r��enablePanicMode)r=rrr r�y
szFirewallClient.enablePanicModecCs|jj�dS)N)r��disablePanicMode)r=rrr r�~
szFirewallClient.disablePanicModecCst|jj��S)N)r	r��queryPanicMode)r=rrr r��
szFirewallClient.queryPanicModecCstt|jj|���S)N)r"r	r��getZoneSettings2)r=�zonerrr �getZoneSettings�
szFirewallClient.getZoneSettingscCst|jj��S)N)r	r$�	getIPSets)r=rrr r��
szFirewallClient.getIPSetscCsttt|jj|����S)N)rr9r	r$�getIPSetSettings)r=�ipsetrrr r��
szFirewallClient.getIPSetSettingscCs|jj||�dS)N)r$r)r=r�rrrr r�
szFirewallClient.addEntrycCs|jj|�S)N)r$r)r=r�rrr r�
szFirewallClient.getEntriescCs|jj||�S)N)r$r)r=r�rrrr r�
szFirewallClient.setEntriescCs|jj||�dS)N)r$r )r=r�rrrr r �
szFirewallClient.removeEntrycCst|jj||��S)N)r	r$r!)r=r�rrrr r!�
szFirewallClient.queryEntrycCst|jj��S)N)r	r�r�)r=rrr r��
szFirewallClient.listServicescCstt|jj|���S)N)r�r	r�ZgetServiceSettings2)r=rarrr �getServiceSettings�
sz!FirewallClient.getServiceSettingscCst|jj��S)N)r	r�r�)r=rrr r��
szFirewallClient.listIcmpTypescCsttt|jj|����S)N)r3r9r	r��getIcmpTypeSettings)r=rrrr r��
sz"FirewallClient.getIcmpTypeSettingscCst|jj��S)N)r	r�r
)r=rrr r
�
szFirewallClient.getHelperscCsttt|jj|����S)N)r&r9r	r��getHelperSettings)r=rrrr r��
sz FirewallClient.getHelperSettingscCst|jj��S)N)r	r��getAutomaticHelpers)r=rrr r��
sz"FirewallClient.getAutomaticHelperscCs|jj|�dS)N)r��setAutomaticHelpers)r=rErrr r��
sz"FirewallClient.setAutomaticHelperscCst|jj��S)N)r	r��getLogDenied)r=rrr r��
szFirewallClient.getLogDeniedcCs|jj|�dS)N)r��setLogDenied)r=rErrr r��
szFirewallClient.setLogDeniedcCst|jj��S)N)r	r��getDefaultZone)r=rrr r��
szFirewallClient.getDefaultZonecCs|jj|�dS)N)r��setDefaultZone)r=r�rrr r��
szFirewallClient.setDefaultZonecCs|jj||j��dS)N)r��setZoneSettings2rO)r=r�r5rrr �setZoneSettings�
szFirewallClient.setZoneSettingscCst|jj��S)N)r	r��getZones)r=rrr r��
szFirewallClient.getZonescCst|jj��S)N)r	r��getActiveZones)r=rrr r�szFirewallClient.getActiveZonescCst|jj|��S)N)r	r�r�)r=r�rrr r�	sz!FirewallClient.getZoneOfInterfacecCst|jj|��S)N)r	r�r�)r=r�rrr r�szFirewallClient.getZoneOfSourcecCst|jj|��S)N)r	r��isImmutable)r=r�rrr r�szFirewallClient.isImmutablecCstt|jj|���S)N)r�r	r��getPolicySettings)r=�policyrrr r�sz FirewallClient.getPolicySettingscCs|jj||j��dS)N)r��setPolicySettingsrO)r=r�r5rrr r�sz FirewallClient.setPolicySettingscCst|jj��S)N)r	r��getPolicies)r=rrr r�$szFirewallClient.getPoliciescCst|jj��S)N)r	r��getActivePolicies)r=rrr r�)sz FirewallClient.getActivePoliciescCst|jj|��S)N)r	r�r�)r=r�rrr �isPolicyImmutable.sz FirewallClient.isPolicyImmutablecCst|jj||��S)N)r	r�r�)r=r�r�rrr r�5szFirewallClient.addInterfacecCst|jj||��S)N)r	r��
changeZone)r=r�r�rrr r�:szFirewallClient.changeZonecCst|jj||��S)N)r	r��changeZoneOfInterface)r=r�r�rrr r�?s
z$FirewallClient.changeZoneOfInterfacecCst|jj|��S)N)r	r�r�)r=r�rrr r�EszFirewallClient.getInterfacescCst|jj||��S)N)r	r�r�)r=r�r�rrr r�JszFirewallClient.queryInterfacecCst|jj||��S)N)r	r�r�)r=r�r�rrr r�OszFirewallClient.removeInterfacecCst|jj||��S)N)r	r�r�)r=r�r�rrr r�VszFirewallClient.addSourcecCst|jj||��S)N)r	r��changeZoneOfSource)r=r�r�rrr r�[sz!FirewallClient.changeZoneOfSourcecCst|jj|��S)N)r	r�r�)r=r�rrr r�`szFirewallClient.getSourcescCst|jj||��S)N)r	r�r�)r=r�r�rrr r�eszFirewallClient.querySourcecCst|jj||��S)N)r	r�r�)r=r�r�rrr r�jszFirewallClient.removeSourcecCst|jj|||��S)N)r	r�r�)r=r�r�rrrr r�qszFirewallClient.addRichRulecCst|jj|��S)N)r	r�r�)r=r�rrr r�vszFirewallClient.getRichRulescCst|jj||��S)N)r	r�r�)r=r�r�rrr r�{szFirewallClient.queryRichRulecCst|jj||��S)N)r	r�r�)r=r�r�rrr r��szFirewallClient.removeRichRulecCst|jj|||��S)N)r	r�rb)r=r�rarrrr rb�szFirewallClient.addServicecCst|jj|��S)N)r	r�r])r=r�rrr r]�szFirewallClient.getServicescCst|jj||��S)N)r	r�rf)r=r�rarrr rf�szFirewallClient.queryServicecCst|jj||��S)N)r	r�re)r=r�rarrr re�szFirewallClient.removeServicecCst|jj||||��S)N)r	r�rl)r=r�rjrkrrrr rl�szFirewallClient.addPortcCst|jj|��S)N)r	r�rh)r=r�rrr rh�szFirewallClient.getPortscCst|jj|||��S)N)r	r�rn)r=r�rjrkrrr rn�szFirewallClient.queryPortcCst|jj|||��S)N)r	r�rm)r=r�rjrkrrr rm�szFirewallClient.removePortcCst|jj|||��S)N)r	r�rr)r=r�rkrrrr rr�szFirewallClient.addProtocolcCst|jj|��S)N)r	r�rp)r=r�rrr rp�szFirewallClient.getProtocolscCst|jj||��S)N)r	r�rt)r=r�rkrrr rt�szFirewallClient.queryProtocolcCst|jj||��S)N)r	r�rs)r=r�rkrrr rs�szFirewallClient.removeProtocolcCs|jj|ddi�dS)Nr2T)r�r�)r=r�rrr r��szFirewallClient.addForwardcCst|jj|��dS)Nr2)r	r�r�)r=r�rrr r��szFirewallClient.queryForwardcCs|jj|ddi�dS)Nr2F)r�r�)r=r�rrr r��szFirewallClient.removeForwardcCst|jj||��S)N)r	r�r�)r=r�rrrr r��szFirewallClient.addMasqueradecCst|jj|��S)N)r	r�r�)r=r�rrr r��szFirewallClient.queryMasqueradecCst|jj|��S)N)r	r�r�)r=r�rrr r��szFirewallClient.removeMasqueradecCs2|dkrd}|dkrd}t|jj||||||��S)Nr#)r	r�r�)r=r�rjrkr�r�rrrr r��szFirewallClient.addForwardPortcCst|jj|��S)N)r	r�r�)r=r�rrr r��szFirewallClient.getForwardPortscCs0|dkrd}|dkrd}t|jj|||||��S)Nr#)r	r�r�)r=r�rjrkr�r�rrr r��s
zFirewallClient.queryForwardPortcCs0|dkrd}|dkrd}t|jj|||||��S)Nr#)r	r�r�)r=r�rjrkr�r�rrr r�s
z FirewallClient.removeForwardPortcCst|jj||||��S)N)r	r�rx)r=r�rjrkrrrr rxszFirewallClient.addSourcePortcCst|jj|��S)N)r	r�rv)r=r�rrr rvszFirewallClient.getSourcePortscCst|jj|||��S)N)r	r�rz)r=r�rjrkrrr rzszFirewallClient.querySourcePortcCst|jj|||��S)N)r	r�ry)r=r�rjrkrrr ry$szFirewallClient.removeSourcePortcCst|jj|||��S)N)r	r�r�)r=r��icmprrrr r�,szFirewallClient.addIcmpBlockcCst|jj|��S)N)r	r�r|)r=r�rrr r|1szFirewallClient.getIcmpBlockscCst|jj||��S)N)r	r�r�)r=r�r�rrr r�6szFirewallClient.queryIcmpBlockcCst|jj||��S)N)r	r�r�)r=r�r�rrr r�;szFirewallClient.removeIcmpBlockcCst|jj|��S)N)r	r�r�)r=r�rrr r�Bsz$FirewallClient.addIcmpBlockInversioncCst|jj|��S)N)r	r�r�)r=r�rrr r�Gsz&FirewallClient.queryIcmpBlockInversioncCst|jj|��S)N)r	r�r�)r=r�rrr r�Lsz'FirewallClient.removeIcmpBlockInversioncCs|jj|||�dS)N)r�rq)r=r(rlrorrr rqSszFirewallClient.addChaincCs|jj|||�dS)N)r�rr)r=r(rlrorrr rrXszFirewallClient.removeChaincCst|jj|||��S)N)r	r�rs)r=r(rlrorrr rs]szFirewallClient.queryChaincCst|jj||��S)N)r	r�rm)r=r(rlrrr rmbszFirewallClient.getChainscCst|jj��S)N)r	r�rk)r=rrr rkgszFirewallClient.getAllChainscCs|jj|||||�dS)N)r�rw)r=r(rlror�rrrr rwnszFirewallClient.addRulecCs|jj|||||�dS)N)r�rx)r=r(rlror�rrrr rxsszFirewallClient.removeRulecCs|jj|||�dS)N)r�ry)r=r(rlrorrr ryxszFirewallClient.removeRulescCst|jj|||||��S)N)r	r�rz)r=r(rlror�rrrr rz}szFirewallClient.queryRulecCst|jj|||��S)N)r	r�ru)r=r(rlrorrr ru�szFirewallClient.getRulescCst|jj��S)N)r	r�rt)r=rrr rt�szFirewallClient.getAllRulescCst|jj||��S)N)r	r��passthrough)r=r(rrrr r��szFirewallClient.passthroughcCst|jj��S)N)r	r�r{)r=rrr r{�sz!FirewallClient.getAllPassthroughscCs|jj�dS)N)r�r})r=rrr r}�sz$FirewallClient.removeAllPassthroughscCst|jj|��S)N)r	r�r~)r=r(rrr r~�szFirewallClient.getPassthroughscCs|jj||�dS)N)r�r)r=r(rrrr r�szFirewallClient.addPassthroughcCs|jj||�dS)N)r�r�)r=r(rrrr r��sz FirewallClient.removePassthroughcCst|jj||��S)N)r	r�r�)r=r(rrrr r��szFirewallClient.queryPassthroughcCs|jj�dS)N)rV�enableLockdown)r=rrr r��szFirewallClient.enableLockdowncCs|jj�dS)N)rV�disableLockdown)r=rrr r��szFirewallClient.disableLockdowncCst|jj��S)N)r	rV�
queryLockdown)r=rrr r��szFirewallClient.queryLockdowncCs|jj|�dS)N)rVrY)r=r<rrr rY�sz*FirewallClient.addLockdownWhitelistCommandcCst|jj��S)N)r	rVr\)r=rrr r\�sz+FirewallClient.getLockdownWhitelistCommandscCst|jj|��S)N)r	rVr[)r=r<rrr r[�sz,FirewallClient.queryLockdownWhitelistCommandcCs|jj|�dS)N)rVrZ)r=r<rrr rZ�sz-FirewallClient.removeLockdownWhitelistCommandcCs|jj|�dS)N)rVr])r=rBrrr r]�sz*FirewallClient.addLockdownWhitelistContextcCst|jj��S)N)r	rVr`)r=rrr r`�sz+FirewallClient.getLockdownWhitelistContextscCst|jj|��S)N)r	rVr_)r=rBrrr r_�sz,FirewallClient.queryLockdownWhitelistContextcCs|jj|�dS)N)rVr^)r=rBrrr r^�sz-FirewallClient.removeLockdownWhitelistContextcCs|jj|�dS)N)rVrg)r=rOrrr rg�sz&FirewallClient.addLockdownWhitelistUidcCst|jj��S)N)r	rVre)r=rrr re�sz'FirewallClient.getLockdownWhitelistUidscCst|jj|��S)N)r	rVri)r=rOrrr ri�sz(FirewallClient.queryLockdownWhitelistUidcCs|jj|�dS)N)rVrh)r=rOrrr rhsz)FirewallClient.removeLockdownWhitelistUidcCs|jj|�dS)N)rVra)r=rHrrr ra
sz'FirewallClient.addLockdownWhitelistUsercCst|jj��S)N)r	rVrd)r=rrr rdsz(FirewallClient.getLockdownWhitelistUserscCst|jj|��S)N)r	rVrc)r=rHrrr rcsz)FirewallClient.queryLockdownWhitelistUsercCs|jj|�dS)N)rVrb)r=rHrrr rbsz*FirewallClient.removeLockdownWhitelistUsercCs|jj�dS)z( Authorize once for all polkit actions. N)r��authorizeAll)r=rrr r�szFirewallClient.authorizeAll)NrT)r)r)r)r)r)r)r)r)�r�r�r�r!r@r�r�r�r�r�r�r�r�r�r�r�rr�r�rr�r�r�r�r�r�r�r�r�r�r�r�r�rrrr r!r�r�r�r�r
r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rbr]rfrerlrhrnrmrrrprtrsr�r�r�r�r�r�r�r�r�r�rxrvrzryr�r|r�r�r�r�r�rqrrrsrmrkrwrxryrzrurtr�r{r}r~rr�r�r�r�r�rYr\r[rZr]r`r_r^rgrerirhrardrcrbr�rrrr r�+s*&0	
r�)4Z
gi.repositoryrr�sysr�Zdbus.mainloop.glibrZ	slip.dbusr�rZfirewallrZfirewall.core.baserrrZfirewall.dbus_utilsr	Zfirewall.functionsr
Zfirewall.core.richrZfirewall.core.ipsetrr
rrZfirewall.errorsrrrrr!�objectr"r�r�r�r�rr"r&r,r/r3r6r9rSrjr�r�r�rrrr �<module>sd
';R8ghyKCzVtbm__pycache__/dbus_utils.cpython-36.pyc000064400000013117150351351710013563 0ustar003

��gJ�@s�dddddddddd	d
gZddlZddlZddlZdd
lmZddlmZejdkZ	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zddd�Zdd�Zddd	�Zdd
�ZdS)�command_of_pid�
pid_of_sender�
uid_of_sender�user_of_uid�context_of_sender�command_of_sender�user_of_sender�dbus_to_python�dbus_signature�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties�N)�minidom)�log�3cCsPy6td|d��}|j�djdd�j�}WdQRXWntk
rJdSX|S)z  Get command for pid from /proc z/proc/%d/cmdline�rr�� N)�open�	readlines�replace�strip�	Exception)�pid�f�cmd�r� /usr/lib/python3.6/dbus_utils.pyr%s&cCsD|jdd�}tj|d�}yt|j|��}Wntk
r>dSX|S)zW Get pid from sender string using 
    org.freedesktop.DBus.GetConnectionUnixProcessID zorg.freedesktop.DBusz/org/freedesktop/DBusN)�
get_object�dbus�	Interface�intZGetConnectionUnixProcessID�
ValueError)�bus�sender�dbus_obj�
dbus_ifacerrrrr.scCsD|jdd�}tj|d�}yt|j|��}Wntk
r>dSX|S)zV Get user id from sender string using 
    org.freedesktop.DBus.GetConnectionUnixUser zorg.freedesktop.DBusz/org/freedesktop/DBusN)rrrr ZGetConnectionUnixUserr!)r"r#r$r%�uidrrrr;scCs,ytj|�}Wntk
r"dSX|dS)z Get user for uid from pwd Nr)�pwd�getpwuidr)r&ZpwsrrrrHs
c
CsP|jdd�}tj|d�}y|j|�}Wntk
r:dSXdjttt|���S)zl Get SELinux context from sender string using 
    org.freedesktop.DBus.GetConnectionSELinuxSecurityContext zorg.freedesktop.DBusz/org/freedesktop/DBusN�)	rrrZ#GetConnectionSELinuxSecurityContextr�join�map�chrr)r"r#r$r%�contextrrrrQscCstt||��S)z  Return command of D-Bus sender )rr)r"r#rrrr_scCstt||��S)N)rr)r"r#rrrrdscCs�|dkr|}�n�t|tj�r(t|�}�n�t|tj�rNtrB|jd�nt|�}�n�trjt|tj�rjt|�}�ndt|tj	�r�t|�}�nLt|tj
�s�t|tj�s�t|tj�s�t|tj
�s�t|tj�s�t|tj�s�t|tj�r�t|�}n�t|tj�r�t|�}n�t|tj��rdd�|D�}n�t|tj��r6tdd�|D��}n�t|tj��rXdd�|j�D�}nvt|t��s�t|t��s�t|t��s�t|t��s�t|t��s�t|t��s�t|t��s�t|t��r�|}ntdt|���|dk	�r�|tk�r�t|t��s�|tk�rt|t��s�|tk�r t|t��s�|tk�r8t|t��s�|tk�rPt|t��s�|tk�rht|t��s�|tk�r�t|t��r�td|t|�|f��|S)	Nzutf-8cSsg|]}t|��qSr)r)�.0�xrrr�
<listcomp>}sz"dbus_to_python.<locals>.<listcomp>cSsg|]}t|��qSr)r)r.r/rrrr0scSsi|]\}}t|�t|��qSr)r)r.�k�vrrr�
<dictcomp>�sz"dbus_to_python.<locals>.<dictcomp>zUnhandled %sz%s is %s, expected %s)�
isinstancer�Boolean�bool�String�PY2�encode�str�
UTF8String�
ObjectPath�Byte�Int16�Int32�Int64�UInt16�UInt32�UInt64r �Double�float�Array�Struct�tuple�
Dictionary�items�bytes�list�dict�	TypeError�repr�type)�objZ
expected_typeZ
python_objrrrrgsV


cCs>t|tj�rdSt|tj�r dSt|tj�r0dSt|tj�r@dSt|tj�rPdSt|tj�r`dSt|tj�rpdSt|tj	�r�dSt|tj
�r�d	St|tj�r�d
St|tj�r�dSt|tj
��r�t|j�dkr�d
|jSd|jSnXt|tj��r�d|jSt|tj��rd|jSt�r*t|tj��r*dStdt|���dS)N�b�s�o�y�n�ir/�q�u�t�d�za(%s)za%sz(%s)za{%s}zUnhandled %s)r4rr5r7r<r=r>r?r@rArBrCrDrF�lenZ	signaturerGrIr8r;rNrO)rQrrrr	�sB


cCs�|dkri}t|d�s"t|di�t|d�}i||<y|j|�}Wntk
rZi}YnXxV|j�D]J\}}dt|�i|||<||kr�|||||d<qfd|||d<qfWdS)N�_fw_dbus_propertiesrP�access�read)�hasattr�setattr�getattrZGetAllrrJr	)rQ�	interfacer_�dipZ_dict�key�valuerrrr
�s


c
Cs�tj|�}t|d�r�x�|jd�D]�}|jd�r |jd�|kr i}t|d�rTt|d�}||kr xX||j�D]H\}}|jd�}|j	d|�|j	d|d�|j	d|d�|j
|�qjWq Wtj|j
��|j
�}	|j�|	S)Nr^rd�name�propertyrPr_)r
ZparseStringraZgetElementsByTagNameZhasAttributeZgetAttributercrJZ
createElementZsetAttributeZappendChildrZdebug10Ztoxml�unlink)
rQ�datard�docZnodererfrgZpropZnew_datarrrr�s&





)N)N)�__all__rr'�sysZxml.domr
Zfirewall.core.loggerr�versionr8rrrrrrrrr	r
rrrrr�<module>s*
	

	
0%
__pycache__/command.cpython-36.pyc000064400000043416150351351710013031 0ustar003

��g�^�@sfdZdgZddlZddlmZddlmZddlmZddl	m
Z
mZmZm
Z
mZGdd�de�ZdS)	z<FirewallCommand class for command line client simplification�FirewallCommand�N)�errors)�
FirewallError)�
DBusException)�checkIPnMask�
checkIP6nMask�	check_mac�
check_port�check_single_addressc@s�eZdZd\dd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Zd]dd�Z	d^dd�Z
d_dd�Zd`dd�Zdadd�Z
dbdd�Zdcdd�Zdddd�Zded d!�Zdfd"d#�Zdgd$d%�Zdhd&d'�Zdid(d)�Zdjd*d+�Zdkd,d-�Zd.d/�Zdld1d2�Zdmd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Zd=d>�Zd?d@�Z dgdAfdBdC�Z!dgfdDdE�Z"dgfdFdG�Z#dHdI�Z$dJdK�Z%dLdM�Z&dNdO�Z'dPdQ�Z(dRdS�Z)dTdU�Z*dVdW�Z+dXdY�Z,dZd[�Z-dS)nrFcCs||_||_d|_d|_dS)NT)�quiet�verbose�'_FirewallCommand__use_exception_handler�fw)�selfrr�r�/usr/lib/python3.6/command.py�__init__#szFirewallCommand.__init__cCs
||_dS)N)r)rrrrr�set_fw)szFirewallCommand.set_fwcCs
||_dS)N)r)r�flagrrr�	set_quiet,szFirewallCommand.set_quietcCs|jS)N)r)rrrr�	get_quiet/szFirewallCommand.get_quietcCs
||_dS)N)r)rrrrr�set_verbose2szFirewallCommand.set_verbosecCs|jS)N)r)rrrr�get_verbose5szFirewallCommand.get_verboseNcCs$|dk	r |jr tjj|d�dS)N�
)r�sys�stdout�write)r�msgrrr�	print_msg8szFirewallCommand.print_msgcCs$|dk	r |jr tjj|d�dS)Nr)rr�stderrr)rrrrr�print_error_msg<szFirewallCommand.print_error_msgcCs,d}d}tjj�r|||}|j|�dS)Nzz)rr�isattyr )rrZFAILZENDrrr�
print_warning@s

zFirewallCommand.print_warningrcCs,|dkr|j|�n
|j|�tj|�dS)N�)r"rr�exit)rrZ	exit_coderrr�print_and_exitGs
zFirewallCommand.print_and_exitcCs|j|d�dS)N�)r%)rrrrr�failRszFirewallCommand.failcCs"|dk	r|jrtjj|d�dS)Nr)rrrr)rrrrr�print_if_verboseUsz FirewallCommand.print_if_verbosec
Cs�|jdk	r|jj�g}
d}g}x�|D]�}
|dk	r�y||
�}
Wnxtk
r�}z\tjt|��}t|�dkrz|jd|�n|jd||�||kr�|j	|�|d7}w&WYdd}~XnX|
j	|
�q&W�xb|
D�]X}
g}|dk	r�||7}t
|
t�o�t
|
t��r|j	|
�n||
7}|dk	�r(||7}|j
�y||�Wn�ttfk
�r}z�t
|t��rx|j|j��|j�}nt|�}tj|�}|tjtjtjtjgk�r�d}t|�dk�r�|jd|�n,|dk�r�|jd|�dS|jd||�||k�r|j	|�|d7}WYdd}~XnX|j�q�W|	�s�t|�|k�sJd|k�rNdSt|�dk�rltj|d�nt|�dk�r�tjtj�dS)Nrr#zWarning: %sz	Error: %s)rZauthorizeAll�	Exceptionr�get_code�str�lenr"r%�append�
isinstance�list�tuple�deactivate_exception_handlerr�fail_if_not_authorized�
get_dbus_name�get_dbus_messager�ALREADY_ENABLED�NOT_ENABLED�ZONE_ALREADY_SET�ALREADY_SET�activate_exception_handlerrr$Z
UNKNOWN_ERROR)rZcmd_type�option�
action_method�query_method�parse_method�message�
start_args�end_args�no_exit�itemsZ_errorsZ_error_codes�itemr�code�	call_itemrrrZ__cmd_sequenceYsr










zFirewallCommand.__cmd_sequencec	Cs|jd||||||d�dS)N�add)rA)�_FirewallCommand__cmd_sequence)rr:r;r<r=r>rArrr�add_sequence�szFirewallCommand.add_sequencec
Cs |jd||||||g|d�dS)NrF)r?rA)rG)r�xr:r;r<r=r>rArrr�x_add_sequence�szFirewallCommand.x_add_sequencec		Cs$|jd||||||g|g|d�	dS)NrF)r?r@rA)rG)	r�zoner:r;r<r=r>ZtimeoutrArrr�zone_add_timeout_sequence�sz)FirewallCommand.zone_add_timeout_sequencec	Cs|jd||||||d�dS)N�remove)rA)rG)rr:r;r<r=r>rArrr�remove_sequence�szFirewallCommand.remove_sequencec
Cs |jd||||||g|d�dS)NrM)r?rA)rG)rrIr:r;r<r=r>rArrr�x_remove_sequence�sz!FirewallCommand.x_remove_sequencec
Csg}x�|D]�}|dk	r�y||�}Wn^tk
r�}	zBt|�dkrR|jd|	�w
ntjt|	��}
|jd|	|
�WYdd}	~	XnX|j|�q
W�xv|D�]l}g}|dk	r�||7}t|t	�r�t|t
�r�|j|�n||7}|j�y||�}Wn�tk
�rj}	zZ|j
|	j��tj|	j��}
t|�dk�rF|jd|	j��w�n|jd|	j�|
�WYdd}	~	Xn`tk
�r�}	zBtjt|	��}
t|�dk�r�|jd|	�n|jd|	|
�WYdd}	~	XnX|j�t|�dk�r�|jd||d|f�q�|j|�q�W|�stjd�dS)	Nr#zWarning: %sz	Error: %sz%s: %s�no�yesr)rPrQ)r)r,r"rr*r+r%r-r.r/r0r1rr2r3r4r9r�print_query_resultrr$)
rr:r<r=r>r?rArBrCrrDrE�resrrrZ__query_sequence�sR
""z FirewallCommand.__query_sequencecCs|j|||||d�dS)N)rA)� _FirewallCommand__query_sequence)rr:r<r=r>rArrr�query_sequence�s
zFirewallCommand.query_sequencecCs|j|||||g|d�dS)N)r?rA)rT)rrIr:r<r=r>rArrr�x_query_sequence�s
z FirewallCommand.x_query_sequencecCsJt|�rFt|�rFt|�rF|jd�o2t|�dkrFttjd|��|S)Nzipset:�z8'%s' is no valid IPv4, IPv6 or MAC address, nor an ipset)rrr�
startswithr,rr�INVALID_ADDR)r�valuerrr�parse_source�s

zFirewallCommand.parse_source�/c
Csly|j|�\}}Wn$tk
r6ttjd|��YnXt|�sLttj|��|dkrdttjd|��||fS)NzTbad port (most likely missing protocol), correct syntax is portid[-portid]%sprotocol�tcp�udp�sctp�dccpz''%s' not in {'tcp'|'udp'|'sctp'|'dccp'})r]r^r_r`)�split�
ValueErrorrr�INVALID_PORTr	�INVALID_PROTOCOL)rrZZ	separator�port�protorrr�
parse_portszFirewallCommand.parse_portc
Cs�d}d}d}d}d}x�d||d�kr�||d�jdd�d}|t|�d7}d||d�krx||d�jdd�d}	n||d�}	|t|	�d7}|dkr�|	}q|dkr�|	}q|dkr�|	}q|dkr�|	}q|d	kr�|r�qttjd
|��qW|�sttjd��|�sttjd��|�p|�s*ttjd
��t|��s@ttj|��|dk�rZttjd|��|�rxt|��rxttj|��|�r�td|��r�|�s�td|��r�ttj	|��||||fS)Nr�=r#�:rerf�toport�toaddr�ifzinvalid forward port arg '%s'zmissing portzmissing protocolzmissing destinationr]r^r_r`z''%s' not in {'tcp'|'udp'|'sctp'|'dccp'}�ipv4�ipv6)r]r^r_r`)
rar,rrZINVALID_FORWARDr	rcrdr
rY)
rrZ�compatreZprotocolrjrk�i�opt�valrrr�parse_forward_portsT

z"FirewallCommand.parse_forward_portcCsF|jd�}t|�dkr"|ddfSt|�dkr2|Sttjd|��dS)Nrhr#r�r&zinvalid ipset option '%s')rar,rrZINVALID_OPTION)rrZ�argsrrr�parse_ipset_optionHs
z"FirewallCommand.parse_ipset_optioncCs.ddg}||kr*ttjd|dj|�f��|S)Nrmrnz'invalid argument: %s (choose from '%s')z', ')rr�INVALID_IPV�join)rrZ�ipvsrrr�check_destination_ipvRsz%FirewallCommand.check_destination_ipvcCsDy|jdd�\}}Wn tk
r4ttjd��YnX|j|�|fS)Nrir#z(destination syntax is ipv:address[/mask])rarbrrZINVALID_DESTINATIONrz)rrZZipvZdestinationrrr�parse_service_destinationZsz)FirewallCommand.parse_service_destinationcCs0dddg}||kr,ttjd|dj|�f��|S)NrmrnZebz'invalid argument: %s (choose from '%s')z', ')rrrwrx)rrZryrrr�	check_ipvbs
zFirewallCommand.check_ipvcCs0dddg}||kr,ttjd|dj|�f��|S)Nrtrmrnz'invalid argument: %s (choose from '%s')z', ')rrrwrx)rrZryrrr�check_helper_familyjs
z#FirewallCommand.check_helper_familycCsB|jd�sttjd|��t|jdd��dkr>ttjd|��|S)NZ
nf_conntrack_z('%s' does not start with 'nf_conntrack_'rtr#zModule name '%s' too short)rXrrZINVALID_MODULEr,�replace)rrZrrr�check_modulers


zFirewallCommand.check_moduleTcCs�|j�}|j�}|j�}|j�}	|j�}
|j�}|j�}|j�}
|j�}|j	�}|j
�}|rv|j�}|j�}|j
�}n,|j�}tt|j�|��}|j�}|j�}dd�}g}|dk	r�||kr�|jd�|r�|s�|s�|r�|r�|r�|jd�|�r|ddj|�}|j|�|j�r2|jd|�|jd|�|�rJ|jd	t|��|jd
|�|�sv|jd|�rndnd
�|�r�|jddj|��|jddj|��n(|jddj|��|jddj|��|jddjt|���|jddjdd�|D���|jddjt|	���|�s:|jd|�r2dnd
�|jd|
�rJdnd
�|jd|�rbdnddjdd�|D���|jddjdd�|D���|jd dj|
��|jd!|�r�dnddjt||d"���dS)#NcSsfd}d}y|j|�}Wntk
r*Yn8X|t|�7}t|||||d�jd��jdd��}|S)Nrz	priority=� �"rt)�indexrbr,�intr~)Zrule�priorityZ
search_strrprrr�rich_rule_sorted_key�s*zDFirewallCommand.print_zone_policy_info.<locals>.rich_rule_sorted_key�defaultZactivez (%s)z, z  summary: z  description: z  priority: z
  target: z  icmp-block-inversion: %srQrPz  ingress-zones: r�z  egress-zones: z  interfaces: z  sources: z  services: z	  ports: cSs g|]}d|d|df�qS)z%s/%srr#r)�.0rerrr�
<listcomp>�sz:FirewallCommand.print_zone_policy_info.<locals>.<listcomp>z
  protocols: z
  forward: %sz  masquerade: %sz  forward-ports: z
	rtcSs$g|]\}}}}d||||f�qS)z$port=%s:proto=%s:toport=%s:toaddr=%sr)r�rerfrjrkrrrr��sz  source-ports: cSs g|]}d|d|df�qS)z%s/%srr#r)r�rerrrr��sz  icmp-blocks: z  rich rules: )�key)Z	getTargetZgetServices�getPorts�getProtocolsZ
getMasqueradeZgetForwardPorts�getSourcePortsZ
getIcmpBlocksZgetRichRules�getDescription�getShortZgetIngressZonesZgetEgressZonesZgetPriorityZgetIcmpBlockInversion�sorted�setZ
getInterfacesZ
getSourcesZ
getForwardr-rxrrr+)rrK�settings�default_zone�extra_interfaces�isPolicy�targetZservices�ports�	protocolsZ
masqueradeZ
forward_ports�source_portsZicmp_blocksZrules�description�short_descriptionZ
ingress_zonesZegress_zonesr�Zicmp_block_inversionZ
interfacesZsourcesZforwardr�Z
attributesrrr�print_zone_policy_info|sx






z&FirewallCommand.print_zone_policy_infocCs|j||||dd�dS)NF)r�r�r�)r�)rrKr�r�r�rrr�print_zone_info�szFirewallCommand.print_zone_infocCs|j||||dd�dS)NT)r�r�r�)r�)rZpolicyr�r�r�rrr�print_policy_info�sz!FirewallCommand.print_policy_infocCs.|j�}|j�}|j�}|j�}|j�}|j�}|j�}	|j�}
|j�}|j	|�|j
rt|j	d|	�|j	d|�|j	ddjdd�|D���|j	ddj|��|j	ddjd	d�|D���|j	d
dj|��|j	ddjdd�|j�D���|j	d
djt
|
���|j	ddjt
|���dS)Nz  summary: z  description: z	  ports: r�cSs g|]}d|d|df�qS)z%s/%srr#r)r�rerrrr��sz6FirewallCommand.print_service_info.<locals>.<listcomp>z
  protocols: z  source-ports: cSs g|]}d|d|df�qS)z%s/%srr#r)r�rerrrr��sz  modules: z  destination: cSsg|]\}}d||f�qS)z%s:%sr)r��k�vrrrr��sz  includes: z  helpers: )r�r�r�Z
getModulesr��getDestinationsr�ZgetIncludesZ
getHelpersrrrxrBr�)rZservicer�r�r�r��modulesr��destinationsr�ZincludesZhelpersrrr�print_service_info�s2


z"FirewallCommand.print_service_infocCsp|j�}|j�}|j�}t|�dkr,ddg}|j|�|jrX|jd|�|jd|�|jddj|��dS)Nrrmrnz  summary: z  description: z  destination: r�)r�r�r�r,rrrx)rZicmptyper�r�r�r�rrr�print_icmptype_info�s
z#FirewallCommand.print_icmptype_infocCs�|j�}|j�}|j�}|j�}|j�}|j|�|jrT|jd|�|jd|�|jd|�|jddjdd�|j�D���|jddj|��dS)	Nz  summary: z  description: z  type: z  options: r�cSs$g|]\}}|rd||fn|�qS)z%s=%sr)r�r�r�rrrr�sz4FirewallCommand.print_ipset_info.<locals>.<listcomp>z  entries: )	ZgetTypeZ
getOptionsZ
getEntriesr�r�rrrxrB)rZipsetr�Z
ipset_typeZoptions�entriesr�r�rrr�print_ipset_info�s
z FirewallCommand.print_ipset_infocCs�|j�}|j�}|j�}|j�}|j�}|j|�|jrT|jd|�|jd|�|jd|�|jd|�|jddjdd�|D���dS)	Nz  summary: z  description: z
  family: z
  module: z	  ports: r�cSs g|]}d|d|df�qS)z%s/%srr#r)r�rerrrr�sz5FirewallCommand.print_helper_info.<locals>.<listcomp>)r�Z	getModuleZ	getFamilyr�r�rrrx)r�helperr�r��moduleZfamilyr�r�rrr�print_helper_infos
z!FirewallCommand.print_helper_infocCs |r|jd�n|jdd�dS)NrQrPr#)r%)rrZrrrrRsz"FirewallCommand.print_query_resultcCs\|js�|j|�tjt|��}|tjtjtjtj	gkrH|j
d|�n|jd||�dS)NzWarning: %sz	Error: %s)r
r2rr*r+rr5r6r7r8r"r%)r�exception_messagerDrrr�exception_handlers

z!FirewallCommand.exception_handlercCsd|krd}|j|tj�dS)NZNotAuthorizedExceptionz`Authorization failed.
    Make sure polkit agent is running or run the application as superuser.)r%rZNOT_AUTHORIZED)rr�rrrrr2'sz&FirewallCommand.fail_if_not_authorizedcCs
d|_dS)NF)r
)rrrrr1-sz,FirewallCommand.deactivate_exception_handlercCs
d|_dS)NT)r
)rrrrr90sz*FirewallCommand.activate_exception_handlercCspg}t�}t|�}xP|D]H}|s"P|j�}t|�dks|ddkrDq||kr|j|�|j|�qW|j�|S)Nr#r�#�;)r�r�)r��open�stripr,r-rF�close)r�filenamer�Zentries_set�f�linerrr�get_ipset_entries_from_file3s

z+FirewallCommand.get_ipset_entries_from_file)FF)N)N)N)Nr)N)N)NNF)F)F)F)F)F)NF)F)F)r\)F).�__name__�
__module__�__qualname__rrrrrrrr r"r%r'r(rGrHrJrLrNrOrTrUrVr[rgrsrvrzr{r|r}rr�r�r�r�r�r�r�rRr�r2r1r9r�rrrrr"sX







J





2



2

O)�__doc__�__all__rZfirewallrZfirewall.errorsrZdbus.exceptionsrZfirewall.functionsrrrr	r
�objectrrrrr�<module>s__pycache__/functions.cpython-36.pyc000064400000036460150351351710013424 0ustar003

��g'K�#@sdddddddddd	d
ddd
ddddddddddddddddddd d!d"g#Zd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d%l	m
Z
d#d&lmZm
Z
ejd'kZd(d)�ed#d*�D�Zd+d�Zd,d�ZdXd.d�Zd/d0�Zd1d2�Zd3d4�Zd5d�Zd6d�Zd7d8�Zd9d�Zd:d�Zd;d"�Zd<d�Zd=d	�Zd>d
�Z d?d�Z!d@d�Z"dAd
�Z#dBd�Z$dCd�Z%dDd�Z&dEdF�Z'dGd�Z(dHd�Z)dId�Z*dJd�Z+dKd�Z,dLd�Z-dMd!�Z.dNd�Z/dOd�Z0dPd�Z1dQd�Z2dRd�Z3dSd�Z4dTd�Z5dUd�Z6dVd�Z7dWd �Z8d$S)Y�PY2�	getPortID�getPortRange�portStr�getServiceName�checkIP�checkIP6�checkIPnMask�
checkIP6nMask�
checkProtocol�checkInterface�checkUINT32�firewalld_is_active�tempFile�readfile�	writefile�enable_ip_forwarding�
check_port�
check_address�check_single_address�	check_mac�uniqify�ppid_of_pid�max_zone_name_len�	checkUser�checkUid�checkCommand�checkContext�joinArgs�	splitArgs�b2u�u2b�
u2b_if_py2�max_policy_name_len�stripNonPrintableCharacters�N)�log)�FIREWALLD_TEMPDIR�FIREWALLD_PIDFILE�3cCs"i|]}|dko|dksd|�qS)��N�)�.0�ir+r+�/usr/lib/python3.6/functions.py�
<dictcomp>.sr/�cCstt|t�r|}nT|r|j�}yt|�}Wn:tk
rbytj|�}Wntjk
r\dSXYnX|dkrpdS|S)z� Check and Get port id from port string or port id using socket.getservbyname

    @param port port string or port id
    @return Port id if valid, -1 if port can not be found and -2 if port is too big
    �i���������)�
isinstance�int�strip�
ValueError�socketZ
getservbyname�error)�portZ_idr+r+r.r7s
cCs�t|t�st|t�r|St|t�s*|j�rDt|�}|dkr@|fS|S|jd�}t|�dkr�|dj�r�|dj�r�t|d�}t|d�}|dkr�|dkr�||kr�||fS||kr�||fS|fSg}x�tt|�dd�D]�}tdj	|d|���}dj	||d��}t|�dk�rnt|�}|dk�r�|dk�r�||k�rF|j
||f�n&||k�r`|j
||f�n|j
|f�q�|dkr�|j
|f�|t|�kr�Pq�Wt|�dk�r�dSt|�dk�r�dS|dS)aI Get port range for port range string or single port id

    @param ports an integer or port string or port range string
    @return Array containing start and end port id for a valid range or -1 if port can not be found and -2 if port is too big for integer input or -1 for invalid ranges or None if the range is ambiguous.
    r$�-r2r1Nr3r3)r5�tuple�listr6�isdigitr�split�len�range�join�append)ZportsZid1�splitsZid2Zmatchedr-Zport2r+r+r.rNsL
$

�:cCsX|dkrdSt|�}t|t�r*|dkr*dSt|�dkr>d|Sd|d||dfSdS)a Create port and port range string

    @param port port or port range int or [int, int]
    @param delimiter of the output string for port ranges, default ':'
    @return Port or port range string, empty string if port isn't specified, None if port or port range is not valid
    �r$Nr1z%sz%s%s%s)rr5r6rA)r;Z	delimiter�_ranger+r+r.r�scCst|�}t|�}t|�dkr�t|�dkr@t|d�t|d�kSt|�dkr�t|d�t|d�kr�t|d�t|d�kr�dSn|t|�dkr�t|�dkr�t|d�t|d�kr�t|d�t|d�kr�t|d�t|d�kr�t|d�t|d�kr�dSdS)Nr1r$r2TF)rrAr)r;rBZ_portrHr+r+r.�portInPortRange�s000rIcCsTt|�}t|�dkr$|d|df}tt|�}ttdd�|�dd�d�}g}x�|D]�}|d|dkr�|d|dkr�|j|�qR|d|dkr�|d|dkr�|d|dkr�|j|�|d|df}qR|d|dko�|d|dko�|d|dkrR|j|�|d|df}qRWttdd�|��}|d|dk�rJ|df}|g|fS)z� Coalesce a port range with existing list of port ranges

        @param new_range tuple/list/string
        @param ranges list of tuple/list/string
        @return tuple of (list of ranges added after coalescing, list of removed original ranges)
    r1r$cSs t|�dkr|d|dfS|S)Nr1r$)rA)�xr+r+r.�<lambda>�sz#coalescePortRange.<locals>.<lambda>cSs|dS)Nr$r+)rJr+r+r.rK�s)�keycSs|d|dkr|dfS|S)Nr$r1r+)rJr+r+r.rK�s)rrA�map�sortedrDr>)Z	new_range�rangesZcoalesced_range�_ranges�removed_rangesrBr+r+r.�coalescePortRange�s*

  
 

rRcCs�t|�}t|�dkr$|d|df}tt|�}ttdd�|�dd�d�}g}g}�xJ|D�]@}|d|dkr�|d|dkr�|j|�qX|d|dkr�|d|dkr�|d|dkr�|j|�|j|dd|df�qX|d|dk�r<|d|dk�r<|d|dk�r<|j|�|j|d|ddf�qX|d|dkrX|d|dkrX|j|�|j|d|ddf�|j|dd|df�qXWttdd�|��}ttdd�|��}||fS)	z� break a port range from existing list of port ranges

        @param remove_range tuple/list/string
        @param ranges list of tuple/list/string
        @return tuple of (list of ranges added after breaking up, list of removed original ranges)
    r1r$cSs t|�dkr|d|dfS|S)Nr1r$)rA)rJr+r+r.rK�sz breakPortRange.<locals>.<lambda>cSs|dS)Nr$r+)rJr+r+r.rK�s)rLcSs|d|dkr|dfS|S)Nr$r1r+)rJr+r+r.rK�scSs|d|dkr|dfS|S)Nr$r1r+)rJr+r+r.rK�s)rrArMrNrDr>)Zremove_rangerOrPrQZadded_rangesrBr+r+r.�breakPortRange�s2
  
$
 
rScCs0ytjt|�|�}Wntjk
r*dSX|S)z� Check and Get service name from port and proto string combination using socket.getservbyport

    @param port string or id
    @param protocol string
    @return Service name if port and protocol are valid, else None
    N)r9Z
getservbyportr6r:)r;�proto�namer+r+r.r�s
cCs.ytjtj|�Wntjk
r(dSXdS)zl Check IPv4 address.
    
    @param ip address string
    @return True if address is valid, else False
    FT)r9�	inet_ptonZAF_INETr:)�ipr+r+r.rs
cCs
|jd�S)z� Normalize the IPv6 address

    This is mostly about converting URL-like IPv6 address to normal ones.
    e.g. [1234::4321] --> 1234:4321
    z[])r7)rWr+r+r.�normalizeIP6srXcCs2ytjtjt|��Wntjk
r,dSXdS)zl Check IPv6 address.
    
    @param ip address string
    @return True if address is valid, else False
    FT)r9rVZAF_INET6rXr:)rWr+r+r.r s
cCs�d|krN|d|jd��}||jd�dd�}t|�dksHt|�dkrVdSn|}d}t|�sbdS|r�d|krvt|�Syt|�}Wntk
r�dSX|dks�|dkr�dSdS)N�/r1F�.r$� T)�indexrArr6r8)rW�addr�maskr-r+r+r.r-s&cCs
|jt�S)N)�	translate�NOPRINT_TRANS_TABLE)Zrule_strr+r+r.r#DscCs�d|krN|d|jd��}||jd�dd�}t|�dksHt|�dkrVdSn|}d}t|�sbdS|r�yt|�}Wntk
r�dSX|dks�|dkr�dSdS)NrYr1Fr$�T)r\rArr6r8)rWr]r^r-r+r+r.r	Gs"cCs`yt|�}Wn:tk
rFytj|�Wntjk
r@dSXYnX|dksX|dkr\dSdS)NFr$�T)r6r8r9Zgetprotobynamer:)Zprotocolr-r+r+r.r
\scCs4|st|�dkrdSxdD]}||krdSqWdS)	z� Check interface string

    @param interface string
    @return True if interface is valid (maximum 16 chars and does not contain ' ', '/', '!', ':', '*'), else False
    �F� rY�!�*T)rdrYrerf)rA)Ziface�chr+r+r.rks
cCs<yt|d�}Wntk
r"dSX|dkr8|dkr8dSdS)Nr$Fl��T)r6r8)�valrJr+r+r.r~scCs�tjjt�sdSy"ttd��}|j�}WdQRXWntk
rFdSXtjjd|�s\dSy&td|d��}|j�}WdQRXWntk
r�dSXd|kr�dSdS)zv Check if firewalld is active

    @return True if there is a firewalld pid file and the pid is used by firewalld
    F�rNz/proc/%sz/proc/%s/cmdlineZ	firewalldT)�os�path�existsr'�open�readline�	Exception)�fd�pidZcmdliner+r+r.r
�s"cCsby*tjjt�stjtd�tjddtdd�Stk
r\}ztj	d|��WYdd}~XnXdS)Ni�Zwtztemp.F)�mode�prefix�dir�deletez#Failed to create temporary file: %s)
rjrkrlr&�mkdir�tempfileZNamedTemporaryFileror%r:)�msgr+r+r.r�s
cCsXyt|d��
}|j�SQRXWn4tk
rR}ztjd||f�WYdd}~XnXdS)NrizFailed to read file "%s": %s)rm�	readlinesror%r:)�filename�f�er+r+r.r�s$cCs\y$t|d��}|j|�WdQRXWn2tk
rV}ztjd||f�dSd}~XnXdS)N�wz Failed to write to file "%s": %sFT)rm�writeror%r:)rz�liner{r|r+r+r.r�scCs(|dkrtdd�S|dkr$tdd�SdS)N�ipv4z/proc/sys/net/ipv4/ip_forwardz1
�ipv6z&/proc/sys/net/ipv6/conf/all/forwardingF)r)�ipvr+r+r.r�s


cCs|jdd�jdd�S)N�_r<z
nf-conntrack-rG)�replace)�moduler+r+r.�get_nf_conntrack_short_name�sr�cCs�t|�}|d
ks<|dks<|dks<t|�dkr�|d|dkr�|dkrTtjd|�nZ|d
krltjd|�nB|dkr�tjd|�n*t|�dkr�|d|dkr�tjd|�dSd	S)Nr2r1r$z'%s': port > 65535z'%s': port is invalidz'%s': port is ambiguousz'%s': range start >= endFTr4r3r4r3)rrAr%Zdebug2)r;rHr+r+r.r�scCs(|dkrt|�S|dkr t|�SdSdS)Nr�r�F)rr	)r��sourcer+r+r.r�s
cCs(|dkrt|�S|dkr t|�SdSdS)Nr�r�F)rr)r�r�r+r+r.r�s
cCsRt|�dkrNxdD]}||dkrdSqWxdD]}||tjkr0dSq0WdSdS)N��r2���rFFr$r1�����	�
�
�rcT�)r2r�r�r�r�)r$r1r�r�r�r�r�r�r�r�r�rc)rA�stringZ	hexdigits)Zmacr-r+r+r.r�s

cCs(g}x|D]}||kr
|j|�q
W|S)N)rD)Z_list�outputrJr+r+r.r�s

cCsHy.tjd|�}t|j�dj��}|j�Wntk
rBdSX|S)z Get parent for pid zps -o ppid -h -p %d 2>/dev/nullr$N)rj�popenr6ryr7�closero)rqr{r+r+r.r�scCsBddlm}ddlm}ttt|j���}d|t|�td�S)z�
    iptables limits length of chain to (currently) 28 chars.
    The longest chain we create is POST_<policy>_allow,
    which leaves 28 - 11 = 17 chars for <policy>.
    r$)�POLICY_CHAIN_PREFIX)�	SHORTCUTS�Z_allow)Zfirewall.core.ipXtablesr��firewall.core.baser��maxrMrA�values)r�r��longest_shortcutr+r+r.r"	scCs.ddlm}ttt|j���}d|td�S)z�
    Netfilter limits length of chain to (currently) 28 chars.
    The longest chain we create is FWDI_<zone>_allow,
    which leaves 28 - 11 = 17 chars for <zone>.
    r$)r�r�Z__allow)r�r�r�rMrAr�)r�r�r+r+r.rscCsTt|�dkst|�tjd�kr"dSx,|D]$}|tjkr(|tjkr(|d	kr(dSq(WdS)
Nr1�SC_LOGIN_NAME_MAXFrZr<r��$T)rZr<r�r�)rArj�sysconfr�Z
ascii_lettersZdigits)�user�cr+r+r.rs


cCsDt|t�r,yt|�}Wntk
r*dSX|dkr@|dkr@dSdS)	NFr$r2r)r1Tli���)r5�strr6r8)Zuidr+r+r.r(s
cCsJt|�dkst|�dkrdSxd
D]}||kr"dSq"W|ddkrFdSd	S)Nr1iF�|�
�r$rYT)r�r�r�)rA)Zcommandrgr+r+r.r2s
cCs�|jd�}t|�dkrdS|ddkr>|ddd�dkr>dS|d	dd�d
krVdS|ddd�dkrndSt|d�d	kr�dSd
S)NrFr�r�Fr$�rootr2Z_ur1Z_rZ_tr�T)r�r�r4r4r4)r@rA)�contextrEr+r+r.r<s
 cCs8dtt�kr djdd�|D��Sdjdd�|D��SdS)N�quoterdcss|]}tj|�VqdS)N)�shlexr�)r,�ar+r+r.�	<genexpr>PszjoinArgs.<locals>.<genexpr>css|]}tj|�VqdS)N)�pipesr�)r,r�r+r+r.r�Rs)rtr�rC)�argsr+r+r.rNscCs8tr*t|t�r*t|�}tj|�}tt|�Stj|�SdS)N)rr5�unicoder r�r@rMr)�_stringrEr+r+r.rTs


cCst|t�r|jdd�S|S)z bytes to unicode zUTF-8r�)r5�bytes�decode)r�r+r+r.r]s
cCst|t�s|jdd�S|S)z unicode to bytes zUTF-8r�)r5r��encode)r�r+r+r.r cs
cCstrt|t�r|jdd�S|S)z" unicode to bytes only if Python 2zUTF-8r�)rr5r�r�)r�r+r+r.r!is)rF)9�__all__r9rjZos.pathr�r�r��sysrwZfirewall.core.loggerr%Zfirewall.configr&r'�versionrrBr`rrrrIrRrSrrrXrrr#r	r
rrr
rrrrr�rrrrrrr"rrrrrrrrr r!r+r+r+r.�<module>sz

:
&+


	




	__pycache__/command.cpython-36.opt-1.pyc000064400000043416150351351710013770 0ustar003

��g�^�@sfdZdgZddlZddlmZddlmZddlmZddl	m
Z
mZmZm
Z
mZGdd�de�ZdS)	z<FirewallCommand class for command line client simplification�FirewallCommand�N)�errors)�
FirewallError)�
DBusException)�checkIPnMask�
checkIP6nMask�	check_mac�
check_port�check_single_addressc@s�eZdZd\dd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Zd]dd�Z	d^dd�Z
d_dd�Zd`dd�Zdadd�Z
dbdd�Zdcdd�Zdddd�Zded d!�Zdfd"d#�Zdgd$d%�Zdhd&d'�Zdid(d)�Zdjd*d+�Zdkd,d-�Zd.d/�Zdld1d2�Zdmd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Zd=d>�Zd?d@�Z dgdAfdBdC�Z!dgfdDdE�Z"dgfdFdG�Z#dHdI�Z$dJdK�Z%dLdM�Z&dNdO�Z'dPdQ�Z(dRdS�Z)dTdU�Z*dVdW�Z+dXdY�Z,dZd[�Z-dS)nrFcCs||_||_d|_d|_dS)NT)�quiet�verbose�'_FirewallCommand__use_exception_handler�fw)�selfrr�r�/usr/lib/python3.6/command.py�__init__#szFirewallCommand.__init__cCs
||_dS)N)r)rrrrr�set_fw)szFirewallCommand.set_fwcCs
||_dS)N)r)r�flagrrr�	set_quiet,szFirewallCommand.set_quietcCs|jS)N)r)rrrr�	get_quiet/szFirewallCommand.get_quietcCs
||_dS)N)r)rrrrr�set_verbose2szFirewallCommand.set_verbosecCs|jS)N)r)rrrr�get_verbose5szFirewallCommand.get_verboseNcCs$|dk	r |jr tjj|d�dS)N�
)r�sys�stdout�write)r�msgrrr�	print_msg8szFirewallCommand.print_msgcCs$|dk	r |jr tjj|d�dS)Nr)rr�stderrr)rrrrr�print_error_msg<szFirewallCommand.print_error_msgcCs,d}d}tjj�r|||}|j|�dS)Nzz)rr�isattyr )rrZFAILZENDrrr�
print_warning@s

zFirewallCommand.print_warningrcCs,|dkr|j|�n
|j|�tj|�dS)N�)r"rr�exit)rrZ	exit_coderrr�print_and_exitGs
zFirewallCommand.print_and_exitcCs|j|d�dS)N�)r%)rrrrr�failRszFirewallCommand.failcCs"|dk	r|jrtjj|d�dS)Nr)rrrr)rrrrr�print_if_verboseUsz FirewallCommand.print_if_verbosec
Cs�|jdk	r|jj�g}
d}g}x�|D]�}
|dk	r�y||
�}
Wnxtk
r�}z\tjt|��}t|�dkrz|jd|�n|jd||�||kr�|j	|�|d7}w&WYdd}~XnX|
j	|
�q&W�xb|
D�]X}
g}|dk	r�||7}t
|
t�o�t
|
t��r|j	|
�n||
7}|dk	�r(||7}|j
�y||�Wn�ttfk
�r}z�t
|t��rx|j|j��|j�}nt|�}tj|�}|tjtjtjtjgk�r�d}t|�dk�r�|jd|�n,|dk�r�|jd|�dS|jd||�||k�r|j	|�|d7}WYdd}~XnX|j�q�W|	�s�t|�|k�sJd|k�rNdSt|�dk�rltj|d�nt|�dk�r�tjtj�dS)Nrr#zWarning: %sz	Error: %s)rZauthorizeAll�	Exceptionr�get_code�str�lenr"r%�append�
isinstance�list�tuple�deactivate_exception_handlerr�fail_if_not_authorized�
get_dbus_name�get_dbus_messager�ALREADY_ENABLED�NOT_ENABLED�ZONE_ALREADY_SET�ALREADY_SET�activate_exception_handlerrr$Z
UNKNOWN_ERROR)rZcmd_type�option�
action_method�query_method�parse_method�message�
start_args�end_args�no_exit�itemsZ_errorsZ_error_codes�itemr�code�	call_itemrrrZ__cmd_sequenceYsr










zFirewallCommand.__cmd_sequencec	Cs|jd||||||d�dS)N�add)rA)�_FirewallCommand__cmd_sequence)rr:r;r<r=r>rArrr�add_sequence�szFirewallCommand.add_sequencec
Cs |jd||||||g|d�dS)NrF)r?rA)rG)r�xr:r;r<r=r>rArrr�x_add_sequence�szFirewallCommand.x_add_sequencec		Cs$|jd||||||g|g|d�	dS)NrF)r?r@rA)rG)	r�zoner:r;r<r=r>ZtimeoutrArrr�zone_add_timeout_sequence�sz)FirewallCommand.zone_add_timeout_sequencec	Cs|jd||||||d�dS)N�remove)rA)rG)rr:r;r<r=r>rArrr�remove_sequence�szFirewallCommand.remove_sequencec
Cs |jd||||||g|d�dS)NrM)r?rA)rG)rrIr:r;r<r=r>rArrr�x_remove_sequence�sz!FirewallCommand.x_remove_sequencec
Csg}x�|D]�}|dk	r�y||�}Wn^tk
r�}	zBt|�dkrR|jd|	�w
ntjt|	��}
|jd|	|
�WYdd}	~	XnX|j|�q
W�xv|D�]l}g}|dk	r�||7}t|t	�r�t|t
�r�|j|�n||7}|j�y||�}Wn�tk
�rj}	zZ|j
|	j��tj|	j��}
t|�dk�rF|jd|	j��w�n|jd|	j�|
�WYdd}	~	Xn`tk
�r�}	zBtjt|	��}
t|�dk�r�|jd|	�n|jd|	|
�WYdd}	~	XnX|j�t|�dk�r�|jd||d|f�q�|j|�q�W|�stjd�dS)	Nr#zWarning: %sz	Error: %sz%s: %s�no�yesr)rPrQ)r)r,r"rr*r+r%r-r.r/r0r1rr2r3r4r9r�print_query_resultrr$)
rr:r<r=r>r?rArBrCrrDrE�resrrrZ__query_sequence�sR
""z FirewallCommand.__query_sequencecCs|j|||||d�dS)N)rA)� _FirewallCommand__query_sequence)rr:r<r=r>rArrr�query_sequence�s
zFirewallCommand.query_sequencecCs|j|||||g|d�dS)N)r?rA)rT)rrIr:r<r=r>rArrr�x_query_sequence�s
z FirewallCommand.x_query_sequencecCsJt|�rFt|�rFt|�rF|jd�o2t|�dkrFttjd|��|S)Nzipset:�z8'%s' is no valid IPv4, IPv6 or MAC address, nor an ipset)rrr�
startswithr,rr�INVALID_ADDR)r�valuerrr�parse_source�s

zFirewallCommand.parse_source�/c
Csly|j|�\}}Wn$tk
r6ttjd|��YnXt|�sLttj|��|dkrdttjd|��||fS)NzTbad port (most likely missing protocol), correct syntax is portid[-portid]%sprotocol�tcp�udp�sctp�dccpz''%s' not in {'tcp'|'udp'|'sctp'|'dccp'})r]r^r_r`)�split�
ValueErrorrr�INVALID_PORTr	�INVALID_PROTOCOL)rrZZ	separator�port�protorrr�
parse_portszFirewallCommand.parse_portc
Cs�d}d}d}d}d}x�d||d�kr�||d�jdd�d}|t|�d7}d||d�krx||d�jdd�d}	n||d�}	|t|	�d7}|dkr�|	}q|dkr�|	}q|dkr�|	}q|dkr�|	}q|d	kr�|r�qttjd
|��qW|�sttjd��|�sttjd��|�p|�s*ttjd
��t|��s@ttj|��|dk�rZttjd|��|�rxt|��rxttj|��|�r�td|��r�|�s�td|��r�ttj	|��||||fS)Nr�=r#�:rerf�toport�toaddr�ifzinvalid forward port arg '%s'zmissing portzmissing protocolzmissing destinationr]r^r_r`z''%s' not in {'tcp'|'udp'|'sctp'|'dccp'}�ipv4�ipv6)r]r^r_r`)
rar,rrZINVALID_FORWARDr	rcrdr
rY)
rrZ�compatreZprotocolrjrk�i�opt�valrrr�parse_forward_portsT

z"FirewallCommand.parse_forward_portcCsF|jd�}t|�dkr"|ddfSt|�dkr2|Sttjd|��dS)Nrhr#r�r&zinvalid ipset option '%s')rar,rrZINVALID_OPTION)rrZ�argsrrr�parse_ipset_optionHs
z"FirewallCommand.parse_ipset_optioncCs.ddg}||kr*ttjd|dj|�f��|S)Nrmrnz'invalid argument: %s (choose from '%s')z', ')rr�INVALID_IPV�join)rrZ�ipvsrrr�check_destination_ipvRsz%FirewallCommand.check_destination_ipvcCsDy|jdd�\}}Wn tk
r4ttjd��YnX|j|�|fS)Nrir#z(destination syntax is ipv:address[/mask])rarbrrZINVALID_DESTINATIONrz)rrZZipvZdestinationrrr�parse_service_destinationZsz)FirewallCommand.parse_service_destinationcCs0dddg}||kr,ttjd|dj|�f��|S)NrmrnZebz'invalid argument: %s (choose from '%s')z', ')rrrwrx)rrZryrrr�	check_ipvbs
zFirewallCommand.check_ipvcCs0dddg}||kr,ttjd|dj|�f��|S)Nrtrmrnz'invalid argument: %s (choose from '%s')z', ')rrrwrx)rrZryrrr�check_helper_familyjs
z#FirewallCommand.check_helper_familycCsB|jd�sttjd|��t|jdd��dkr>ttjd|��|S)NZ
nf_conntrack_z('%s' does not start with 'nf_conntrack_'rtr#zModule name '%s' too short)rXrrZINVALID_MODULEr,�replace)rrZrrr�check_modulers


zFirewallCommand.check_moduleTcCs�|j�}|j�}|j�}|j�}	|j�}
|j�}|j�}|j�}
|j�}|j	�}|j
�}|rv|j�}|j�}|j
�}n,|j�}tt|j�|��}|j�}|j�}dd�}g}|dk	r�||kr�|jd�|r�|s�|s�|r�|r�|r�|jd�|�r|ddj|�}|j|�|j�r2|jd|�|jd|�|�rJ|jd	t|��|jd
|�|�sv|jd|�rndnd
�|�r�|jddj|��|jddj|��n(|jddj|��|jddj|��|jddjt|���|jddjdd�|D���|jddjt|	���|�s:|jd|�r2dnd
�|jd|
�rJdnd
�|jd|�rbdnddjdd�|D���|jddjdd�|D���|jd dj|
��|jd!|�r�dnddjt||d"���dS)#NcSsfd}d}y|j|�}Wntk
r*Yn8X|t|�7}t|||||d�jd��jdd��}|S)Nrz	priority=� �"rt)�indexrbr,�intr~)Zrule�priorityZ
search_strrprrr�rich_rule_sorted_key�s*zDFirewallCommand.print_zone_policy_info.<locals>.rich_rule_sorted_key�defaultZactivez (%s)z, z  summary: z  description: z  priority: z
  target: z  icmp-block-inversion: %srQrPz  ingress-zones: r�z  egress-zones: z  interfaces: z  sources: z  services: z	  ports: cSs g|]}d|d|df�qS)z%s/%srr#r)�.0rerrr�
<listcomp>�sz:FirewallCommand.print_zone_policy_info.<locals>.<listcomp>z
  protocols: z
  forward: %sz  masquerade: %sz  forward-ports: z
	rtcSs$g|]\}}}}d||||f�qS)z$port=%s:proto=%s:toport=%s:toaddr=%sr)r�rerfrjrkrrrr��sz  source-ports: cSs g|]}d|d|df�qS)z%s/%srr#r)r�rerrrr��sz  icmp-blocks: z  rich rules: )�key)Z	getTargetZgetServices�getPorts�getProtocolsZ
getMasqueradeZgetForwardPorts�getSourcePortsZ
getIcmpBlocksZgetRichRules�getDescription�getShortZgetIngressZonesZgetEgressZonesZgetPriorityZgetIcmpBlockInversion�sorted�setZ
getInterfacesZ
getSourcesZ
getForwardr-rxrrr+)rrK�settings�default_zone�extra_interfaces�isPolicy�targetZservices�ports�	protocolsZ
masqueradeZ
forward_ports�source_portsZicmp_blocksZrules�description�short_descriptionZ
ingress_zonesZegress_zonesr�Zicmp_block_inversionZ
interfacesZsourcesZforwardr�Z
attributesrrr�print_zone_policy_info|sx






z&FirewallCommand.print_zone_policy_infocCs|j||||dd�dS)NF)r�r�r�)r�)rrKr�r�r�rrr�print_zone_info�szFirewallCommand.print_zone_infocCs|j||||dd�dS)NT)r�r�r�)r�)rZpolicyr�r�r�rrr�print_policy_info�sz!FirewallCommand.print_policy_infocCs.|j�}|j�}|j�}|j�}|j�}|j�}|j�}	|j�}
|j�}|j	|�|j
rt|j	d|	�|j	d|�|j	ddjdd�|D���|j	ddj|��|j	ddjd	d�|D���|j	d
dj|��|j	ddjdd�|j�D���|j	d
djt
|
���|j	ddjt
|���dS)Nz  summary: z  description: z	  ports: r�cSs g|]}d|d|df�qS)z%s/%srr#r)r�rerrrr��sz6FirewallCommand.print_service_info.<locals>.<listcomp>z
  protocols: z  source-ports: cSs g|]}d|d|df�qS)z%s/%srr#r)r�rerrrr��sz  modules: z  destination: cSsg|]\}}d||f�qS)z%s:%sr)r��k�vrrrr��sz  includes: z  helpers: )r�r�r�Z
getModulesr��getDestinationsr�ZgetIncludesZ
getHelpersrrrxrBr�)rZservicer�r�r�r��modulesr��destinationsr�ZincludesZhelpersrrr�print_service_info�s2


z"FirewallCommand.print_service_infocCsp|j�}|j�}|j�}t|�dkr,ddg}|j|�|jrX|jd|�|jd|�|jddj|��dS)Nrrmrnz  summary: z  description: z  destination: r�)r�r�r�r,rrrx)rZicmptyper�r�r�r�rrr�print_icmptype_info�s
z#FirewallCommand.print_icmptype_infocCs�|j�}|j�}|j�}|j�}|j�}|j|�|jrT|jd|�|jd|�|jd|�|jddjdd�|j�D���|jddj|��dS)	Nz  summary: z  description: z  type: z  options: r�cSs$g|]\}}|rd||fn|�qS)z%s=%sr)r�r�r�rrrr�sz4FirewallCommand.print_ipset_info.<locals>.<listcomp>z  entries: )	ZgetTypeZ
getOptionsZ
getEntriesr�r�rrrxrB)rZipsetr�Z
ipset_typeZoptions�entriesr�r�rrr�print_ipset_info�s
z FirewallCommand.print_ipset_infocCs�|j�}|j�}|j�}|j�}|j�}|j|�|jrT|jd|�|jd|�|jd|�|jd|�|jddjdd�|D���dS)	Nz  summary: z  description: z
  family: z
  module: z	  ports: r�cSs g|]}d|d|df�qS)z%s/%srr#r)r�rerrrr�sz5FirewallCommand.print_helper_info.<locals>.<listcomp>)r�Z	getModuleZ	getFamilyr�r�rrrx)r�helperr�r��moduleZfamilyr�r�rrr�print_helper_infos
z!FirewallCommand.print_helper_infocCs |r|jd�n|jdd�dS)NrQrPr#)r%)rrZrrrrRsz"FirewallCommand.print_query_resultcCs\|js�|j|�tjt|��}|tjtjtjtj	gkrH|j
d|�n|jd||�dS)NzWarning: %sz	Error: %s)r
r2rr*r+rr5r6r7r8r"r%)r�exception_messagerDrrr�exception_handlers

z!FirewallCommand.exception_handlercCsd|krd}|j|tj�dS)NZNotAuthorizedExceptionz`Authorization failed.
    Make sure polkit agent is running or run the application as superuser.)r%rZNOT_AUTHORIZED)rr�rrrrr2'sz&FirewallCommand.fail_if_not_authorizedcCs
d|_dS)NF)r
)rrrrr1-sz,FirewallCommand.deactivate_exception_handlercCs
d|_dS)NT)r
)rrrrr90sz*FirewallCommand.activate_exception_handlercCspg}t�}t|�}xP|D]H}|s"P|j�}t|�dks|ddkrDq||kr|j|�|j|�qW|j�|S)Nr#r�#�;)r�r�)r��open�stripr,r-rF�close)r�filenamer�Zentries_set�f�linerrr�get_ipset_entries_from_file3s

z+FirewallCommand.get_ipset_entries_from_file)FF)N)N)N)Nr)N)N)NNF)F)F)F)F)F)NF)F)F)r\)F).�__name__�
__module__�__qualname__rrrrrrrr r"r%r'r(rGrHrJrLrNrOrTrUrVr[rgrsrvrzr{r|r}rr�r�r�r�r�r�r�rRr�r2r1r9r�rrrrr"sX







J





2



2

O)�__doc__�__all__rZfirewallrZfirewall.errorsrZdbus.exceptionsrZfirewall.functionsrrrr	r
�objectrrrrr�<module>s__pycache__/fw_types.cpython-36.opt-1.pyc000064400000005613150351351710014207 0ustar003

��g��@sdgZGdd�de�ZdS)�LastUpdatedOrderedDictc@sxeZdZddd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zddd�ZdS)rNcCsi|_g|_|r|j|�dS)N)�_dict�_list�update)�self�x�r�/usr/lib/python3.6/fw_types.py�__init__szLastUpdatedOrderedDict.__init__cCs|jdd�=|jj�dS)N)rr�clear)rrrrr
szLastUpdatedOrderedDict.clearcCs"x|j�D]\}}|||<q
WdS)N)�items)rr�key�valuerrrr#szLastUpdatedOrderedDict.updatecs�fdd��jD�S)Ncsg|]}|�|f�qSrr)�.0r)rrr�
<listcomp>(sz0LastUpdatedOrderedDict.items.<locals>.<listcomp>)r)rr)rrr'szLastUpdatedOrderedDict.itemscCs"||jkr|jj|�|j|=dS)N)rr�remove)rrrrr�__delitem__*s
z"LastUpdatedOrderedDict.__delitem__cs&d�jjdj�fdd��jD��fS)Nz%s([%s])z, csg|]}d|�|f�qS)z(%r, %r)r)rr)rrrr1sz3LastUpdatedOrderedDict.__repr__.<locals>.<listcomp>)�	__class__�__name__�joinr)rr)rr�__repr__/szLastUpdatedOrderedDict.__repr__cCs$||jkr|jj|�||j|<dS)N)rr�append)rrr
rrr�__setitem__3s
z"LastUpdatedOrderedDict.__setitem__cCs$t|�tkr|j|S|j|SdS)N)�type�intrr)rrrrr�__getitem__8s
z"LastUpdatedOrderedDict.__getitem__cCs
t|j�S)N)�lenr)rrrr�__len__>szLastUpdatedOrderedDict.__len__cCst|�S)N)r)rrrr�copyAszLastUpdatedOrderedDict.copycCs|jdd�S)N)r)rrrr�keysDszLastUpdatedOrderedDict.keyscs�fdd��jD�S)Ncsg|]}�|�qSrr)rr)rrrrHsz1LastUpdatedOrderedDict.values.<locals>.<listcomp>)r)rr)rr�valuesGszLastUpdatedOrderedDict.valuescCs ||kr||S|||<|SdS)Nr)rrr
rrr�
setdefaultJsz!LastUpdatedOrderedDict.setdefault)N)N)r�
__module__�__qualname__r	r
rrrrrrrrrrr rrrrrs
N)�__all__�objectrrrrr�<module>s__pycache__/__init__.cpython-36.pyc000064400000000161150351351710013140 0ustar003

��g�@sdS)N�rrr�/usr/lib/python3.6/__init__.py�<module>s__pycache__/__init__.cpython-36.opt-1.pyc000064400000000161150351351710014077 0ustar003

��g�@sdS)N�rrr�/usr/lib/python3.6/__init__.py�<module>s__pycache__/errors.cpython-36.pyc000064400000007340150351351710012723 0ustar003

��g��@s�dZdZdZdZdZdZdZdZdZd	Z	d
Z
dZdZd
Z
dZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZd Z d!Z!d"Z"d#Z#d$Z$d%Z%d&Z&d'Z'd(Z(d)Z)d*Z*d+Z+d,Z,d-Z-d.Z.d/Z/d0Z0d1Z1d2Z2d3Z3d4Z4d5Z5d6Z6d7Z7d8Z8d9Z9d:Z:d;Z;d<Z<d=Z=d>Z>d?Z?d@Z@dAZAdBZBdCZCdDZDdEZEdFZFdGZGdHZHdIZIdJZJdKZKdLZLdMZMdNZNdOZOdPZPdQdRlQZQGdSdT�dTeR�ZSeQjTeSjUZVdUdV�eWeV�D�eS_XdWdV�eSjXD�eS_YdRS)X���
������������������� �!�"�#�$�%�&�d�e�f�g�h�i�j�k�l�m�n�o�p�q�r�s�t�u�v�w�x�y�z�{�|�}�~�����������������������������������Nc@s6eZdZd
dd�Zdd�Zdd�Zdd	�Zee�ZdS)�
FirewallErrorNcCsR||_|dk	rHtjdkrHyt|�}Wn"tk
rFt|�jd�}YnX||_dS)N�3Zunicode_escape)�code�sys�version�str�UnicodeEncodeErrorZunicode�encode�msg)�selfrUr[�x�r^�/usr/lib/python3.6/errors.py�__init__ns
zFirewallError.__init__cCsd|j|j|jfS)Nz
%s(%r, %r))�	__class__rUr[)r\r^r^r_�__repr__yszFirewallError.__repr__cCs(|jrd|j|j|jfS|j|jS)Nz%s: %s)r[�errorsrU)r\r^r^r_�__str__|szFirewallError.__str__cCsPd|kr |jd�}|d|�}n|}ytj|}Wntk
rJt}YnX|S)N�:)�indexrS�codes�KeyError�
UNKNOWN_ERROR)r[�idxZecoderUr^r^r_�get_code�s

zFirewallError.get_code)N)�__name__�
__module__�__qualname__r`rbrdrk�staticmethodr^r^r^r_rSms

rScCs6i|].}|jd�rttt|��tkr|tt|��qS)�_)�
startswith�type�getattr�mod�int)�.0Zvarnamer^r^r_�
<dictcomp>�srwcCsi|]}|tj|�qSr^)rSrc)rvrUr^r^r_rw�s)ZZALREADY_ENABLEDZNOT_ENABLEDZCOMMAND_FAILEDZNO_IPV6_NATZ
PANIC_MODEZZONE_ALREADY_SETZUNKNOWN_INTERFACEZ
ZONE_CONFLICTZ
BUILTIN_CHAINZEBTABLES_NO_REJECTZNOT_OVERLOADABLEZNO_DEFAULTSZBUILTIN_ZONEZBUILTIN_SERVICEZBUILTIN_ICMPTYPEZ
NAME_CONFLICTZ
NAME_MISMATCHZPARSE_ERRORZ
ACCESS_DENIEDZUNKNOWN_SOURCEZRT_TO_PERM_FAILEDZIPSET_WITH_TIMEOUTZ
BUILTIN_IPSETZALREADY_SETZMISSING_IMPORTZ
DBUS_ERRORZBUILTIN_HELPERZNOT_APPLIEDZINVALID_ACTIONZINVALID_SERVICEZINVALID_PORTZINVALID_PROTOCOLZINVALID_INTERFACEZINVALID_ADDRZINVALID_FORWARDZINVALID_ICMPTYPEZ
INVALID_TABLEZ
INVALID_CHAINZINVALID_TARGETZINVALID_IPVZINVALID_ZONEZINVALID_PROPERTYZ
INVALID_VALUEZINVALID_OBJECTZINVALID_NAMEZINVALID_FILENAMEZINVALID_DIRECTORYZINVALID_TYPEZINVALID_SETTINGZINVALID_DESTINATIONZINVALID_RULEZ
INVALID_LIMITZINVALID_FAMILYZINVALID_LOG_LEVELZINVALID_AUDIT_TYPEZINVALID_MARKZINVALID_CONTEXTZINVALID_COMMANDZINVALID_USERZINVALID_UIDZINVALID_MODULEZINVALID_PASSTHROUGHZINVALID_MACZ
INVALID_IPSETZ
INVALID_ENTRYZINVALID_OPTIONZINVALID_HELPERZINVALID_PRIORITYZINVALID_POLICYZ
MISSING_TABLEZ
MISSING_CHAINZMISSING_PORTZMISSING_PROTOCOLZMISSING_ADDRZMISSING_NAMEZMISSING_SETTINGZMISSING_FAMILYZRUNNING_BUT_FAILEDZNOT_RUNNINGZNOT_AUTHORIZEDrirV�	ExceptionrS�modulesrmrt�dirrcrgr^r^r^r_�<module>s�$server/config_zone.py000064400000132127150351351710010733 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.

# force use of pygobject3 in python-slip
from gi.repository import GObject
import sys
sys.modules['gobject'] = GObject

import dbus
import dbus.service
import slip.dbus
import slip.dbus.service

from firewall import config
from firewall.dbus_utils import dbus_to_python, \
    dbus_introspection_prepare_properties, \
    dbus_introspection_add_properties
from firewall.core.io.zone import Zone
from firewall.core.fw_ifcfg import ifcfg_set_zone_of_interface
from firewall.core.base import DEFAULT_ZONE_TARGET
from firewall.core.rich import Rich_Rule
from firewall.core.logger import log
from firewall.server.decorators import handle_exceptions, \
    dbus_handle_exceptions, dbus_service_method
from firewall import errors
from firewall.errors import FirewallError
from firewall.functions import portStr, portInPortRange, coalescePortRange, \
                               breakPortRange

############################################################################
#
# class FirewallDConfig
#
############################################################################

class FirewallDConfigZone(slip.dbus.service.Object):
    """FirewallD main class"""

    persistent = True
    """ Make FirewallD persistent. """
    default_polkit_auth_required = config.dbus.PK_ACTION_CONFIG
    """ Use PK_ACTION_INFO as a default """

    @handle_exceptions
    def __init__(self, parent, conf, zone, item_id, *args, **kwargs):
        super(FirewallDConfigZone, self).__init__(*args, **kwargs)
        self.parent = parent
        self.config = conf
        self.obj = zone
        self.item_id = item_id
        self.busname = args[0]
        self.path = args[1]
        self._log_prefix = "config.zone.%d" % self.item_id
        dbus_introspection_prepare_properties(
            self, config.dbus.DBUS_INTERFACE_CONFIG_ZONE)

    @dbus_handle_exceptions
    def __del__(self):
        pass

    @dbus_handle_exceptions
    def unregister(self):
        self.remove_from_connection()

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # P R O P E R T I E S

    @dbus_handle_exceptions
    def _get_property(self, property_name):
        if property_name == "name":
            return dbus.String(self.obj.name)
        elif property_name == "filename":
            return dbus.String(self.obj.filename)
        elif property_name == "path":
            return dbus.String(self.obj.path)
        elif property_name == "default":
            return dbus.Boolean(self.obj.default)
        elif property_name == "builtin":
            return dbus.Boolean(self.obj.builtin)
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ss',
                         out_signature='v')
    @dbus_handle_exceptions
    def Get(self, interface_name, property_name, sender=None): # pylint: disable=W0613
        # get a property
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        log.debug1("%s.Get('%s', '%s')", self._log_prefix,
                   interface_name, property_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_ZONE:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        return self._get_property(property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='s',
                         out_signature='a{sv}')
    @dbus_handle_exceptions
    def GetAll(self, interface_name, sender=None): # pylint: disable=W0613
        interface_name = dbus_to_python(interface_name, str)
        log.debug1("%s.GetAll('%s')", self._log_prefix, interface_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_ZONE:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        ret = { }
        for x in [ "name", "filename", "path", "default", "builtin" ]:
            ret[x] = self._get_property(x)
        return dbus.Dictionary(ret, signature="sv")

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ssv')
    @dbus_handle_exceptions
    def Set(self, interface_name, property_name, new_value, sender=None):
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        new_value = dbus_to_python(new_value)
        log.debug1("%s.Set('%s', '%s', '%s')", self._log_prefix,
                   interface_name, property_name, new_value)
        self.parent.accessCheck(sender)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_ZONE:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        raise dbus.exceptions.DBusException(
            "org.freedesktop.DBus.Error.PropertyReadOnly: "
            "Property '%s' is read-only" % property_name)

    @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as')
    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)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(dbus.INTROSPECTABLE_IFACE, out_signature='s')
    @dbus_handle_exceptions
    def Introspect(self, sender=None): # pylint: disable=W0613
        log.debug2("%s.Introspect()", self._log_prefix)

        data = super(FirewallDConfigZone, self).Introspect(
            self.path, self.busname.get_bus())

        return dbus_introspection_add_properties(
            self, data, config.dbus.DBUS_INTERFACE_CONFIG_ZONE)

    # S E T T I N G S

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature="(sssbsasa(ss)asba(ssss)asasasasa(ss)b)")
    @dbus_handle_exceptions
    def getSettings(self, sender=None): # pylint: disable=W0613
        """get settings for zone
        """
        log.debug1("%s.getSettings()", self._log_prefix)
        settings = self.config.get_zone_config(self.obj)
        if settings[4] == DEFAULT_ZONE_TARGET:
            # convert to list, fix target, convert back to tuple
            _settings = list(settings)
            _settings[4] = "default"
            settings = tuple(_settings)
        return settings

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature="a{sv}")
    @dbus_handle_exceptions
    def getSettings2(self, sender=None):
        """get settings for zone
        """
        log.debug1("%s.getSettings2()", self._log_prefix)
        settings = self.config.get_zone_config_dict(self.obj)
        if settings["target"] == DEFAULT_ZONE_TARGET:
            settings["target"] = "default"
        return settings

    def _checkDuplicateInterfacesSources(self, settings):
        """Assignment of interfaces/sources to zones is different from other
           zone settings in the sense that particular interface/zone can be
           part of only one zone. So make sure added interfaces/sources have
           not already been bound to another zone."""
        old_settings = self.config.get_zone_config_dict(self.obj)
        old_ifaces = set(old_settings["interfaces"]) if "interfaces" in old_settings else set()
        old_sources = set(old_settings["sources"]) if "sources" in old_settings else set()
        if isinstance(settings, tuple):
            added_ifaces = set(settings[Zone.index_of("interfaces")]) - old_ifaces
            added_sources = set(settings[Zone.index_of("sources")]) - old_sources
        else: # dict
            new_ifaces = set(settings["interfaces"]) if "interfaces" in settings else set()
            new_sources = set(settings["sources"]) if "sources" in settings else set()
            added_ifaces = new_ifaces - old_ifaces
            added_sources = new_sources - old_sources

        for iface in added_ifaces:
            if self.parent.getZoneOfInterface(iface):
                raise FirewallError(errors.ZONE_CONFLICT, iface)  # or move to new zone ?
        for source in added_sources:
            if self.parent.getZoneOfSource(source):
                raise FirewallError(errors.ZONE_CONFLICT, source) # or move to new zone ?

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature="(sssbsasa(ss)asba(ssss)asasasasa(ss)b)")
    @dbus_handle_exceptions
    def update(self, settings, sender=None):
        """update settings for zone
        """
        settings = dbus_to_python(settings)
        log.debug1("%s.update('...')", self._log_prefix)
        self.parent.accessCheck(sender)
        if settings[4] == "default":
            # convert to list, fix target, convert back to tuple
            _settings = list(settings)
            _settings[4] = DEFAULT_ZONE_TARGET
            settings = tuple(_settings)
        self._checkDuplicateInterfacesSources(settings)
        self.obj = self.config.set_zone_config(self.obj, settings)
        self.Updated(self.obj.name)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature="a{sv}")
    @dbus_handle_exceptions
    def update2(self, settings, sender=None):
        """update settings for zone
        """
        settings = dbus_to_python(settings)
        log.debug1("%s.update2('...')", self._log_prefix)
        self.parent.accessCheck(sender)
        if "target" in settings and settings["target"] == "default":
            settings["target"] = DEFAULT_ZONE_TARGET
        self._checkDuplicateInterfacesSources(settings)
        self.obj = self.config.set_zone_config_dict(self.obj, settings)
        self.Updated(self.obj.name)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE)
    @dbus_handle_exceptions
    def loadDefaults(self, sender=None):
        """load default settings for builtin zone
        """
        log.debug1("%s.loadDefaults()", self._log_prefix)
        self.parent.accessCheck(sender)
        self.obj = self.config.load_zone_defaults(self.obj)
        self.Updated(self.obj.name)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_ZONE, signature='s')
    @dbus_handle_exceptions
    def Updated(self, name):
        log.debug1("%s.Updated('%s')" % (self._log_prefix, name))

    # R E M O V E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE)
    @dbus_handle_exceptions
    def remove(self, sender=None):
        """remove zone
        """
        log.debug1("%s.removeZone()", self._log_prefix)
        self.parent.accessCheck(sender)
        self.config.remove_zone(self.obj)
        self.parent.removeZone(self.obj)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_ZONE, signature='s')
    @dbus_handle_exceptions
    def Removed(self, name):
        log.debug1("%s.Removed('%s')" % (self._log_prefix, name))

    # R E N A M E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def rename(self, name, sender=None):
        """rename zone
        """
        name = dbus_to_python(name, str)
        log.debug1("%s.rename('%s')", self._log_prefix, name)
        self.parent.accessCheck(sender)
        self.obj = self.config.rename_zone(self.obj, name)
        self.Renamed(name)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_ZONE, signature='s')
    @dbus_handle_exceptions
    def Renamed(self, name):
        log.debug1("%s.Renamed('%s')" % (self._log_prefix, name))

    # version

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='s')
    @dbus_handle_exceptions
    def getVersion(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getVersion()", self._log_prefix)
        return self.getSettings()[0]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # short

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='s')
    @dbus_handle_exceptions
    def getShort(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getShort()", self._log_prefix)
        return self.getSettings()[1]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # description

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='s')
    @dbus_handle_exceptions
    def getDescription(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getDescription()", self._log_prefix)
        return self.getSettings()[2]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # immutable (deprecated)
    # settings[3] was used for 'immutable'

    # target

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='s')
    @dbus_handle_exceptions
    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"

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # service

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='as')
    @dbus_handle_exceptions
    def getServices(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getServices()", self._log_prefix)
        return self.getSettings()[5]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='as')
    @dbus_handle_exceptions
    def setServices(self, services, sender=None):
        services = dbus_to_python(services, list)
        log.debug1("%s.setServices('[%s]')", self._log_prefix,
                   ",".join(services))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[5] = services
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def addService(self, service, sender=None):
        service = dbus_to_python(service, str)
        log.debug1("%s.addService('%s')", self._log_prefix, service)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if service in settings[5]:
            raise FirewallError(errors.ALREADY_ENABLED, service)
        settings[5].append(service)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeService(self, service, sender=None):
        service = dbus_to_python(service, str)
        log.debug1("%s.removeService('%s')", self._log_prefix, service)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if service not in settings[5]:
            raise FirewallError(errors.NOT_ENABLED, service)
        settings[5].remove(service)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    def queryService(self, service, sender=None): # pylint: disable=W0613
        service = dbus_to_python(service, str)
        log.debug1("%s.queryService('%s')", self._log_prefix, service)
        return service in self.getSettings()[5]

    # port

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='a(ss)')
    @dbus_handle_exceptions
    def getPorts(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getPorts()", self._log_prefix)
        return self.getSettings()[6]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='a(ss)')
    @dbus_handle_exceptions
    def setPorts(self, ports, sender=None):
        _ports = [ ]
        # convert embedded lists to tuples
        for port in dbus_to_python(ports, list):
            if isinstance(port, list):
                _ports.append(tuple(port))
            else:
                _ports.append(port)
        ports = _ports
        log.debug1("%s.setPorts('[%s]')", self._log_prefix,
                   ",".join("('%s, '%s')" % (port[0], port[1]) for port in ports))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[6] = ports
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='ss')
    @dbus_handle_exceptions
    def addPort(self, port, protocol, sender=None):
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.addPort('%s', '%s')", self._log_prefix, port,
                   protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        existing_port_ids = list(filter(lambda x: x[1] == protocol, settings[6]))
        for port_id in existing_port_ids:
            if portInPortRange(port, port_id[0]):
                raise FirewallError(errors.ALREADY_ENABLED,
                                    "%s:%s" % (port, protocol))
        added_ranges, removed_ranges = coalescePortRange(port, [_port for (_port, _protocol) in existing_port_ids])
        for range in removed_ranges:
            settings[6].remove((portStr(range, "-"), protocol))
        for range in added_ranges:
            settings[6].append((portStr(range, "-"), protocol))
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='ss')
    @dbus_handle_exceptions
    def removePort(self, port, protocol, sender=None):
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.removePort('%s', '%s')", self._log_prefix, port,
                   protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        existing_port_ids = list(filter(lambda x: x[1] == protocol, settings[6]))
        for port_id in existing_port_ids:
            if portInPortRange(port, port_id[0]):
                break
        else:
            raise FirewallError(errors.NOT_ENABLED, "%s:%s" % (port, protocol))
        added_ranges, removed_ranges = breakPortRange(port, [_port for (_port, _protocol) in existing_port_ids])
        for range in removed_ranges:
            settings[6].remove((portStr(range, "-"), protocol))
        for range in added_ranges:
            settings[6].append((portStr(range, "-"), protocol))
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='ss', out_signature='b')
    @dbus_handle_exceptions
    def queryPort(self, port, protocol, sender=None): # pylint: disable=W0613
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.queryPort('%s', '%s')", self._log_prefix, port,
                   protocol)
        for (_port, _protocol) in self.getSettings()[6]:
            if portInPortRange(port, _port) and protocol == _protocol:
                return True

        return False

    # protocol

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='as')
    @dbus_handle_exceptions
    def getProtocols(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getProtocols()", self._log_prefix)
        return self.getSettings()[13]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='as')
    @dbus_handle_exceptions
    def setProtocols(self, protocols, sender=None):
        protocols = dbus_to_python(protocols, list)
        log.debug1("%s.setProtocols('[%s]')", self._log_prefix,
                   ",".join(protocols))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[13] = protocols
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def addProtocol(self, protocol, sender=None):
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.addProtocol('%s')", self._log_prefix, protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if protocol in settings[13]:
            raise FirewallError(errors.ALREADY_ENABLED, protocol)
        settings[13].append(protocol)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeProtocol(self, protocol, sender=None):
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.removeProtocol('%s')", self._log_prefix, protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if protocol not in settings[13]:
            raise FirewallError(errors.NOT_ENABLED, protocol)
        settings[13].remove(protocol)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    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]

    # source port

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='a(ss)')
    @dbus_handle_exceptions
    def getSourcePorts(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getSourcePorts()", self._log_prefix)
        return self.getSettings()[14]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='a(ss)')
    @dbus_handle_exceptions
    def setSourcePorts(self, ports, sender=None):
        _ports = [ ]
        # convert embedded lists to tuples
        for port in dbus_to_python(ports, list):
            if isinstance(port, list):
                _ports.append(tuple(port))
            else:
                _ports.append(port)
        ports = _ports
        log.debug1("%s.setSourcePorts('[%s]')", self._log_prefix,
                   ",".join("('%s, '%s')" % (port[0], port[1]) for port in ports))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[14] = ports
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='ss')
    @dbus_handle_exceptions
    def addSourcePort(self, port, protocol, sender=None):
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.addSourcePort('%s', '%s')", self._log_prefix, port,
                   protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        existing_port_ids = list(filter(lambda x: x[1] == protocol, settings[14]))
        for port_id in existing_port_ids:
            if portInPortRange(port, port_id[0]):
                raise FirewallError(errors.ALREADY_ENABLED,
                                    "%s:%s" % (port, protocol))
        added_ranges, removed_ranges = coalescePortRange(port, [_port for (_port, _protocol) in existing_port_ids])
        for range in removed_ranges:
            settings[14].remove((portStr(range, "-"), protocol))
        for range in added_ranges:
            settings[14].append((portStr(range, "-"), protocol))
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='ss')
    @dbus_handle_exceptions
    def removeSourcePort(self, port, protocol, sender=None):
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.removeSourcePort('%s', '%s')", self._log_prefix, port,
                   protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        existing_port_ids = list(filter(lambda x: x[1] == protocol, settings[14]))
        for port_id in existing_port_ids:
            if portInPortRange(port, port_id[0]):
                break
        else:
            raise FirewallError(errors.NOT_ENABLED, "%s:%s" % (port, protocol))
        added_ranges, removed_ranges = breakPortRange(port, [_port for (_port, _protocol) in existing_port_ids])
        for range in removed_ranges:
            settings[14].remove((portStr(range, "-"), protocol))
        for range in added_ranges:
            settings[14].append((portStr(range, "-"), protocol))
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='ss', out_signature='b')
    @dbus_handle_exceptions
    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)
        for (_port, _protocol) in self.getSettings()[14]:
            if portInPortRange(port, _port) and protocol == _protocol:
                return True

        return False

    # icmp block

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='as')
    @dbus_handle_exceptions
    def getIcmpBlocks(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getIcmpBlocks()", self._log_prefix)
        return self.getSettings()[7]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='as')
    @dbus_handle_exceptions
    def setIcmpBlocks(self, icmptypes, sender=None):
        icmptypes = dbus_to_python(icmptypes, list)
        log.debug1("%s.setIcmpBlocks('[%s]')", self._log_prefix,
                   ",".join(icmptypes))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[7] = icmptypes
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def addIcmpBlock(self, icmptype, sender=None):
        icmptype = dbus_to_python(icmptype, str)
        log.debug1("%s.addIcmpBlock('%s')", self._log_prefix, icmptype)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if icmptype in settings[7]:
            raise FirewallError(errors.ALREADY_ENABLED, icmptype)
        settings[7].append(icmptype)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeIcmpBlock(self, icmptype, sender=None):
        icmptype = dbus_to_python(icmptype, str)
        log.debug1("%s.removeIcmpBlock('%s')", self._log_prefix, icmptype)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if icmptype not in settings[7]:
            raise FirewallError(errors.NOT_ENABLED, icmptype)
        settings[7].remove(icmptype)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    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]

    # icmp block inversion

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='b')
    @dbus_handle_exceptions
    def getIcmpBlockInversion(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getIcmpBlockInversion()", self._log_prefix)
        return self.getSettings()[15]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='b')
    @dbus_handle_exceptions
    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)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE)
    @dbus_handle_exceptions
    def addIcmpBlockInversion(self, sender=None):
        log.debug1("%s.addIcmpBlockInversion()", self._log_prefix)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if settings[15]:
            raise FirewallError(errors.ALREADY_ENABLED, "icmp-block-inversion")
        settings[15] = True
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE)
    @dbus_handle_exceptions
    def removeIcmpBlockInversion(self, sender=None):
        log.debug1("%s.removeIcmpBlockInversion()", self._log_prefix)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if not settings[15]:
            raise FirewallError(errors.NOT_ENABLED, "icmp-block-inversion")
        settings[15] = False
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='b')
    @dbus_handle_exceptions
    def queryIcmpBlockInversion(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.queryIcmpBlockInversion()", self._log_prefix)
        return self.getSettings()[15]

    # masquerade

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='b')
    @dbus_handle_exceptions
    def getMasquerade(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getMasquerade()", self._log_prefix)
        return self.getSettings()[8]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='b')
    @dbus_handle_exceptions
    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)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE)
    @dbus_handle_exceptions
    def addMasquerade(self, sender=None):
        log.debug1("%s.addMasquerade()", self._log_prefix)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if settings[8]:
            raise FirewallError(errors.ALREADY_ENABLED, "masquerade")
        settings[8] = True
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE)
    @dbus_handle_exceptions
    def removeMasquerade(self, sender=None):
        log.debug1("%s.removeMasquerade()", self._log_prefix)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if not settings[8]:
            raise FirewallError(errors.NOT_ENABLED, "masquerade")
        settings[8] = False
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='b')
    @dbus_handle_exceptions
    def queryMasquerade(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.queryMasquerade()", self._log_prefix)
        return self.getSettings()[8]

    # forward port

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='a(ssss)')
    @dbus_handle_exceptions
    def getForwardPorts(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getForwardPorts()", self._log_prefix)
        return self.getSettings()[9]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='a(ssss)')
    @dbus_handle_exceptions
    def setForwardPorts(self, ports, sender=None):
        _ports = [ ]
        # convert embedded lists to tuples
        for port in dbus_to_python(ports, list):
            if isinstance(port, list):
                _ports.append(tuple(port))
            else:
                _ports.append(port)
        ports = _ports
        log.debug1("%s.setForwardPorts('[%s]')", self._log_prefix,
                   ",".join("('%s, '%s', '%s', '%s')" % (port[0], port[1], \
                                                         port[2], port[3]) for port in ports))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[9] = ports
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='ssss')
    @dbus_handle_exceptions
    def addForwardPort(self, port, protocol, toport, toaddr, sender=None): # pylint: disable=R0913
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        toport = dbus_to_python(toport, str)
        toaddr = dbus_to_python(toaddr, str)
        log.debug1("%s.addForwardPort('%s', '%s', '%s', '%s')",
                   self._log_prefix, port, protocol, toport, toaddr)
        self.parent.accessCheck(sender)
        fwp_id = (port, protocol, str(toport), str(toaddr))
        settings = list(self.getSettings())
        if fwp_id in settings[9]:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "%s:%s:%s:%s" % (port, protocol, toport,
                                                 toaddr))
        settings[9].append(fwp_id)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='ssss')
    @dbus_handle_exceptions
    def removeForwardPort(self, port, protocol, toport, toaddr, sender=None): # pylint: disable=R0913
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        toport = dbus_to_python(toport, str)
        toaddr = dbus_to_python(toaddr, str)
        log.debug1("%s.removeForwardPort('%s', '%s', '%s', '%s')",
                   self._log_prefix, port, protocol, toport, toaddr)
        self.parent.accessCheck(sender)
        fwp_id = (port, protocol, str(toport), str(toaddr))
        settings = list(self.getSettings())
        if fwp_id not in settings[9]:
            raise FirewallError(errors.NOT_ENABLED,
                                "%s:%s:%s:%s" % (port, protocol, toport,
                                                 toaddr))
        settings[9].remove(fwp_id)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='ssss',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryForwardPort(self, port, protocol, toport, toaddr, sender=None): # pylint: disable=W0613, R0913
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        toport = dbus_to_python(toport, str)
        toaddr = dbus_to_python(toaddr, str)
        log.debug1("%s.queryForwardPort('%s', '%s', '%s', '%s')",
                   self._log_prefix, port, protocol, toport, toaddr)
        fwp_id = (port, protocol, str(toport), str(toaddr))
        return fwp_id in self.getSettings()[9]

    # interface

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='as')
    @dbus_handle_exceptions
    def getInterfaces(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getInterfaces()", self._log_prefix)
        return self.getSettings()[10]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='as')
    @dbus_handle_exceptions
    def setInterfaces(self, interfaces, sender=None):
        interfaces = dbus_to_python(interfaces, list)
        log.debug1("%s.setInterfaces('[%s]')", self._log_prefix,
                   ",".join(interfaces))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[10] = interfaces
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def addInterface(self, interface, sender=None):
        interface = dbus_to_python(interface, str)
        log.debug1("%s.addInterface('%s')", self._log_prefix, interface)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if interface in settings[10]:
            raise FirewallError(errors.ALREADY_ENABLED, interface)
        settings[10].append(interface)
        self.update(settings)

        ifcfg_set_zone_of_interface(self.obj.name, interface)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeInterface(self, interface, sender=None):
        interface = dbus_to_python(interface, str)
        log.debug1("%s.removeInterface('%s')", self._log_prefix, interface)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if interface not in settings[10]:
            raise FirewallError(errors.NOT_ENABLED, interface)
        settings[10].remove(interface)
        self.update(settings)

        ifcfg_set_zone_of_interface("", interface)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s',
                         out_signature='b')
    @dbus_handle_exceptions
    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]

    # source

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='as')
    @dbus_handle_exceptions
    def getSources(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getSources()", self._log_prefix)
        return self.getSettings()[11]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='as')
    @dbus_handle_exceptions
    def setSources(self, sources, sender=None):
        sources = dbus_to_python(sources, list)
        log.debug1("%s.setSources('[%s]')", self._log_prefix,
                   ",".join(sources))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[11] = sources
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def addSource(self, source, sender=None):
        source = dbus_to_python(source, str)
        log.debug1("%s.addSource('%s')", self._log_prefix, source)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if source in settings[11]:
            raise FirewallError(errors.ALREADY_ENABLED, source)
        settings[11].append(source)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeSource(self, source, sender=None):
        source = dbus_to_python(source, str)
        log.debug1("%s.removeSource('%s')", self._log_prefix, source)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if source not in settings[11]:
            raise FirewallError(errors.NOT_ENABLED, source)
        settings[11].remove(source)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    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]

    # rich rule

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         out_signature='as')
    @dbus_handle_exceptions
    def getRichRules(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getRichRules()", self._log_prefix)
        return self.getSettings()[12]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='as')
    @dbus_handle_exceptions
    def setRichRules(self, rules, sender=None):
        rules = dbus_to_python(rules, list)
        log.debug1("%s.setRichRules('[%s]')", self._log_prefix,
                   ",".join(rules))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        rules = [ str(Rich_Rule(rule_str=r)) for r in rules ]
        settings[12] = rules
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def addRichRule(self, rule, sender=None):
        rule = dbus_to_python(rule, str)
        log.debug1("%s.addRichRule('%s')", self._log_prefix, rule)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        rule_str = str(Rich_Rule(rule_str=rule))
        if rule_str in settings[12]:
            raise FirewallError(errors.ALREADY_ENABLED, rule)
        settings[12].append(rule_str)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeRichRule(self, rule, sender=None):
        rule = dbus_to_python(rule, str)
        log.debug1("%s.removeRichRule('%s')", self._log_prefix, rule)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        rule_str = str(Rich_Rule(rule_str=rule))
        if rule_str not in settings[12]:
            raise FirewallError(errors.NOT_ENABLED, rule)
        settings[12].remove(rule_str)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ZONE,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    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]
server/__init__.py000064400000000000150351351710010152 0ustar00server/firewalld.py000064400000340142150351351710010402 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.

__all__ = [ "FirewallD" ]

from gi.repository import GLib, GObject

# force use of pygobject3 in python-slip
import sys
sys.modules['gobject'] = GObject

import copy
import dbus
import dbus.service
import slip.dbus
import slip.dbus.service

from firewall import config
from firewall.core.fw import Firewall
from firewall.core.rich import Rich_Rule
from firewall.core.logger import log
from firewall.client import FirewallClientZoneSettings
from firewall.server.decorators import dbus_handle_exceptions, \
                                       dbus_service_method, \
                                       handle_exceptions, \
                                       FirewallDBusException
from firewall.server.config import FirewallDConfig
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.ipset import IPSet
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, \
                                nm_set_zone_of_connection
from firewall.core.fw_ifcfg import ifcfg_set_zone_of_interface
from firewall import errors
from firewall.errors import FirewallError

############################################################################
#
# class FirewallD
#
############################################################################

class FirewallD(slip.dbus.service.Object):
    """FirewallD main class"""

    persistent = True
    """ Make FirewallD persistent. """
    default_polkit_auth_required = config.dbus.PK_ACTION_CONFIG
    """ Use config.dbus.PK_ACTION_CONFIG as a default """

    @handle_exceptions
    def __init__(self, *args, **kwargs):
        super(FirewallD, self).__init__(*args, **kwargs)
        self.fw = Firewall()
        self.busname = args[0]
        self.path = args[1]
        self.start()
        dbus_introspection_prepare_properties(self, config.dbus.DBUS_INTERFACE)
        self.config = FirewallDConfig(self.fw.config, self.busname,
                                      config.dbus.DBUS_PATH_CONFIG)

    def __del__(self):
        self.stop()

    @handle_exceptions
    def start(self):
        # tests if iptables and ip6tables are usable using test functions
        # loads default firewall rules for iptables and ip6tables
        log.debug1("start()")
        self._timeouts = { }
        return self.fw.start()

    @handle_exceptions
    def stop(self):
        # stops firewall: unloads firewall modules, flushes chains and tables,
        #   resets policies
        log.debug1("stop()")
        return self.fw.stop()

    # lockdown functions

    @dbus_handle_exceptions
    def accessCheck(self, sender):
        if self.fw.policies.query_lockdown():
            if sender is None:
                log.error("Lockdown not possible, sender not set.")
                return
            bus = dbus.SystemBus()
            context = context_of_sender(bus, sender)
            if self.fw.policies.access_check("context", context):
                return
            uid = uid_of_sender(bus, sender)
            if self.fw.policies.access_check("uid", uid):
                return
            user = user_of_uid(uid)
            if self.fw.policies.access_check("user", user):
                return
            command = command_of_sender(bus, sender)
            if self.fw.policies.access_check("command", command):
                return
            raise FirewallError(errors.ACCESS_DENIED, "lockdown is enabled")

    # timeout functions

    @dbus_handle_exceptions
    def addTimeout(self, zone, x, tag):
        if zone not in self._timeouts:
            self._timeouts[zone] = { }
        self._timeouts[zone][x] = tag

    @dbus_handle_exceptions
    def removeTimeout(self, zone, x):
        if zone in self._timeouts and x in self._timeouts[zone]:
            GLib.source_remove(self._timeouts[zone][x])
            del self._timeouts[zone][x]

    @dbus_handle_exceptions
    def cleanup_timeouts(self):
        # cleanup timeouts
        for zone in self._timeouts:
            for x in self._timeouts[zone]:
                GLib.source_remove(self._timeouts[zone][x])
            self._timeouts[zone].clear()
        self._timeouts.clear()

    # property handling

    @dbus_handle_exceptions
    def _get_property(self, prop):
        if prop == "version":
            return dbus.String(config.VERSION)
        elif prop == "interface_version":
            return dbus.String("%d.%d" % (config.dbus.DBUS_INTERFACE_VERSION,
                                          config.dbus.DBUS_INTERFACE_REVISION))
        elif prop == "state":
            return dbus.String(self.fw.get_state())

        elif prop == "IPv4":
            return dbus.Boolean(self.fw.is_ipv_enabled("ipv4"))

        elif prop == "IPv4ICMPTypes":
            return dbus.Array(self.fw.ipv4_supported_icmp_types, "s")

        elif prop == "IPv6":
            return dbus.Boolean(self.fw.is_ipv_enabled("ipv6"))

        elif prop == "IPv6_rpfilter":
            return dbus.Boolean(self.fw.ipv6_rpfilter_enabled)

        elif prop == "IPv6ICMPTypes":
            return dbus.Array(self.fw.ipv6_supported_icmp_types, "s")

        elif prop == "BRIDGE":
            return dbus.Boolean(self.fw.ebtables_enabled)

        elif prop == "IPSet":
            return dbus.Boolean(self.fw.ipset_enabled)

        elif prop == "IPSetTypes":
            return dbus.Array(self.fw.ipset_supported_types, "s")

        elif prop == "nf_conntrack_helper_setting":
            return dbus.Boolean(False)

        elif prop == "nf_conntrack_helpers":
            return dbus.Dictionary({}, "sas")

        elif prop == "nf_nat_helpers":
            return dbus.Dictionary({}, "sas")

        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % prop)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ss',
                         out_signature='v')
    @dbus_handle_exceptions
    def Get(self, interface_name, property_name, sender=None): # pylint: disable=W0613
        # get a property
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        log.debug1("Get('%s', '%s')", interface_name, property_name)

        if interface_name == config.dbus.DBUS_INTERFACE:
            return self._get_property(property_name)
        elif interface_name in [ config.dbus.DBUS_INTERFACE_ZONE,
                                 config.dbus.DBUS_INTERFACE_DIRECT,
                                 config.dbus.DBUS_INTERFACE_POLICIES,
                                 config.dbus.DBUS_INTERFACE_IPSET ]:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % property_name)
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='s',
                         out_signature='a{sv}')
    @dbus_handle_exceptions
    def GetAll(self, interface_name, sender=None): # pylint: disable=W0613
        interface_name = dbus_to_python(interface_name, str)
        log.debug1("GetAll('%s')", interface_name)

        ret = { }
        if interface_name == config.dbus.DBUS_INTERFACE:
            for x in [ "version", "interface_version", "state",
                       "IPv4", "IPv6", "IPv6_rpfilter", "BRIDGE",
                       "IPSet", "IPSetTypes", "nf_conntrack_helper_setting",
                       "nf_conntrack_helpers", "nf_nat_helpers",
                       "IPv4ICMPTypes", "IPv6ICMPTypes" ]:
                ret[x] = self._get_property(x)
        elif interface_name in [ config.dbus.DBUS_INTERFACE_ZONE,
                                 config.dbus.DBUS_INTERFACE_DIRECT,
                                 config.dbus.DBUS_INTERFACE_POLICIES,
                                 config.dbus.DBUS_INTERFACE_IPSET ]:
            pass
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        return dbus.Dictionary(ret, signature="sv")

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ssv')
    @dbus_handle_exceptions
    def Set(self, interface_name, property_name, new_value, sender=None):
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        new_value = dbus_to_python(new_value)
        log.debug1("Set('%s', '%s', '%s')", interface_name, property_name,
                   new_value)
        self.accessCheck(sender)

        if interface_name == config.dbus.DBUS_INTERFACE:
            if property_name in [ "version", "interface_version", "state",
                                  "IPv4", "IPv6", "IPv6_rpfilter", "BRIDGE",
                                  "IPSet", "IPSetTypes",
                                  "nf_conntrack_helper_setting",
                                  "nf_conntrack_helpers", "nf_nat_helpers",
                                  "IPv4ICMPTypes", "IPv6ICMPTypes" ]:
                raise dbus.exceptions.DBusException(
                    "org.freedesktop.DBus.Error.PropertyReadOnly: "
                    "Property '%s' is read-only" % property_name)
            else:
                raise dbus.exceptions.DBusException(
                    "org.freedesktop.DBus.Error.InvalidArgs: "
                    "Property '%s' does not exist" % property_name)
        elif interface_name in [ config.dbus.DBUS_INTERFACE_ZONE,
                                 config.dbus.DBUS_INTERFACE_DIRECT,
                                 config.dbus.DBUS_INTERFACE_POLICIES,
                                 config.dbus.DBUS_INTERFACE_IPSET ]:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % property_name)
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

    @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as')
    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("PropertiesChanged('%s', '%s', '%s')",
                   interface_name, changed_properties, invalidated_properties)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(dbus.INTROSPECTABLE_IFACE, out_signature='s')
    @dbus_handle_exceptions
    def Introspect(self, sender=None): # pylint: disable=W0613
        log.debug2("Introspect()")

        data = super(FirewallD, self).Introspect(self.path,
                                                 self.busname.get_bus())

        return dbus_introspection_add_properties(self, data,
                                                 config.dbus.DBUS_INTERFACE)

    # reload

    @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 reload(self, sender=None): # pylint: disable=W0613
        """Reload the firewall rules.
        """
        log.debug1("reload()")

        self.fw.reload()
        self.config.reload()
        self.Reloaded()

    # complete_reload

    @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 completeReload(self, sender=None): # pylint: disable=W0613
        """Completely reload the firewall.

        Completely reload the firewall: Stops firewall, unloads modules and 
        starts the firewall again.
        """
        log.debug1("completeReload()")

        self.fw.reload(True)
        self.config.reload()
        self.Reloaded()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE)
    @dbus_handle_exceptions
    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)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='',
                         out_signature='')
    @dbus_handle_exceptions
    def runtimeToPermanent(self, sender=None): # pylint: disable=W0613
        """Make runtime configuration permanent
        """
        log.debug1("copyRuntimeToPermanent()")

        error = False

        # Services or icmptypes can not be modified in runtime, but they can
        # be removed or modified in permanent environment. Therefore copying
        # of services and icmptypes to permanent is also needed.

        # services

        config_names = self.config.getServiceNames()
        for name in self.fw.service.get_services():
            conf = self.getServiceSettings(name)
            try:
                if name in config_names:
                    conf_obj = self.config.getServiceByName(name)
                    if conf_obj.getSettings() != conf:
                        log.debug1("Copying service '%s' settings" % name)
                        conf_obj.update(conf)
                    else:
                        log.debug1("Service '%s' is identical, ignoring." % name)
                else:
                    log.debug1("Creating service '%s'" % name)
                    self.config.addService(name, conf)
            except Exception as e:
                log.warning(
                    "Runtime To Permanent failed on service '%s': %s" % \
                    (name, e))
                error = True

        # icmptypes

        config_names = self.config.getIcmpTypeNames()
        for name in self.fw.icmptype.get_icmptypes():
            conf = self.getIcmpTypeSettings(name)
            try:
                if name in config_names:
                    conf_obj = self.config.getIcmpTypeByName(name)
                    if conf_obj.getSettings() != conf:
                        log.debug1("Copying icmptype '%s' settings" % name)
                        conf_obj.update(conf)
                    else:
                        log.debug1("IcmpType '%s' is identical, ignoring." % name)
                else:
                    log.debug1("Creating icmptype '%s'" % name)
                    self.config.addIcmpType(name, conf)
            except Exception as e:
                log.warning(
                    "Runtime To Permanent failed on icmptype '%s': %s" % \
                    (name, e))
                error = True

        # ipsets

        config_names = self.config.getIPSetNames()
        for name in self.fw.ipset.get_ipsets():
            try:
                conf = self.getIPSetSettings(name)
                if name in config_names:
                    conf_obj = self.config.getIPSetByName(name)
                    if conf_obj.getSettings() != conf:
                        log.debug1("Copying ipset '%s' settings" % name)
                        conf_obj.update(conf)
                    else:
                        log.debug1("IPSet '%s' is identical, ignoring." % name)
                else:
                    log.debug1("Creating ipset '%s'" % name)
                    self.config.addIPSet(name, conf)
            except Exception as e:
                log.warning(
                    "Runtime To Permanent failed on ipset '%s': %s" % \
                    (name, e))
                error = True

        # zones

        config_names = self.config.getZoneNames()
        nm_bus_name = nm_get_bus_name()
        for name in self.fw.zone.get_zones():
            conf = self.getZoneSettings2(name)
            settings = FirewallClientZoneSettings(conf)
            if nm_bus_name is not None:
                changed = False
                for interface in settings.getInterfaces():
                    if self.fw.zone.interface_get_sender(name, interface) == nm_bus_name:
                        log.debug1("Zone '%s': interface binding for '%s' has been added by NM, ignoring." % (name, interface))
                        settings.removeInterface(interface)
                        changed = True
                # For the remaining interfaces, attempt to let NM manage them
                for interface in settings.getInterfaces():
                    try:
                        connection = nm_get_connection_of_interface(interface)
                        if connection and nm_set_zone_of_connection(name, connection):
                            settings.removeInterface(interface)
                            changed = True
                    except Exception:
                        pass

                if changed:
                    del conf
                    conf = settings.getSettingsDict()
            # For the remaining try to update the ifcfg files
            for interface in settings.getInterfaces():
                ifcfg_set_zone_of_interface(name, interface)
            try:
                if name in config_names:
                    conf_obj = self.config.getZoneByName(name)
                    log.debug1("Copying zone '%s' settings" % name)
                    conf_obj.update2(conf)
                else:
                    log.debug1("Creating zone '%s'" % name)
                    self.config.addZone2(name, conf)
            except Exception as e:
                log.warning(
                    "Runtime To Permanent failed on zone '%s': %s" % \
                    (name, e))
                error = True

        # policies

        config_names = self.config.getPolicyNames()
        for name in self.fw.policy.get_policies_not_derived_from_zone():
            conf = self.getPolicySettings(name)
            try:
                if name in config_names:
                    conf_obj = self.config.getPolicyByName(name)
                    conf_obj.update(conf)
                else:
                    log.debug1("Creating policy '%s'" % name)
                    self.config.addPolicy(name, conf)
            except Exception as e:
                log.warning(
                    "Runtime To Permanent failed on policy '%s': %s" % \
                    (name, e))
                error = True

        # helpers

        config_names = self.config.getHelperNames()
        for name in self.fw.helper.get_helpers():
            conf = self.getHelperSettings(name)
            try:
                if name in config_names:
                    conf_obj = self.config.getHelperByName(name)
                    if conf_obj.getSettings() != conf:
                        log.debug1("Copying helper '%s' settings" % name)
                        conf_obj.update(conf)
                    else:
                        log.debug1("Helper '%s' is identical, ignoring." % name)
                else:
                    log.debug1("Creating helper '%s'" % name)
                    self.config.addHelper(name, conf)
            except Exception as e:
                log.warning(
                    "Runtime To Permanent failed on helper '%s': %s" % \
                    (name, e))
                error = True

        # direct

        # rt_config = self.fw.direct.get_config()
        conf = ( self.fw.direct.get_all_chains(),
                 self.fw.direct.get_all_rules(),
                 self.fw.direct.get_all_passthroughs() )
        try:
            if self.config.getSettings() != conf:
                log.debug1("Copying direct configuration")
                self.config.update(conf)
            else:
                log.debug1("Direct configuration is identical, ignoring.")
        except Exception as e:
            log.warning(
                "Runtime To Permanent failed on direct configuration: %s" % e)
            error = True

        # policies

        conf = self.fw.policies.lockdown_whitelist.export_config()
        try:
            if self.config.getSettings() != conf:
                log.debug1("Copying policies configuration")
                self.config.setLockdownWhitelist(conf)
            else:
                log.debug1("Policies configuration is identical, ignoring.")
        except Exception as e:
            log.warning(
                "Runtime To Permanent failed on policies configuration: %s" % \
                e)
            error = True

        if error:
            raise FirewallError(errors.RT_TO_PERM_FAILED)

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # POLICIES
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # lockdown

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='',
                         out_signature='')
    @dbus_handle_exceptions
    def enableLockdown(self, sender=None):
        """Enable lockdown policies
        """
        log.debug1("policies.enableLockdown()")
        self.accessCheck(sender)
        self.fw.policies.enable_lockdown()
        self.LockdownEnabled()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='',
                         out_signature='')
    @dbus_handle_exceptions
    def disableLockdown(self, sender=None):
        """Disable lockdown policies
        """
        log.debug1("policies.disableLockdown()")
        self.accessCheck(sender)
        self.fw.policies.disable_lockdown()
        self.LockdownDisabled()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryLockdown(self, sender=None): # pylint: disable=W0613
        """Retuns True if lockdown is enabled
        """
        log.debug1("policies.queryLockdown()")
        # no access check here
        return self.fw.policies.query_lockdown()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICIES, signature='')
    @dbus_handle_exceptions
    def LockdownEnabled(self):
        log.debug1("LockdownEnabled()")

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICIES, signature='')
    @dbus_handle_exceptions
    def LockdownDisabled(self):
        log.debug1("LockdownDisabled()")

    # lockdown whitelist

    # command

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='s',
                         out_signature='')
    @dbus_handle_exceptions
    def addLockdownWhitelistCommand(self, command, sender=None):
        """Add lockdown command
        """
        command = dbus_to_python(command, str)
        log.debug1("policies.addLockdownWhitelistCommand('%s')" % command)
        self.accessCheck(sender)
        self.fw.policies.lockdown_whitelist.add_command(command)
        self.LockdownWhitelistCommandAdded(command)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='s',
                         out_signature='')
    @dbus_handle_exceptions
    def removeLockdownWhitelistCommand(self, command, sender=None):
        """Remove lockdown command
        """
        command = dbus_to_python(command, str)
        log.debug1("policies.removeLockdownWhitelistCommand('%s')" % command)
        self.accessCheck(sender)
        self.fw.policies.lockdown_whitelist.remove_command(command)
        self.LockdownWhitelistCommandRemoved(command)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='s',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryLockdownWhitelistCommand(self, command, sender=None): # pylint: disable=W0613
        """Query lockdown command
        """
        command = dbus_to_python(command, str)
        log.debug1("policies.queryLockdownWhitelistCommand('%s')" % command)
        # no access check here
        return self.fw.policies.lockdown_whitelist.has_command(command)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='',
                         out_signature='as')
    @dbus_handle_exceptions
    def getLockdownWhitelistCommands(self, sender=None): # pylint: disable=W0613
        """Add lockdown command
        """
        log.debug1("policies.getLockdownWhitelistCommands()")
        # no access check here
        return self.fw.policies.lockdown_whitelist.get_commands()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICIES, signature='s')
    @dbus_handle_exceptions
    def LockdownWhitelistCommandAdded(self, command):
        log.debug1("LockdownWhitelistCommandAdded('%s')" % command)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICIES, signature='s')
    @dbus_handle_exceptions
    def LockdownWhitelistCommandRemoved(self, command):
        log.debug1("LockdownWhitelistCommandRemoved('%s')" % command)

    # uid

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='i',
                         out_signature='')
    @dbus_handle_exceptions
    def addLockdownWhitelistUid(self, uid, sender=None):
        """Add lockdown uid
        """
        uid = dbus_to_python(uid, int)
        log.debug1("policies.addLockdownWhitelistUid('%s')" % uid)
        self.accessCheck(sender)
        self.fw.policies.lockdown_whitelist.add_uid(uid)
        self.LockdownWhitelistUidAdded(uid)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='i',
                         out_signature='')
    @dbus_handle_exceptions
    def removeLockdownWhitelistUid(self, uid, sender=None):
        """Remove lockdown uid
        """
        uid = dbus_to_python(uid, int)
        log.debug1("policies.removeLockdownWhitelistUid('%s')" % uid)
        self.accessCheck(sender)
        self.fw.policies.lockdown_whitelist.remove_uid(uid)
        self.LockdownWhitelistUidRemoved(uid)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='i',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryLockdownWhitelistUid(self, uid, sender=None): # pylint: disable=W0613
        """Query lockdown uid
        """
        uid = dbus_to_python(uid, int)
        log.debug1("policies.queryLockdownWhitelistUid('%s')" % uid)
        # no access check here
        return self.fw.policies.lockdown_whitelist.has_uid(uid)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='',
                         out_signature='ai')
    @dbus_handle_exceptions
    def getLockdownWhitelistUids(self, sender=None): # pylint: disable=W0613
        """Add lockdown uid
        """
        log.debug1("policies.getLockdownWhitelistUids()")
        # no access check here
        return self.fw.policies.lockdown_whitelist.get_uids()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICIES, signature='i')
    @dbus_handle_exceptions
    def LockdownWhitelistUidAdded(self, uid):
        log.debug1("LockdownWhitelistUidAdded(%d)" % uid)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICIES, signature='i')
    @dbus_handle_exceptions
    def LockdownWhitelistUidRemoved(self, uid):
        log.debug1("LockdownWhitelistUidRemoved(%d)" % uid)

    # user

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='s',
                         out_signature='')
    @dbus_handle_exceptions
    def addLockdownWhitelistUser(self, user, sender=None):
        """Add lockdown user
        """
        user = dbus_to_python(user, str)
        log.debug1("policies.addLockdownWhitelistUser('%s')" % user)
        self.accessCheck(sender)
        self.fw.policies.lockdown_whitelist.add_user(user)
        self.LockdownWhitelistUserAdded(user)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='s',
                         out_signature='')
    @dbus_handle_exceptions
    def removeLockdownWhitelistUser(self, user, sender=None):
        """Remove lockdown user
        """
        user = dbus_to_python(user, str)
        log.debug1("policies.removeLockdownWhitelistUser('%s')" % user)
        self.accessCheck(sender)
        self.fw.policies.lockdown_whitelist.remove_user(user)
        self.LockdownWhitelistUserRemoved(user)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='s',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryLockdownWhitelistUser(self, user, sender=None): # pylint: disable=W0613
        """Query lockdown user
        """
        user = dbus_to_python(user, str)
        log.debug1("policies.queryLockdownWhitelistUser('%s')" % user)
        # no access check here
        return self.fw.policies.lockdown_whitelist.has_user(user)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='',
                         out_signature='as')
    @dbus_handle_exceptions
    def getLockdownWhitelistUsers(self, sender=None): # pylint: disable=W0613
        """Add lockdown user
        """
        log.debug1("policies.getLockdownWhitelistUsers()")
        # no access check here
        return self.fw.policies.lockdown_whitelist.get_users()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICIES, signature='s')
    @dbus_handle_exceptions
    def LockdownWhitelistUserAdded(self, user):
        log.debug1("LockdownWhitelistUserAdded('%s')" % user)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICIES, signature='s')
    @dbus_handle_exceptions
    def LockdownWhitelistUserRemoved(self, user):
        log.debug1("LockdownWhitelistUserRemoved('%s')" % user)

    # context

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='s',
                         out_signature='')
    @dbus_handle_exceptions
    def addLockdownWhitelistContext(self, context, sender=None):
        """Add lockdown context
        """
        context = dbus_to_python(context, str)
        log.debug1("policies.addLockdownWhitelistContext('%s')" % context)
        self.accessCheck(sender)
        self.fw.policies.lockdown_whitelist.add_context(context)
        self.LockdownWhitelistContextAdded(context)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='s',
                         out_signature='')
    @dbus_handle_exceptions
    def removeLockdownWhitelistContext(self, context, sender=None):
        """Remove lockdown context
        """
        context = dbus_to_python(context, str)
        log.debug1("policies.removeLockdownWhitelistContext('%s')" % context)
        self.accessCheck(sender)
        self.fw.policies.lockdown_whitelist.remove_context(context)
        self.LockdownWhitelistContextRemoved(context)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='s',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryLockdownWhitelistContext(self, context, sender=None): # pylint: disable=W0613
        """Query lockdown context
        """
        context = dbus_to_python(context, str)
        log.debug1("policies.queryLockdownWhitelistContext('%s')" % context)
        # no access check here
        return self.fw.policies.lockdown_whitelist.has_context(context)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_POLICIES_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICIES, in_signature='',
                         out_signature='as')
    @dbus_handle_exceptions
    def getLockdownWhitelistContexts(self, sender=None): # pylint: disable=W0613
        """Add lockdown context
        """
        log.debug1("policies.getLockdownWhitelistContexts()")
        # no access check here
        return self.fw.policies.lockdown_whitelist.get_contexts()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICIES, signature='s')
    @dbus_handle_exceptions
    def LockdownWhitelistContextAdded(self, context):
        log.debug1("LockdownWhitelistContextAdded('%s')" % context)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICIES, signature='s')
    @dbus_handle_exceptions
    def LockdownWhitelistContextRemoved(self, context):
        log.debug1("LockdownWhitelistContextRemoved('%s')" % context)

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # PANIC

    @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 enablePanicMode(self, sender=None):
        """Enable panic mode.
        
        All ingoing and outgoing connections and packets will be blocked.
        """
        log.debug1("enablePanicMode()")
        self.accessCheck(sender)
        self.fw.enable_panic_mode()
        self.PanicModeEnabled()

    @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 disablePanicMode(self, sender=None):
        """Disable panic mode.

        Enables normal mode: Allowed ingoing and outgoing connections 
        will not be blocked anymore
        """
        log.debug1("disablePanicMode()")
        self.accessCheck(sender)
        self.fw.disable_panic_mode()
        self.PanicModeDisabled()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryPanicMode(self, sender=None): # pylint: disable=W0613
        # returns True if in panic mode
        log.debug1("queryPanicMode()")
        return self.fw.query_panic_mode()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE, signature='')
    @dbus_handle_exceptions
    def PanicModeEnabled(self):
        log.debug1("PanicModeEnabled()")

    @dbus.service.signal(config.dbus.DBUS_INTERFACE, signature='')
    @dbus_handle_exceptions
    def PanicModeDisabled(self):
        log.debug1("PanicModeDisabled()")

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # list functions

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='s',
                         out_signature="(sssbsasa(ss)asba(ssss)asasasasa(ss)b)")
    @dbus_handle_exceptions
    def getZoneSettings(self, zone, sender=None): # pylint: disable=W0613
        # returns zone settings for zone
        zone = dbus_to_python(zone, str)
        log.debug1("getZoneSettings(%s)", zone)
        return self.fw.zone.get_config_with_settings(zone)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature="a{sv}")
    @dbus_handle_exceptions
    def getZoneSettings2(self, zone, sender=None):
        zone = dbus_to_python(zone, str)
        log.debug1("getZoneSettings2(%s)", zone)
        return self.fw.zone.get_config_with_settings_dict(zone)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sa{sv}')
    @dbus_handle_exceptions
    def setZoneSettings2(self, zone, settings, sender=None):
        zone = dbus_to_python(zone, str)
        log.debug1("setZoneSettings2(%s)", zone)
        self.accessCheck(sender)
        self.fw.zone.set_config_with_settings_dict(zone, settings, sender)
        self.ZoneUpdated(zone, settings)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='sa{sv}')
    @dbus_handle_exceptions
    def ZoneUpdated(self, zone, settings):
        log.debug1("zone.ZoneUpdated('%s', '%s')" % (zone, settings))

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICY, in_signature='s',
                         out_signature="a{sv}")
    @dbus_handle_exceptions
    def getPolicySettings(self, policy, sender=None):
        policy = dbus_to_python(policy, str)
        log.debug1("policy.getPolicySettings(%s)", policy)
        return self.fw.policy.get_config_with_settings_dict(policy)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICY, in_signature='sa{sv}')
    @dbus_handle_exceptions
    def setPolicySettings(self, policy, settings, sender=None):
        policy = dbus_to_python(policy, str)
        log.debug1("policy.setPolicySettings(%s)", policy)
        self.accessCheck(sender)
        self.fw.policy.set_config_with_settings_dict(policy, settings, sender)
        self.PolicyUpdated(policy, settings)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICY, signature='sa{sv}')
    @dbus_handle_exceptions
    def PolicyUpdated(self, policy, settings):
        log.debug1("policy.PolicyUpdated('%s', '%s')" % (policy, settings))

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='',
                         out_signature='as')
    @dbus_handle_exceptions
    def listServices(self, sender=None): # pylint: disable=W0613
        # returns the list of services
        # TODO: should be renamed to getServices()
        # because is called by firewall-cmd --get-services
        log.debug1("listServices()")
        return self.fw.service.get_services()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='s',
                         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
        service = dbus_to_python(service, str)
        log.debug1("getServiceSettings(%s)", service)
        obj = self.fw.service.get_service(service)
        conf_dict = obj.export_config_dict()
        conf_list = []
        for i in range(8): # tuple based dbus API has 8 elements
            if obj.IMPORT_EXPORT_STRUCTURE[i][0] not in conf_dict:
                # old API needs the empty elements as well. Grab it from the
                # object otherwise we don't know the type.
                conf_list.append(copy.deepcopy(getattr(obj, obj.IMPORT_EXPORT_STRUCTURE[i][0])))
            else:
                conf_list.append(conf_dict[obj.IMPORT_EXPORT_STRUCTURE[i][0]])
        return tuple(conf_list)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_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_dict()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='',
                         out_signature='as')
    @dbus_handle_exceptions
    def listIcmpTypes(self, sender=None): # pylint: disable=W0613
        # returns the list of services
        # TODO: should be renamed to getIcmptypes()
        # because is called by firewall-cmd --get-icmptypes
        log.debug1("listIcmpTypes()")
        return self.fw.icmptype.get_icmptypes()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='s',
                         out_signature=IcmpType.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def getIcmpTypeSettings(self, icmptype, sender=None): # pylint: disable=W0613
        # returns icmptype settings for icmptype
        icmptype = dbus_to_python(icmptype, str)
        log.debug1("getIcmpTypeSettings(%s)", icmptype)
        return self.fw.icmptype.get_icmptype(icmptype).export_config()

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # LOG DENIED

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='',
                         out_signature='s')
    @dbus_handle_exceptions
    def getLogDenied(self, sender=None): # pylint: disable=W0613
        # returns the log denied value
        log.debug1("getLogDenied()")
        return self.fw.get_log_denied()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='s',
                         out_signature='')
    @dbus_handle_exceptions
    def setLogDenied(self, value, sender=None):
        # set the log denied value
        value = dbus_to_python(value, str)
        log.debug1("setLogDenied('%s')" % value)
        self.accessCheck(sender)
        self.fw.set_log_denied(value)
        self.LogDeniedChanged(value)
        # must reload the firewall as well
        self.fw.reload()
        self.config.reload()
        self.Reloaded()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE, signature='s')
    @dbus_handle_exceptions
    def LogDeniedChanged(self, value):
        log.debug1("LogDeniedChanged('%s')" % (value))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # AUTOMATIC HELPER ASSIGNMENT

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='',
                         out_signature='s')
    @dbus_handle_exceptions
    def getAutomaticHelpers(self, sender=None): # pylint: disable=W0613
        # returns the automatic helpers value
        log.debug1("getAutomaticHelpers()")
        # NOTE: This feature was removed and is now a noop. We retain the dbus
        # call to keep API.
        return "no"

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='s',
                         out_signature='')
    @dbus_handle_exceptions
    def setAutomaticHelpers(self, value, sender=None):
        # set the automatic helpers value
        value = dbus_to_python(value, str)
        log.debug1("setAutomaticHelpers('%s')" % value)
        self.accessCheck(sender)
        # NOTE: This feature was removed and is now a noop. We retain the dbus
        # call to keep API.

    @dbus.service.signal(config.dbus.DBUS_INTERFACE, signature='s')
    @dbus_handle_exceptions
    def AutomaticHelpersChanged(self, value):
        log.debug1("AutomaticHelpersChanged('%s')" % (value))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # DEFAULT ZONE

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='',
                         out_signature='s')
    @dbus_handle_exceptions
    def getDefaultZone(self, sender=None): # pylint: disable=W0613
        # returns the system default zone
        log.debug1("getDefaultZone()")
        return self.fw.get_default_zone()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='s',
                         out_signature='')
    @dbus_handle_exceptions
    def setDefaultZone(self, zone, sender=None):
        # set the system default zone
        zone = dbus_to_python(zone, str)
        log.debug1("setDefaultZone('%s')" % zone)
        self.accessCheck(sender)
        self.fw.set_default_zone(zone)
        self.DefaultZoneChanged(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE, signature='s')
    @dbus_handle_exceptions
    def DefaultZoneChanged(self, zone):
        log.debug1("DefaultZoneChanged('%s')" % (zone))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # POLICY INTERFACE
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # POLICIES

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICY, in_signature='',
                         out_signature='as')
    @dbus_handle_exceptions
    def getPolicies(self, sender=None):
        log.debug1("policy.getPolicies()")
        return self.fw.policy.get_policies_not_derived_from_zone()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICY, in_signature='',
                         out_signature='a{sa{sas}}')
    @dbus_handle_exceptions
    def getActivePolicies(self, sender=None):
        log.debug1("policy.getActivePolicies()")
        policies = { }
        for policy in self.fw.policy.get_active_policies_not_derived_from_zone():
            policies[policy] = { }
            policies[policy]["ingress_zones"] = self.fw.policy.list_ingress_zones(policy)
            policies[policy]["egress_zones"] = self.fw.policy.list_egress_zones(policy)
        return policies

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # ZONE INTERFACE
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # ZONES

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    # TODO: shouldn't this be in DBUS_INTERFACE instead of DBUS_INTERFACE_ZONE ?
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='',
                         out_signature='as')
    @dbus_handle_exceptions
    def getZones(self, sender=None): # pylint: disable=W0613
        # returns the list of zones
        log.debug1("zone.getZones()")
        return self.fw.zone.get_zones()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='',
                         out_signature='a{sa{sas}}')
    @dbus_handle_exceptions
    def getActiveZones(self, sender=None): # pylint: disable=W0613
        # returns the list of active zones
        log.debug1("zone.getActiveZones()")
        zones = { }
        for zone in self.fw.zone.get_zones():
            interfaces = self.fw.zone.list_interfaces(zone)
            sources = self.fw.zone.list_sources(zone)
            if len(interfaces) + len(sources) > 0:
                zones[zone] = { }
                if len(interfaces) > 0:
                    zones[zone]["interfaces"] = interfaces
                if len(sources) > 0:
                    zones[zone]["sources"] = sources
        return zones

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='s')
    @dbus_handle_exceptions
    def getZoneOfInterface(self, interface, sender=None): # pylint: disable=W0613
        """Return the zone an interface belongs to.

        :Parameters:
            `interface` : str
                Name of the interface
        :Returns: str. The name of the zone.
        """
        interface = dbus_to_python(interface, str)
        log.debug1("zone.getZoneOfInterface('%s')" % interface)
        zone = self.fw.zone.get_zone_of_interface(interface)
        if zone:
            return zone
        return ""

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='s')
    @dbus_handle_exceptions
    def getZoneOfSource(self, source, sender=None): # pylint: disable=W0613
        #Return the zone an source belongs to.
        source = dbus_to_python(source, str)
        log.debug1("zone.getZoneOfSource('%s')" % source)
        zone = self.fw.zone.get_zone_of_source(source)
        if zone:
            return zone
        return ""

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='b')
    @dbus_handle_exceptions
    def isImmutable(self, zone, sender=None): # pylint: disable=W0613
        # no immutable zones anymore
        return False

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # INTERFACES

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='s')
    @dbus_handle_exceptions
    def addInterface(self, zone, interface, sender=None):
        """Add an interface to a zone.
        If zone is empty, use default zone.
        """
        zone = dbus_to_python(zone, str)
        interface = dbus_to_python(interface, str)
        log.debug1("zone.addInterface('%s', '%s')" % (zone, interface))
        self.accessCheck(sender)
        _zone = self.fw.zone.add_interface(zone, interface, sender)

        self.InterfaceAdded(_zone, interface)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='s')
    @dbus_handle_exceptions
    def changeZone(self, zone, interface, sender=None):
        """Change a zone an interface is part of.
        If zone is empty, use default zone.

        This function is deprecated, use changeZoneOfInterface instead
        """
        zone = dbus_to_python(zone, str)
        interface = dbus_to_python(interface, str)
        return self.changeZoneOfInterface(zone, interface, sender)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='s')
    @dbus_handle_exceptions
    def changeZoneOfInterface(self, zone, interface, sender=None):
        """Change a zone an interface is part of.
        If zone is empty, use default zone.
        """
        zone = dbus_to_python(zone, str)
        interface = dbus_to_python(interface, str)
        log.debug1("zone.changeZoneOfInterface('%s', '%s')" % (zone, interface))
        self.accessCheck(sender)
        _zone = self.fw.zone.change_zone_of_interface(zone, interface, sender)

        self.ZoneOfInterfaceChanged(_zone, interface)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='s')
    @dbus_handle_exceptions
    def removeInterface(self, zone, interface, sender=None):
        """Remove interface from a zone.
        If zone is empty, remove from zone the interface belongs to.
        """
        zone = dbus_to_python(zone, str)
        interface = dbus_to_python(interface, str)
        log.debug1("zone.removeInterface('%s', '%s')" % (zone, interface))
        self.accessCheck(sender)
        _zone = self.fw.zone.remove_interface(zone, interface)

        self.InterfaceRemoved(_zone, interface)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryInterface(self, zone, interface, sender=None): # pylint: disable=W0613
        """Return true if an interface is in a zone.
        If zone is empty, use default zone.
        """
        zone = dbus_to_python(zone, str)
        interface = dbus_to_python(interface, str)
        log.debug1("zone.queryInterface('%s', '%s')" % (zone, interface))
        return self.fw.zone.query_interface(zone, interface)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='as')
    @dbus_handle_exceptions
    def getInterfaces(self, zone, sender=None): # pylint: disable=W0613
        """Return the list of interfaces of a zone.
        If zone is empty, use default zone.
        """
        # TODO: should be renamed to listInterfaces()
        # because is called by firewall-cmd --zone --list-interfaces
        zone = dbus_to_python(zone, str)
        log.debug1("zone.getInterfaces('%s')" % (zone))
        return self.fw.zone.list_interfaces(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ss')
    @dbus_handle_exceptions
    def InterfaceAdded(self, zone, interface):
        log.debug1("zone.InterfaceAdded('%s', '%s')" % (zone, interface))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ss')
    @dbus_handle_exceptions
    def ZoneChanged(self, zone, interface):
        """
        This signal is deprecated.
        """
        log.debug1("zone.ZoneChanged('%s', '%s')" % (zone, interface))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ss')
    @dbus_handle_exceptions
    def ZoneOfInterfaceChanged(self, zone, interface):
        log.debug1("zone.ZoneOfInterfaceChanged('%s', '%s')" % (zone,
                                                                interface))
        self.ZoneChanged(zone, interface)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ss')
    @dbus_handle_exceptions
    def InterfaceRemoved(self, zone, interface):
        log.debug1("zone.InterfaceRemoved('%s', '%s')" % (zone, interface))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # SOURCES

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='s')
    @dbus_handle_exceptions
    def addSource(self, zone, source, sender=None):
        """Add a source to a zone.
        If zone is empty, use default zone.
        """
        zone = dbus_to_python(zone, str)
        source = dbus_to_python(source, str)
        log.debug1("zone.addSource('%s', '%s')" % (zone, source))
        self.accessCheck(sender)
        _zone = self.fw.zone.add_source(zone, source, sender)

        self.SourceAdded(_zone, source)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='s')
    @dbus_handle_exceptions
    def changeZoneOfSource(self, zone, source, sender=None):
        """Change a zone an source is part of.
        If zone is empty, use default zone.
        """
        zone = dbus_to_python(zone, str)
        source = dbus_to_python(source, str)
        log.debug1("zone.changeZoneOfSource('%s', '%s')" % (zone, source))
        self.accessCheck(sender)
        _zone = self.fw.zone.change_zone_of_source(zone, source, sender)

        self.ZoneOfSourceChanged(_zone, source)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='s')
    @dbus_handle_exceptions
    def removeSource(self, zone, source, sender=None):
        """Remove source from a zone.
        If zone is empty, remove from zone the source belongs to.
        """
        zone = dbus_to_python(zone, str)
        source = dbus_to_python(source, str)
        log.debug1("zone.removeSource('%s', '%s')" % (zone, source))
        self.accessCheck(sender)
        _zone = self.fw.zone.remove_source(zone, source)

        self.SourceRemoved(_zone, source)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='b')
    @dbus_handle_exceptions
    def querySource(self, zone, source, sender=None): # pylint: disable=W0613
        """Return true if an source is in a zone.
        If zone is empty, use default zone.
        """
        zone = dbus_to_python(zone, str)
        source = dbus_to_python(source, str)
        log.debug1("zone.querySource('%s', '%s')" % (zone, source))
        return self.fw.zone.query_source(zone, source)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='as')
    @dbus_handle_exceptions
    def getSources(self, zone, sender=None): # pylint: disable=W0613
        """Return the list of sources of a zone.
        If zone is empty, use default zone.
        """
        # TODO: should be renamed to listSources()
        # because is called by firewall-cmd --zone --list-sources
        zone = dbus_to_python(zone, str)
        log.debug1("zone.getSources('%s')" % (zone))
        return self.fw.zone.list_sources(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ss')
    @dbus_handle_exceptions
    def SourceAdded(self, zone, source):
        log.debug1("zone.SourceAdded('%s', '%s')" % (zone, source))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ss')
    @dbus_handle_exceptions
    def ZoneOfSourceChanged(self, zone, source):
        log.debug1("zone.ZoneOfSourceChanged('%s', '%s')" % (zone, source))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ss')
    @dbus_handle_exceptions
    def SourceRemoved(self, zone, source):
        log.debug1("zone.SourceRemoved('%s', '%s')" % (zone, source))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # RICH RULES

    @dbus_handle_exceptions
    def disableTimedRichRule(self, zone, rule):
        log.debug1("zone.disableTimedRichRule('%s', '%s')" % (zone, rule))
        del self._timeouts[zone][rule]
        obj = Rich_Rule(rule_str=rule)
        self.fw.zone.remove_rule(zone, obj)
        self.RichRuleRemoved(zone, rule)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ssi',
                         out_signature='s')
    @dbus_handle_exceptions
    def addRichRule(self, zone, rule, timeout, sender=None): # pylint: disable=W0613
        zone = dbus_to_python(zone, str)
        rule = dbus_to_python(rule, str)
        timeout = dbus_to_python(timeout, int)
        log.debug1("zone.addRichRule('%s', '%s')" % (zone, rule))
        obj = Rich_Rule(rule_str=rule)
        _zone = self.fw.zone.add_rule(zone, obj, timeout)

        if timeout > 0:
            tag = GLib.timeout_add_seconds(timeout, self.disableTimedRichRule,
                                           _zone, rule)
            self.addTimeout(_zone, rule, tag)

        self.RichRuleAdded(_zone, rule, timeout)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='s')
    @dbus_handle_exceptions
    def removeRichRule(self, zone, rule, sender=None): # pylint: disable=W0613
        zone = dbus_to_python(zone, str)
        rule = dbus_to_python(rule, str)
        log.debug1("zone.removeRichRule('%s', '%s')" % (zone, rule))
        obj = Rich_Rule(rule_str=rule)
        _zone = self.fw.zone.remove_rule(zone, obj)
        self.removeTimeout(_zone, rule)
        self.RichRuleRemoved(_zone, rule)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryRichRule(self, zone, rule, sender=None): # pylint: disable=W0613
        zone = dbus_to_python(zone, str)
        rule = dbus_to_python(rule, str)
        log.debug1("zone.queryRichRule('%s', '%s')" % (zone, rule))
        obj = Rich_Rule(rule_str=rule)
        return self.fw.zone.query_rule(zone, obj)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='as')
    @dbus_handle_exceptions
    def getRichRules(self, zone, sender=None): # pylint: disable=W0613
        # returns the list of enabled rich rules for zone
        # TODO: should be renamed to listRichRules()
        # because is called by firewall-cmd --zone --list-rich-rules
        zone = dbus_to_python(zone, str)
        log.debug1("zone.getRichRules('%s')" % (zone))
        return self.fw.zone.list_rules(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ssi')
    @dbus_handle_exceptions
    def RichRuleAdded(self, zone, rule, timeout):
        log.debug1("zone.RichRuleAdded('%s', '%s', %d)" % (zone, rule, timeout))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ss')
    @dbus_handle_exceptions
    def RichRuleRemoved(self, zone, rule):
        log.debug1("zone.RichRuleRemoved('%s', '%s')" % (zone, rule))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # SERVICES

    @dbus_handle_exceptions
    def disableTimedService(self, zone, service):
        log.debug1("zone.disableTimedService('%s', '%s')" % (zone, service))
        del self._timeouts[zone][service]
        self.fw.zone.remove_service(zone, service)
        self.ServiceRemoved(zone, service)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ssi',
                         out_signature='s')
    @dbus_handle_exceptions
    def addService(self, zone, service, timeout, sender=None):
        # enables service <service> if not enabled already for zone
        zone = dbus_to_python(zone, str)
        service = dbus_to_python(service, str)
        timeout = dbus_to_python(timeout, int)
        log.debug1("zone.addService('%s', '%s', %d)" % (zone, service, timeout))
        self.accessCheck(sender)

        _zone = self.fw.zone.add_service(zone, service, timeout, sender)

        if timeout > 0:
            tag = GLib.timeout_add_seconds(timeout, self.disableTimedService,
                                           _zone, service)
            self.addTimeout(_zone, service, tag)

        self.ServiceAdded(_zone, service, timeout)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='s')
    @dbus_handle_exceptions
    def removeService(self, zone, service, sender=None):
        # disables service for zone
        zone = dbus_to_python(zone, str)
        service = dbus_to_python(service, str)
        log.debug1("zone.removeService('%s', '%s')" % (zone, service))
        self.accessCheck(sender)

        _zone = self.fw.zone.remove_service(zone, service)

        self.removeTimeout(_zone, service)
        self.ServiceRemoved(_zone, service)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryService(self, zone, service, sender=None): # pylint: disable=W0613
        # returns true if a service is enabled for zone
        zone = dbus_to_python(zone, str)
        service = dbus_to_python(service, str)
        log.debug1("zone.queryService('%s', '%s')" % (zone, service))
        return self.fw.zone.query_service(zone, service)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='as')
    @dbus_handle_exceptions
    def getServices(self, zone, sender=None): # pylint: disable=W0613
        # returns the list of enabled services for zone
        # TODO: should be renamed to listServices()
        # because is called by firewall-cmd --zone --list-services
        zone = dbus_to_python(zone, str)
        log.debug1("zone.getServices('%s')" % (zone))
        return self.fw.zone.list_services(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ssi')
    @dbus_handle_exceptions
    def ServiceAdded(self, zone, service, timeout):
        log.debug1("zone.ServiceAdded('%s', '%s', %d)" % \
                       (zone, service, timeout))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ss')
    @dbus_handle_exceptions
    def ServiceRemoved(self, zone, service):
        log.debug1("zone.ServiceRemoved('%s', '%s')" % (zone, service))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # PORTS

    @dbus_handle_exceptions
    def disableTimedPort(self, zone, port, protocol):
        log.debug1("zone.disableTimedPort('%s', '%s', '%s')" % \
                       (zone, port, protocol))
        del self._timeouts[zone][(port, protocol)]
        self.fw.zone.remove_port(zone, port, protocol)
        self.PortRemoved(zone, port, protocol)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sssi',
                         out_signature='s')
    @dbus_handle_exceptions
    def addPort(self, zone, port, protocol, timeout, sender=None): # pylint: disable=R0913
        # adds port <port> <protocol> if not enabled already to zone
        zone = dbus_to_python(zone, str)
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        timeout = dbus_to_python(timeout, int)
        log.debug1("zone.addPort('%s', '%s', '%s')" % \
                       (zone, port, protocol))
        self.accessCheck(sender)
        _zone = self.fw.zone.add_port(zone, port, protocol, timeout, sender)

        if timeout > 0:
            tag = GLib.timeout_add_seconds(timeout, self.disableTimedPort,
                                           _zone, port, protocol)
            self.addTimeout(_zone, (port, protocol), tag)

        self.PortAdded(_zone, port, protocol, timeout)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sss',
                         out_signature='s')
    @dbus_handle_exceptions
    def removePort(self, zone, port, protocol, sender=None): # pylint: disable=R0913
        # removes port<port> <protocol> if enabled from zone
        zone = dbus_to_python(zone, str)
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("zone.removePort('%s', '%s', '%s')" % \
                       (zone, port, protocol))
        self.accessCheck(sender)
        _zone= self.fw.zone.remove_port(zone, port, protocol)

        self.removeTimeout(_zone, (port, protocol))
        self.PortRemoved(_zone, port, protocol)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sss',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryPort(self, zone, port, protocol, sender=None): # pylint: disable=W0613, R0913
        # returns true if a port is enabled for zone
        zone = dbus_to_python(zone, str)
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("zone.queryPort('%s', '%s', '%s')" % (zone, port, protocol))
        return self.fw.zone.query_port(zone, port, protocol)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='aas')
    @dbus_handle_exceptions
    def getPorts(self, zone, sender=None): # pylint: disable=W0613
        # returns the list of enabled ports
        # TODO: should be renamed to listPorts()
        # because is called by firewall-cmd --zone --list-ports
        zone = dbus_to_python(zone, str)
        log.debug1("zone.getPorts('%s')" % (zone))
        return self.fw.zone.list_ports(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='sssi')
    @dbus_handle_exceptions
    def PortAdded(self, zone, port, protocol, timeout=0):
        log.debug1("zone.PortAdded('%s', '%s', '%s', %d)" % \
                       (zone, port, protocol, timeout))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='sss')
    @dbus_handle_exceptions
    def PortRemoved(self, zone, port, protocol):
        log.debug1("zone.PortRemoved('%s', '%s', '%s')" % \
                       (zone, port, protocol))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # PROTOCOLS

    @dbus_handle_exceptions
    def disableTimedProtocol(self, zone, protocol):
        log.debug1("zone.disableTimedProtocol('%s', '%s')" % (zone, protocol))
        del self._timeouts[zone][(protocol)]
        self.fw.zone.remove_protocol(zone, protocol)
        self.ProtocolRemoved(zone, protocol)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ssi',
                         out_signature='s')
    @dbus_handle_exceptions
    def addProtocol(self, zone, protocol, timeout, sender=None):
        # adds protocol <protocol> if not enabled already to zone
        zone = dbus_to_python(zone, str)
        protocol = dbus_to_python(protocol, str)
        timeout = dbus_to_python(timeout, int)
        log.debug1("zone.enableProtocol('%s', '%s')" % (zone, protocol))
        self.accessCheck(sender)
        _zone = self.fw.zone.add_protocol(zone, protocol, timeout, sender)

        if timeout > 0:
            tag = GLib.timeout_add_seconds(timeout, self.disableTimedProtocol,
                                           _zone, protocol)
            self.addTimeout(_zone, protocol, tag)

        self.ProtocolAdded(_zone, protocol, timeout)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='s')
    @dbus_handle_exceptions
    def removeProtocol(self, zone, protocol, sender=None):
        # removes protocol<protocol> if enabled from zone
        zone = dbus_to_python(zone, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("zone.removeProtocol('%s', '%s')" % (zone, protocol))
        self.accessCheck(sender)
        _zone= self.fw.zone.remove_protocol(zone, protocol)

        self.removeTimeout(_zone, protocol)
        self.ProtocolRemoved(_zone, protocol)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryProtocol(self, zone, protocol, sender=None): # pylint: disable=W0613
        # returns true if a protocol is enabled for zone
        zone = dbus_to_python(zone, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("zone.queryProtocol('%s', '%s')" % (zone, protocol))
        return self.fw.zone.query_protocol(zone, protocol)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='as')
    @dbus_handle_exceptions
    def getProtocols(self, zone, sender=None): # pylint: disable=W0613
        # returns the list of enabled protocols
        # TODO: should be renamed to listProtocols()
        # because is called by firewall-cmd --zone --list-protocols
        zone = dbus_to_python(zone, str)
        log.debug1("zone.getProtocols('%s')" % (zone))
        return self.fw.zone.list_protocols(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ssi')
    @dbus_handle_exceptions
    def ProtocolAdded(self, zone, protocol, timeout=0):
        log.debug1("zone.ProtocolAdded('%s', '%s', %d)" % \
                       (zone, protocol, timeout))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ss')
    @dbus_handle_exceptions
    def ProtocolRemoved(self, zone, protocol):
        log.debug1("zone.ProtocolRemoved('%s', '%s')" % (zone, protocol))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # SOURCE PORTS

    @dbus_handle_exceptions
    def disableTimedSourcePort(self, zone, port, protocol):
        log.debug1("zone.disableTimedSourcePort('%s', '%s', '%s')" % \
                   (zone, port, protocol))
        del self._timeouts[zone][("sport", port, protocol)]
        self.fw.zone.remove_source_port(zone, port, protocol)
        self.SourcePortRemoved(zone, port, protocol)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sssi',
                         out_signature='s')
    @dbus_handle_exceptions
    def addSourcePort(self, zone, port, protocol, timeout, sender=None): # pylint: disable=R0913
        # adds source port <port> <protocol> if not enabled already to zone
        zone = dbus_to_python(zone, str)
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        timeout = dbus_to_python(timeout, int)
        log.debug1("zone.addSourcePort('%s', '%s', '%s')" % (zone, port,
                                                             protocol))
        self.accessCheck(sender)
        _zone = self.fw.zone.add_source_port(zone, port, protocol, timeout,
                                             sender)

        if timeout > 0:
            tag = GLib.timeout_add_seconds(timeout, self.disableTimedSourcePort,
                                           _zone, port, protocol)
            self.addTimeout(_zone, ("sport", port, protocol), tag)

        self.SourcePortAdded(_zone, port, protocol, timeout)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sss',
                         out_signature='s')
    @dbus_handle_exceptions
    def removeSourcePort(self, zone, port, protocol, sender=None): # pylint: disable=R0913
        # removes source port<port> <protocol> if enabled from zone
        zone = dbus_to_python(zone, str)
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("zone.removeSourcePort('%s', '%s', '%s')" % (zone, port,
                                                                protocol))
        self.accessCheck(sender)
        _zone= self.fw.zone.remove_source_port(zone, port, protocol)

        self.removeTimeout(_zone, ("sport", port, protocol))
        self.SourcePortRemoved(_zone, port, protocol)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sss',
                         out_signature='b')
    @dbus_handle_exceptions
    def querySourcePort(self, zone, port, protocol, sender=None): # pylint: disable=W0613, R0913
        # returns true if a source port is enabled for zone
        zone = dbus_to_python(zone, str)
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("zone.querySourcePort('%s', '%s', '%s')" % (zone, port,
                                                               protocol))
        return self.fw.zone.query_source_port(zone, port, protocol)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='aas')
    @dbus_handle_exceptions
    def getSourcePorts(self, zone, sender=None): # pylint: disable=W0613
        # returns the list of enabled source ports
        # TODO: should be renamed to listSourcePorts()
        # because is called by firewall-cmd --zone --list-source-ports
        zone = dbus_to_python(zone, str)
        log.debug1("zone.getSourcePorts('%s')" % (zone))
        return self.fw.zone.list_source_ports(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='sssi')
    @dbus_handle_exceptions
    def SourcePortAdded(self, zone, port, protocol, timeout=0):
        log.debug1("zone.SourcePortAdded('%s', '%s', '%s', %d)" % \
                   (zone, port, protocol, timeout))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='sss')
    @dbus_handle_exceptions
    def SourcePortRemoved(self, zone, port, protocol):
        log.debug1("zone.SourcePortRemoved('%s', '%s', '%s')" % (zone, port,
                                                                 protocol))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # MASQUERADE

    @dbus_handle_exceptions
    def disableTimedMasquerade(self, zone):
        del self._timeouts[zone]["masquerade"]
        self.fw.zone.remove_masquerade(zone)
        self.MasqueradeRemoved(zone)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='si',
                         out_signature='s')
    @dbus_handle_exceptions
    def addMasquerade(self, zone, timeout, sender=None):
        # adds masquerade if not added already
        zone = dbus_to_python(zone, str)
        timeout = dbus_to_python(timeout, int)
        log.debug1("zone.addMasquerade('%s')" % (zone))
        self.accessCheck(sender)
        _zone = self.fw.zone.add_masquerade(zone, timeout, sender)
        
        if timeout > 0:
            tag = GLib.timeout_add_seconds(timeout, self.disableTimedMasquerade,
                                           _zone)
            self.addTimeout(_zone, "masquerade", tag)

        self.MasqueradeAdded(_zone, timeout)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='s')
    @dbus_handle_exceptions
    def removeMasquerade(self, zone, sender=None):
        # removes masquerade
        zone = dbus_to_python(zone, str)
        log.debug1("zone.removeMasquerade('%s')" % (zone))
        self.accessCheck(sender)
        _zone = self.fw.zone.remove_masquerade(zone)

        self.removeTimeout(_zone, "masquerade")
        self.MasqueradeRemoved(_zone)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryMasquerade(self, zone, sender=None): # pylint: disable=W0613
        # returns true if a masquerade is added
        zone = dbus_to_python(zone, str)
        log.debug1("zone.queryMasquerade('%s')" % (zone))
        return self.fw.zone.query_masquerade(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='si')
    @dbus_handle_exceptions
    def MasqueradeAdded(self, zone, timeout=0):
        log.debug1("zone.MasqueradeAdded('%s', %d)" % (zone, timeout))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='s')
    @dbus_handle_exceptions
    def MasqueradeRemoved(self, zone):
        log.debug1("zone.MasqueradeRemoved('%s')" % (zone))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # FORWARD PORT

    @dbus_handle_exceptions
    def disable_forward_port(self, zone, port, protocol, toport, toaddr): # pylint: disable=R0913
        del self._timeouts[zone][(port, protocol, toport, toaddr)]
        self.fw.zone.remove_forward_port(zone, port, protocol, toport, toaddr)
        self.ForwardPortRemoved(zone, port, protocol, toport, toaddr)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sssssi',
                         out_signature='s')
    @dbus_handle_exceptions
    def addForwardPort(self, zone, port, protocol, toport, toaddr, timeout,
                       sender=None): # pylint: disable=R0913
        # add forward port if not enabled already for zone
        zone = dbus_to_python(zone, str)
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        toport = dbus_to_python(toport, str)
        toaddr = dbus_to_python(toaddr, str)
        timeout = dbus_to_python(timeout, int)
        log.debug1("zone.addForwardPort('%s', '%s', '%s', '%s', '%s')" % \
                       (zone, port, protocol, toport, toaddr))
        self.accessCheck(sender)
        _zone = self.fw.zone.add_forward_port(zone, port, protocol, toport,
                                              toaddr, timeout, sender)

        if timeout > 0:
            tag = GLib.timeout_add_seconds(timeout,
                                           self.disable_forward_port,
                                           _zone, port, protocol, toport,
                                           toaddr)
            self.addTimeout(_zone, (port, protocol, toport, toaddr), tag)

        self.ForwardPortAdded(_zone, port, protocol, toport, toaddr, timeout)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sssss',
                         out_signature='s')
    @dbus_handle_exceptions
    def removeForwardPort(self, zone, port, protocol, toport, toaddr,
                          sender=None): # pylint: disable=R0913
        # remove forward port from zone
        zone = dbus_to_python(zone, str)
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        toport = dbus_to_python(toport, str)
        toaddr = dbus_to_python(toaddr, str)
        log.debug1("zone.removeForwardPort('%s', '%s', '%s', '%s', '%s')" % \
                       (zone, port, protocol, toport, toaddr))
        self.accessCheck(sender)
        _zone = self.fw.zone.remove_forward_port(zone, port, protocol, toport,
                                                 toaddr)

        self.removeTimeout(_zone, (port, protocol, toport, toaddr))
        self.ForwardPortRemoved(_zone, port, protocol, toport, toaddr)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sssss',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryForwardPort(self, zone, port, protocol, toport, toaddr,
                         sender=None): # pylint: disable=W0613, R0913
        # returns true if a forward port is enabled for zone
        zone = dbus_to_python(zone, str)
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        toport = dbus_to_python(toport, str)
        toaddr = dbus_to_python(toaddr, str)
        log.debug1("zone.queryForwardPort('%s', '%s', '%s', '%s', '%s')" % \
                       (zone, port, protocol, toport, toaddr))
        return self.fw.zone.query_forward_port(zone, port, protocol, toport,
                                               toaddr)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='aas')
    @dbus_handle_exceptions
    def getForwardPorts(self, zone, sender=None): # pylint: disable=W0613
        # returns the list of enabled ports for zone
        # TODO: should be renamed to listForwardPorts()
        # because is called by firewall-cmd --zone --list-forward-ports
        zone = dbus_to_python(zone, str)
        log.debug1("zone.getForwardPorts('%s')" % (zone))
        return self.fw.zone.list_forward_ports(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='sssssi')
    @dbus_handle_exceptions
    def ForwardPortAdded(self, zone, port, protocol, toport, toaddr,
                         timeout=0): # pylint: disable=R0913
        log.debug1("zone.ForwardPortAdded('%s', '%s', '%s', '%s', '%s', %d)" % \
                       (zone, port, protocol, toport, toaddr, timeout))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='sssss')
    @dbus_handle_exceptions
    def ForwardPortRemoved(self, zone, port, protocol, toport, toaddr): # pylint: disable=R0913
        log.debug1("zone.ForwardPortRemoved('%s', '%s', '%s', '%s', '%s')" % \
                       (zone, port, protocol, toport, toaddr))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # ICMP BLOCK

    @dbus_handle_exceptions
    def disableTimedIcmpBlock(self, zone, icmp, sender): # pylint: disable=W0613
        log.debug1("zone.disableTimedIcmpBlock('%s', '%s')" % (zone, icmp))
        del self._timeouts[zone][icmp]
        self.fw.zone.remove_icmp_block(zone, icmp)
        self.IcmpBlockRemoved(zone, icmp)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ssi',
                         out_signature='s')
    @dbus_handle_exceptions
    def addIcmpBlock(self, zone, icmp, timeout, sender=None):
        # add icmpblock <icmp> if not enabled already for zone
        zone = dbus_to_python(zone, str)
        icmp = dbus_to_python(icmp, str)
        timeout = dbus_to_python(timeout, int)
        log.debug1("zone.enableIcmpBlock('%s', '%s')" % (zone, icmp))
        self.accessCheck(sender)
        _zone = self.fw.zone.add_icmp_block(zone, icmp, timeout, sender)

        if timeout > 0:
            tag = GLib.timeout_add_seconds(timeout, self.disableTimedIcmpBlock,
                                           _zone, icmp, sender)
            self.addTimeout(_zone, icmp, tag)

        self.IcmpBlockAdded(_zone, icmp, timeout)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='s')
    @dbus_handle_exceptions
    def removeIcmpBlock(self, zone, icmp, sender=None):
        # removes icmpBlock from zone
        zone = dbus_to_python(zone, str)
        icmp = dbus_to_python(icmp, str)
        log.debug1("zone.removeIcmpBlock('%s', '%s')" % (zone, icmp))
        self.accessCheck(sender)
        _zone = self.fw.zone.remove_icmp_block(zone, icmp)

        self.removeTimeout(_zone, icmp)
        self.IcmpBlockRemoved(_zone, icmp)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ss',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryIcmpBlock(self, zone, icmp, sender=None): # pylint: disable=W0613
        # returns true if a icmp is enabled for zone
        zone = dbus_to_python(zone, str)
        icmp = dbus_to_python(icmp, str)
        log.debug1("zone.queryIcmpBlock('%s', '%s')" % (zone, icmp))
        return self.fw.zone.query_icmp_block(zone, icmp)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='as')
    @dbus_handle_exceptions
    def getIcmpBlocks(self, zone, sender=None): # pylint: disable=W0613
        # returns the list of enabled icmpblocks
        # TODO: should be renamed to listIcmpBlocks()
        # because is called by firewall-cmd --zone --list-icmp-blocks
        zone = dbus_to_python(zone, str)
        log.debug1("zone.getIcmpBlocks('%s')" % (zone))
        return self.fw.zone.list_icmp_blocks(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ssi')
    @dbus_handle_exceptions
    def IcmpBlockAdded(self, zone, icmp, timeout=0):
        log.debug1("zone.IcmpBlockAdded('%s', '%s', %d)" % \
                       (zone, icmp, timeout))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='ss')
    @dbus_handle_exceptions
    def IcmpBlockRemoved(self, zone, icmp):
        log.debug1("zone.IcmpBlockRemoved('%s', '%s')" % (zone, icmp))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # ICMP BLOCK INVERSION

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='s')
    @dbus_handle_exceptions
    def addIcmpBlockInversion(self, zone, sender=None):
        # adds icmpBlockInversion if not added already
        zone = dbus_to_python(zone, str)
        log.debug1("zone.addIcmpBlockInversion('%s')" % (zone))
        self.accessCheck(sender)
        _zone = self.fw.zone.add_icmp_block_inversion(zone, sender)
        
        self.IcmpBlockInversionAdded(_zone)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='s')
    @dbus_handle_exceptions
    def removeIcmpBlockInversion(self, zone, sender=None):
        # removes icmpBlockInversion
        zone = dbus_to_python(zone, str)
        log.debug1("zone.removeIcmpBlockInversion('%s')" % (zone))
        self.accessCheck(sender)
        _zone = self.fw.zone.remove_icmp_block_inversion(zone)

        self.IcmpBlockInversionRemoved(_zone)
        return _zone

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='s',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryIcmpBlockInversion(self, zone, sender=None): # pylint: disable=W0613
        # returns true if a icmpBlockInversion is added
        zone = dbus_to_python(zone, str)
        log.debug1("zone.queryIcmpBlockInversion('%s')" % (zone))
        return self.fw.zone.query_icmp_block_inversion(zone)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='s')
    @dbus_handle_exceptions
    def IcmpBlockInversionAdded(self, zone):
        log.debug1("zone.IcmpBlockInversionAdded('%s')" % (zone))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='s')
    @dbus_handle_exceptions
    def IcmpBlockInversionRemoved(self, zone):
        log.debug1("zone.IcmpBlockInversionRemoved('%s')" % (zone))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # DIRECT INTERFACE
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # DIRECT CHAIN

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='sss',
                         out_signature='')
    @dbus_handle_exceptions
    def addChain(self, ipv, table, chain, sender=None):
        # inserts direct chain
        ipv = dbus_to_python(ipv, str)
        table = dbus_to_python(table, str)
        chain = dbus_to_python(chain, str)
        log.debug1("direct.addChain('%s', '%s', '%s')" % (ipv, table, chain))
        self.accessCheck(sender)
        self.fw.direct.add_chain(ipv, table, chain)
        self.ChainAdded(ipv, table, chain)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='sss',
                         out_signature='')
    @dbus_handle_exceptions
    def removeChain(self, ipv, table, chain, sender=None):
        # removes direct chain
        ipv = dbus_to_python(ipv, str)
        table = dbus_to_python(table, str)
        chain = dbus_to_python(chain, str)
        log.debug1("direct.removeChain('%s', '%s', '%s')" % (ipv, table, chain))
        self.accessCheck(sender)
        self.fw.direct.remove_chain(ipv, table, chain)
        self.ChainRemoved(ipv, table, chain)
    
    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='sss',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryChain(self, ipv, table, chain, sender=None): # pylint: disable=W0613
        # returns true if a chain is enabled
        ipv = dbus_to_python(ipv, str)
        table = dbus_to_python(table, str)
        chain = dbus_to_python(chain, str)
        log.debug1("direct.queryChain('%s', '%s', '%s')" % (ipv, table, chain))
        return self.fw.direct.query_chain(ipv, table, chain)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='ss',
                         out_signature='as')
    @dbus_handle_exceptions
    def getChains(self, ipv, table, sender=None): # pylint: disable=W0613
        # returns list of added chains
        ipv = dbus_to_python(ipv, str)
        table = dbus_to_python(table, str)
        log.debug1("direct.getChains('%s', '%s')" % (ipv, table))
        return self.fw.direct.get_chains(ipv, table)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='',
                         out_signature='a(sss)')
    @dbus_handle_exceptions
    def getAllChains(self, sender=None): # pylint: disable=W0613
        # returns list of added chains
        log.debug1("direct.getAllChains()")
        return self.fw.direct.get_all_chains()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_DIRECT, signature='sss')
    @dbus_handle_exceptions
    def ChainAdded(self, ipv, table, chain):
        log.debug1("direct.ChainAdded('%s', '%s', '%s')" % (ipv, table, chain))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_DIRECT, signature='sss')
    @dbus_handle_exceptions
    def ChainRemoved(self, ipv, table, chain):
        log.debug1("direct.ChainRemoved('%s', '%s', '%s')" % (ipv, table,
                                                              chain))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # DIRECT RULE

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT,
                         in_signature='sssias', out_signature='')
    @dbus_handle_exceptions
    def addRule(self, ipv, table, chain, priority, args, sender=None): # pylint: disable=R0913
        # inserts direct rule
        ipv = dbus_to_python(ipv, str)
        table = dbus_to_python(table, str)
        chain = dbus_to_python(chain, str)
        priority = dbus_to_python(priority, int)
        args = tuple( dbus_to_python(i, str) for i in args )
        log.debug1("direct.addRule('%s', '%s', '%s', %d, '%s')" % \
                       (ipv, table, chain, priority, "','".join(args)))
        self.accessCheck(sender)
        self.fw.direct.add_rule(ipv, table, chain, priority, args)
        self.RuleAdded(ipv, table, chain, priority, args)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT,
                         in_signature='sssias', out_signature='')
    @dbus_handle_exceptions
    def removeRule(self, ipv, table, chain, priority, args, sender=None): # pylint: disable=R0913
        # removes direct rule
        ipv = dbus_to_python(ipv, str)
        table = dbus_to_python(table, str)
        chain = dbus_to_python(chain, str)
        priority = dbus_to_python(priority, int)
        args = tuple( dbus_to_python(i, str) for i in args )
        log.debug1("direct.removeRule('%s', '%s', '%s', %d, '%s')" % \
                       (ipv, table, chain, priority, "','".join(args)))
        self.accessCheck(sender)
        self.fw.direct.remove_rule(ipv, table, chain, priority, args)
        self.RuleRemoved(ipv, table, chain, priority, args)
    
    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='sss',
                         out_signature='')
    @dbus_handle_exceptions
    def removeRules(self, ipv, table, chain, sender=None):
        # removes direct rule
        ipv = dbus_to_python(ipv, str)
        table = dbus_to_python(table, str)
        chain = dbus_to_python(chain, str)
        log.debug1("direct.removeRules('%s', '%s', '%s')" % (ipv, table, chain))
        self.accessCheck(sender)
        for (priority, args) in self.fw.direct.get_rules(ipv, table, chain):
            self.fw.direct.remove_rule(ipv, table, chain, priority, args)
            self.RuleRemoved(ipv, table, chain, priority, args)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT,
                         in_signature='sssias', out_signature='b')
    @dbus_handle_exceptions
    def queryRule(self, ipv, table, chain, priority, args, sender=None): # pylint: disable=W0613, R0913
        # returns true if a rule is enabled
        ipv = dbus_to_python(ipv, str)
        table = dbus_to_python(table, str)
        chain = dbus_to_python(chain, str)
        priority = dbus_to_python(priority, int)
        args = tuple( dbus_to_python(i, str) for i in args )
        log.debug1("direct.queryRule('%s', '%s', '%s', %d, '%s')" % \
                       (ipv, table, chain, priority, "','".join(args)))
        return self.fw.direct.query_rule(ipv, table, chain, priority, args)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='sss',
                         out_signature='a(ias)')
    @dbus_handle_exceptions
    def getRules(self, ipv, table, chain, sender=None): # pylint: disable=W0613
        # returns list of added rules
        ipv = dbus_to_python(ipv, str)
        table = dbus_to_python(table, str)
        chain = dbus_to_python(chain, str)
        log.debug1("direct.getRules('%s', '%s', '%s')" % (ipv, table, chain))
        return self.fw.direct.get_rules(ipv, table, chain)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='',
                         out_signature='a(sssias)')
    @dbus_handle_exceptions
    def getAllRules(self, sender=None): # pylint: disable=W0613
        # returns list of added rules
        log.debug1("direct.getAllRules()")
        return self.fw.direct.get_all_rules()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_DIRECT, signature='sssias')
    @dbus_handle_exceptions
    def RuleAdded(self, ipv, table, chain, priority, args): # pylint: disable=R0913
        log.debug1("direct.RuleAdded('%s', '%s', '%s', %d, '%s')" % \
                       (ipv, table, chain, priority, "','".join(args)))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_DIRECT, signature='sssias')
    @dbus_handle_exceptions
    def RuleRemoved(self, ipv, table, chain, priority, args): # pylint: disable=R0913
        log.debug1("direct.RuleRemoved('%s', '%s', '%s', %d, '%s')" % \
                       (ipv, table, chain, priority, "','".join(args)))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # DIRECT PASSTHROUGH (untracked)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='sas',
                         out_signature='s')
    @dbus_handle_exceptions
    def passthrough(self, ipv, args, sender=None):
        # inserts direct rule
        ipv = dbus_to_python(ipv, str)
        args = tuple( dbus_to_python(i, str) for i in args )
        log.debug1("direct.passthrough('%s', '%s')" % (ipv, "','".join(args)))
        self.accessCheck(sender)
        try:
            return self.fw.direct.passthrough(ipv, args)
        except FirewallError as error:
            if ipv in ["ipv4", "ipv6"]:
                query_args = set(["-C", "--check",
                                  "-L", "--list"])
            else:
                query_args = set(["-L", "--list"])
            msg = str(error)
            if error.code == errors.COMMAND_FAILED:
                if len(set(args) & query_args) <= 0:
                    log.warning(msg)
                raise FirewallDBusException(msg)
            raise

    # DIRECT PASSTHROUGH (tracked)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='sas',
                         out_signature='')
    @dbus_handle_exceptions
    def addPassthrough(self, ipv, args, sender=None):
        # inserts direct passthrough
        ipv = dbus_to_python(ipv)
        args = tuple( dbus_to_python(i) for i in args )
        log.debug1("direct.addPassthrough('%s', '%s')" % \
                   (ipv, "','".join(args)))
        self.accessCheck(sender)
        self.fw.direct.add_passthrough(ipv, args)
        self.PassthroughAdded(ipv, args)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='sas',
                         out_signature='')
    @dbus_handle_exceptions
    def removePassthrough(self, ipv, args, sender=None):
        # removes direct passthrough
        ipv = dbus_to_python(ipv)
        args = tuple( dbus_to_python(i) for i in args )
        log.debug1("direct.removePassthrough('%s', '%s')" % \
                       (ipv, "','".join(args)))
        self.accessCheck(sender)
        self.fw.direct.remove_passthrough(ipv, args)
        self.PassthroughRemoved(ipv, args)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='sas',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryPassthrough(self, ipv, args, sender=None): # pylint: disable=W0613
        # returns true if a passthrough is enabled
        ipv = dbus_to_python(ipv)
        args = tuple( dbus_to_python(i) for i in args )
        log.debug1("direct.queryPassthrough('%s', '%s')" % \
                       (ipv, "','".join(args)))
        return self.fw.direct.query_passthrough(ipv, args)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='',
                         out_signature='a(sas)')
    @dbus_handle_exceptions
    def getAllPassthroughs(self, sender=None): # pylint: disable=W0613
        # returns list of all added passthroughs
        log.debug1("direct.getAllPassthroughs()")
        return self.fw.direct.get_all_passthroughs()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='',
                         out_signature='')
    @dbus_handle_exceptions
    def removeAllPassthroughs(self, sender=None): # pylint: disable=W0613
        # remove all passhroughs
        log.debug1("direct.removeAllPassthroughs()")
        # remove in reverse order to avoid removing non-empty chains
        for passthrough in reversed(self.getAllPassthroughs()):
            self.removePassthrough(*passthrough)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_DIRECT_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_DIRECT, in_signature='s',
                         out_signature='aas')
    @dbus_handle_exceptions
    def getPassthroughs(self, ipv, sender=None): # pylint: disable=W0613
        # returns list of all added passthroughs with ipv
        ipv = dbus_to_python(ipv)
        log.debug1("direct.getPassthroughs('%s')", ipv)
        return self.fw.direct.get_passthroughs(ipv)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_DIRECT, signature='sas')
    @dbus_handle_exceptions
    def PassthroughAdded(self, ipv, args):
        log.debug1("direct.PassthroughAdded('%s', '%s')" % \
                       (ipv, "','".join(args)))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_DIRECT, signature='sas')
    @dbus_handle_exceptions
    def PassthroughRemoved(self, ipv, args):
        log.debug1("direct.PassthroughRemoved('%s', '%s')" % \
                       (ipv, "','".join(args)))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_ALL)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='',
                         out_signature='')
    @dbus_handle_exceptions
    def authorizeAll(self, sender=None): # pylint: disable=W0613
        """ PK_ACTION_ALL implies all other actions, i.e. once a subject is
            authorized for PK_ACTION_ALL it's also authorized for any other action.
            Use-case is GUI (RHBZ#994729).
        """
        pass

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # IPSETS
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_IPSET, in_signature='s',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryIPSet(self, ipset, sender=None): # pylint: disable=W0613
        # returns true if a set with the name exists
        ipset = dbus_to_python(ipset)
        log.debug1("ipset.queryIPSet('%s')" % (ipset))
        return self.fw.ipset.query_ipset(ipset)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_IPSET, in_signature='',
                         out_signature='as')
    @dbus_handle_exceptions
    def getIPSets(self, sender=None): # pylint: disable=W0613
        # returns list of added sets
        log.debug1("ipsets.getIPSets()")
        return self.fw.ipset.get_ipsets()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_IPSET, in_signature='s',
                         out_signature=IPSet.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def getIPSetSettings(self, ipset, sender=None): # pylint: disable=W0613
        # returns ipset settings for ipset
        ipset = dbus_to_python(ipset, str)
        log.debug1("getIPSetSettings(%s)", ipset)
        return self.fw.ipset.get_ipset(ipset).export_config()

    # set entries # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_IPSET, in_signature='ss',
                         out_signature='')
    @dbus_handle_exceptions
    def addEntry(self, ipset, entry, sender=None):
        # adds ipset entry
        ipset = dbus_to_python(ipset)
        entry = dbus_to_python(entry)
        log.debug1("ipset.addEntry('%s', '%s')" % (ipset, entry))
        self.accessCheck(sender)
        self.fw.ipset.add_entry(ipset, entry)
        self.EntryAdded(ipset, entry)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_IPSET, in_signature='ss',
                         out_signature='')
    @dbus_handle_exceptions
    def removeEntry(self, ipset, entry, sender=None):
        # removes ipset entry
        ipset = dbus_to_python(ipset)
        entry = dbus_to_python(entry)
        log.debug1("ipset.removeEntry('%s', '%s')" % (ipset, entry))
        self.accessCheck(sender)
        self.fw.ipset.remove_entry(ipset, entry)
        self.EntryRemoved(ipset, entry)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_IPSET, in_signature='ss',
                         out_signature='b')
    @dbus_handle_exceptions
    def queryEntry(self, ipset, entry, sender=None): # pylint: disable=W0613
        # returns true if the entry exists in the ipset
        ipset = dbus_to_python(ipset)
        entry = dbus_to_python(entry)
        log.debug1("ipset.queryEntry('%s', '%s')" % (ipset, entry))
        return self.fw.ipset.query_entry(ipset, entry)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_IPSET, in_signature='s',
                         out_signature='as')
    @dbus_handle_exceptions
    def getEntries(self, ipset, sender=None): # pylint: disable=W0613
        # returns list of added entries for the ipset
        ipset = dbus_to_python(ipset)
        log.debug1("ipset.getEntries('%s')" % ipset)
        return self.fw.ipset.get_entries(ipset)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(config.dbus.DBUS_INTERFACE_IPSET, in_signature='sas')
    @dbus_handle_exceptions
    def setEntries(self, ipset, entries, sender=None): # pylint: disable=W0613
        # returns list of added entries for the ipset
        ipset = dbus_to_python(ipset)
        entries = dbus_to_python(entries, list)
        log.debug1("ipset.setEntries('%s', '[%s]')", ipset, ",".join(entries))
        old_entries = self.fw.ipset.get_entries(ipset)
        self.fw.ipset.set_entries(ipset, entries)
        old_entries_set = set(old_entries)
        entries_set = set(entries)
        for entry in entries_set - old_entries_set:
            self.EntryAdded(ipset, entry)
        for entry in old_entries_set - entries_set:
            self.EntryRemoved(ipset, entry)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_IPSET, signature='ss')
    @dbus_handle_exceptions
    def EntryAdded(self, ipset, entry):
        ipset = dbus_to_python(ipset)
        entry = dbus_to_python(entry)
        log.debug1("ipset.EntryAdded('%s', '%s')" % (ipset, entry))

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_IPSET, signature='ss')
    @dbus_handle_exceptions
    def EntryRemoved(self, ipset, entry):
        ipset = dbus_to_python(ipset)
        entry = dbus_to_python(entry)
        log.debug1("ipset.EntryRemoved('%s', '%s')" % (ipset, entry))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # HELPERS
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='',
                         out_signature='as')
    @dbus_handle_exceptions
    def getHelpers(self, sender=None): # pylint: disable=W0613
        # returns list of added sets
        log.debug1("helpers.getHelpers()")
        return self.fw.helper.get_helpers()

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO)
    @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='s',
                         out_signature=Helper.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def getHelperSettings(self, helper, sender=None): # pylint: disable=W0613
        # returns helper settings for helper
        helper = dbus_to_python(helper, str)
        log.debug1("getHelperSettings(%s)", helper)
        return self.fw.helper.get_helper(helper).export_config()

server/config_policy.py000064400000020455150351351710011257 0ustar00# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: GPL-2.0-or-later

# force use of pygobject3 in python-slip
from gi.repository import GObject
import sys
sys.modules['gobject'] = GObject

import dbus
import dbus.service
import slip.dbus
import slip.dbus.service

from firewall import config
from firewall.dbus_utils import dbus_to_python, \
    dbus_introspection_prepare_properties, \
    dbus_introspection_add_properties
from firewall.core.logger import log
from firewall.server.decorators import handle_exceptions, \
    dbus_handle_exceptions, dbus_service_method

class FirewallDConfigPolicy(slip.dbus.service.Object):
    persistent = True
    default_polkit_auth_required = config.dbus.PK_ACTION_CONFIG

    @handle_exceptions
    def __init__(self, parent, conf, policy, item_id, *args, **kwargs):
        super(FirewallDConfigPolicy, self).__init__(*args, **kwargs)
        self.parent = parent
        self.config = conf
        self.obj = policy
        self.item_id = item_id
        self.busname = args[0]
        self.path = args[1]
        self._log_prefix = "config.policy.%d" % self.item_id
        dbus_introspection_prepare_properties(
            self, config.dbus.DBUS_INTERFACE_CONFIG_POLICY)

    @dbus_handle_exceptions
    def __del__(self):
        pass

    @dbus_handle_exceptions
    def unregister(self):
        self.remove_from_connection()

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # P R O P E R T I E S

    @dbus_handle_exceptions
    def _get_property(self, property_name):
        if property_name == "name":
            return dbus.String(self.obj.name)
        elif property_name == "filename":
            return dbus.String(self.obj.filename)
        elif property_name == "path":
            return dbus.String(self.obj.path)
        elif property_name == "default":
            return dbus.Boolean(self.obj.default)
        elif property_name == "builtin":
            return dbus.Boolean(self.obj.builtin)
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ss',
                         out_signature='v')
    @dbus_handle_exceptions
    def Get(self, interface_name, property_name, sender=None):
        # get a property
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        log.debug1("%s.Get('%s', '%s')", self._log_prefix,
                   interface_name, property_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_POLICY:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        return self._get_property(property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='s',
                         out_signature='a{sv}')
    @dbus_handle_exceptions
    def GetAll(self, interface_name, sender=None):
        interface_name = dbus_to_python(interface_name, str)
        log.debug1("%s.GetAll('%s')", self._log_prefix, interface_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_POLICY:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        ret = { }
        for x in [ "name", "filename", "path", "default", "builtin" ]:
            ret[x] = self._get_property(x)
        return dbus.Dictionary(ret, signature="sv")

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ssv')
    @dbus_handle_exceptions
    def Set(self, interface_name, property_name, new_value, sender=None):
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        new_value = dbus_to_python(new_value)
        log.debug1("%s.Set('%s', '%s', '%s')", self._log_prefix,
                   interface_name, property_name, new_value)
        self.parent.accessCheck(sender)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_POLICY:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        raise dbus.exceptions.DBusException(
            "org.freedesktop.DBus.Error.PropertyReadOnly: "
            "Property '%s' is read-only" % property_name)

    @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as')
    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)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(dbus.INTROSPECTABLE_IFACE, out_signature='s')
    @dbus_handle_exceptions
    def Introspect(self, sender=None):
        log.debug2("%s.Introspect()", self._log_prefix)

        data = super(FirewallDConfigPolicy, self).Introspect(
            self.path, self.busname.get_bus())

        return dbus_introspection_add_properties(
            self, data, config.dbus.DBUS_INTERFACE_CONFIG_POLICY)

    # S E T T I N G S

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICY,
                         out_signature="a{sv}")
    @dbus_handle_exceptions
    def getSettings(self, sender=None):
        """get settings for policy
        """
        log.debug1("%s.getSettings()", self._log_prefix)
        settings = self.config.get_policy_object_config_dict(self.obj)
        return settings

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICY,
                         in_signature="a{sv}")
    @dbus_handle_exceptions
    def update(self, settings, sender=None):
        """update settings for policy
        """
        settings = dbus_to_python(settings)
        log.debug1("%s.update('...')", self._log_prefix)
        self.parent.accessCheck(sender)
        self.obj = self.config.set_policy_object_config_dict(self.obj, settings)
        self.Updated(self.obj.name)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICY)
    @dbus_handle_exceptions
    def loadDefaults(self, sender=None):
        """load default settings for builtin policy
        """
        log.debug1("%s.loadDefaults()", self._log_prefix)
        self.parent.accessCheck(sender)
        self.obj = self.config.load_policy_object_defaults(self.obj)
        self.Updated(self.obj.name)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_POLICY, signature='s')
    @dbus_handle_exceptions
    def Updated(self, name):
        log.debug1("%s.Updated('%s')" % (self._log_prefix, name))

    # R E M O V E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICY)
    @dbus_handle_exceptions
    def remove(self, sender=None):
        """remove policy
        """
        log.debug1("%s.removePolicy()", self._log_prefix)
        self.parent.accessCheck(sender)
        self.config.remove_policy_object(self.obj)
        self.parent.removePolicy(self.obj)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_POLICY, signature='s')
    @dbus_handle_exceptions
    def Removed(self, name):
        log.debug1("%s.Removed('%s')" % (self._log_prefix, name))

    # R E N A M E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICY,
                         in_signature='s')
    @dbus_handle_exceptions
    def rename(self, name, sender=None):
        """rename policy
        """
        name = dbus_to_python(name, str)
        log.debug1("%s.rename('%s')", self._log_prefix, name)
        self.parent.accessCheck(sender)
        self.obj = self.config.rename_policy_object(self.obj, name)
        self.Renamed(name)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_POLICY, signature='s')
    @dbus_handle_exceptions
    def Renamed(self, name):
        log.debug1("%s.Renamed('%s')" % (self._log_prefix, name))
server/config_helper.py000064400000042212150351351710011232 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.

# force use of pygobject3 in python-slip
from gi.repository import GObject
import sys
sys.modules['gobject'] = GObject

import dbus
import dbus.service
import slip.dbus
import slip.dbus.service

from firewall import config
from firewall.dbus_utils import dbus_to_python, \
    dbus_introspection_prepare_properties, \
    dbus_introspection_add_properties
from firewall.core.io.helper import Helper
from firewall.core.logger import log
from firewall.server.decorators import handle_exceptions, \
    dbus_handle_exceptions, dbus_service_method
from firewall import errors
from firewall.errors import FirewallError

############################################################################
#
# class FirewallDConfig
#
############################################################################

class FirewallDConfigHelper(slip.dbus.service.Object):
    """FirewallD main class"""

    persistent = True
    """ Make FirewallD persistent. """
    default_polkit_auth_required = config.dbus.PK_ACTION_CONFIG
    """ Use PK_ACTION_INFO as a default """

    @handle_exceptions
    def __init__(self, parent, conf, helper, item_id, *args, **kwargs):
        super(FirewallDConfigHelper, self).__init__(*args, **kwargs)
        self.parent = parent
        self.config = conf
        self.obj = helper
        self.item_id = item_id
        self.busname = args[0]
        self.path = args[1]
        self._log_prefix = "config.helper.%d" % self.item_id
        dbus_introspection_prepare_properties(
            self, config.dbus.DBUS_INTERFACE_CONFIG_HELPER)

    @dbus_handle_exceptions
    def __del__(self):
        pass

    @dbus_handle_exceptions
    def unregister(self):
        self.remove_from_connection()

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # P R O P E R T I E S

    @dbus_handle_exceptions
    def _get_property(self, property_name):
        if property_name == "name":
            return dbus.String(self.obj.name)
        elif property_name == "filename":
            return dbus.String(self.obj.filename)
        elif property_name == "path":
            return dbus.String(self.obj.path)
        elif property_name == "default":
            return dbus.Boolean(self.obj.default)
        elif property_name == "builtin":
            return dbus.Boolean(self.obj.builtin)
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ss',
                         out_signature='v')
    @dbus_handle_exceptions
    def Get(self, interface_name, property_name, sender=None): # pylint: disable=W0613
        # get a property
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        log.debug1("%s.Get('%s', '%s')", self._log_prefix,
                   interface_name, property_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_HELPER:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        return self._get_property(property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='s',
                         out_signature='a{sv}')
    @dbus_handle_exceptions
    def GetAll(self, interface_name, sender=None): # pylint: disable=W0613
        interface_name = dbus_to_python(interface_name, str)
        log.debug1("%s.GetAll('%s')", self._log_prefix, interface_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_HELPER:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        ret = { }
        for x in [ "name", "filename", "path", "default", "builtin" ]:
            ret[x] = self._get_property(x)
        return dbus.Dictionary(ret, signature="sv")

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ssv')
    @dbus_handle_exceptions
    def Set(self, interface_name, property_name, new_value, sender=None):
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        new_value = dbus_to_python(new_value)
        log.debug1("%s.Set('%s', '%s', '%s')", self._log_prefix,
                   interface_name, property_name, new_value)
        self.parent.accessCheck(sender)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_HELPER:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        raise dbus.exceptions.DBusException(
            "org.freedesktop.DBus.Error.PropertyReadOnly: "
            "Property '%s' is read-only" % property_name)

    @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as')
    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)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(dbus.INTROSPECTABLE_IFACE, out_signature='s')
    @dbus_handle_exceptions
    def Introspect(self, sender=None): # pylint: disable=W0613
        log.debug2("%s.Introspect()", self._log_prefix)

        data = super(FirewallDConfigHelper, self).Introspect(
            self.path, self.busname.get_bus())

        return dbus_introspection_add_properties(
            self, data, config.dbus.DBUS_INTERFACE_CONFIG_HELPER)

    # S E T T I N G S

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         out_signature=Helper.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def getSettings(self, sender=None): # pylint: disable=W0613
        """get settings for helper
        """
        log.debug1("%s.getSettings()", self._log_prefix)
        return self.config.get_helper_config(self.obj)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature=Helper.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def update(self, settings, sender=None):
        """update settings for helper
        """
        settings = dbus_to_python(settings)
        log.debug1("%s.update('...')", self._log_prefix)
        self.parent.accessCheck(sender)
        self.obj = self.config.set_helper_config(self.obj, settings)
        self.Updated(self.obj.name)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER)
    @dbus_handle_exceptions
    def loadDefaults(self, sender=None):
        """load default settings for builtin helper
        """
        log.debug1("%s.loadDefaults()", self._log_prefix)
        self.parent.accessCheck(sender)
        self.obj = self.config.load_helper_defaults(self.obj)
        self.Updated(self.obj.name)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         signature='s')
    @dbus_handle_exceptions
    def Updated(self, name):
        log.debug1("%s.Updated('%s')" % (self._log_prefix, name))

    # R E M O V E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER)
    @dbus_handle_exceptions
    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)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         signature='s')
    @dbus_handle_exceptions
    def Removed(self, name):
        log.debug1("%s.Removed('%s')" % (self._log_prefix, name))

    # R E N A M E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='s')
    @dbus_handle_exceptions
    def rename(self, name, sender=None):
        """rename helper
        """
        name = dbus_to_python(name, str)
        log.debug1("%s.rename('%s')", self._log_prefix, name)
        self.parent.accessCheck(sender)
        self.obj = self.config.rename_helper(self.obj, name)
        self.Renamed(name)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         signature='s')
    @dbus_handle_exceptions
    def Renamed(self, name):
        log.debug1("%s.Renamed('%s')" % (self._log_prefix, name))

    # version

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         out_signature='s')
    @dbus_handle_exceptions
    def getVersion(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getVersion()", self._log_prefix)
        return self.getSettings()[0]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # short

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         out_signature='s')
    @dbus_handle_exceptions
    def getShort(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getShort()", self._log_prefix)
        return self.getSettings()[1]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # description

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         out_signature='s')
    @dbus_handle_exceptions
    def getDescription(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getDescription()", self._log_prefix)
        return self.getSettings()[2]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # family

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         out_signature='s')
    @dbus_handle_exceptions
    def getFamily(self, sender=None):
        log.debug1("%s.getFamily()", self._log_prefix)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        return settings[3]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='s')
    @dbus_handle_exceptions
    def setFamily(self, ipv, sender=None):
        ipv = dbus_to_python(ipv, str)
        log.debug1("%s.setFamily('%s')", self._log_prefix, ipv)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if settings[3] == ipv:
            raise FirewallError(errors.ALREADY_ENABLED, "'%s'" % ipv)
        settings[3] = ipv
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    def queryFamily(self, ipv, sender=None): # pylint: disable=W0613
        ipv = dbus_to_python(ipv, str)
        log.debug1("%s.queryFamily('%s')", self._log_prefix, ipv)
        settings = self.getSettings()
        return (settings[3] == ipv)

    # module

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         out_signature='s')
    @dbus_handle_exceptions
    def getModule(self, sender=None):
        log.debug1("%s.getModule()", self._log_prefix)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        return settings[4]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='s')
    @dbus_handle_exceptions
    def setModule(self, module, sender=None):
        module = dbus_to_python(module, str)
        log.debug1("%s.setModule('%s')", self._log_prefix, module)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if settings[4] == module:
            raise FirewallError(errors.ALREADY_ENABLED, "'%s'" % module)
        settings[4] = module
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    def queryModule(self, module, sender=None): # pylint: disable=W0613
        module = dbus_to_python(module, str)
        log.debug1("%s.queryModule('%s')", self._log_prefix, module)
        settings = self.getSettings()
        return (settings[4] == module)

    # port

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         out_signature='a(ss)')
    @dbus_handle_exceptions
    def getPorts(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getPorts()", self._log_prefix)
        return self.getSettings()[5]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='a(ss)')
    @dbus_handle_exceptions
    def setPorts(self, ports, sender=None):
        _ports = [ ]
        # convert embedded lists to tuples
        for port in dbus_to_python(ports, list):
            if isinstance(port, list):
                _ports.append(tuple(port))
            else:
                _ports.append(port)
        ports = _ports
        log.debug1("%s.setPorts('[%s]')", self._log_prefix,
                   ",".join("('%s, '%s')" % (port[0], port[1]) for port in ports))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[5] = ports
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='ss')
    @dbus_handle_exceptions
    def addPort(self, port, protocol, sender=None):
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.addPort('%s', '%s')", self._log_prefix, port,
                   protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if (port,protocol) in settings[5]:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "%s:%s" % (port, protocol))
        settings[5].append((port,protocol))
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='ss')
    @dbus_handle_exceptions
    def removePort(self, port, protocol, sender=None):
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.removePort('%s', '%s')", self._log_prefix, port,
                   protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if (port,protocol) not in settings[5]:
            raise FirewallError(errors.NOT_ENABLED, "%s:%s" % (port, protocol))
        settings[5].remove((port,protocol))
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_HELPER,
                         in_signature='ss', out_signature='b')
    @dbus_handle_exceptions
    def queryPort(self, port, protocol, sender=None): # pylint: disable=W0613
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.queryPort('%s', '%s')", self._log_prefix, port,
                   protocol)
        return (port,protocol) in self.getSettings()[5]
server/__pycache__/config_ipset.cpython-36.pyc000064400000031650150351351720015370 0ustar003

��gzI�@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZmZmZmZddlmZdd	lmZmZmZdd
l	mZddlmZGdd
�d
ejjj �Z!dS)�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�IPSet)�IPSET_TYPES�normalize_ipset_entry�check_entry_overlaps_existing�check_for_overlapping_entries)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�errors)�
FirewallErrorcseZdZdZdZejjZe	�fdd��Z
edd��Zedd��Z
ed	d
��Zeejddd
�edWdd���Zeejddd
�edXdd���Zejjjejj�eejdd�edYdd����Zejjejdd�dd��Zejjjejj�eejdd�edZ�fdd�	���Zeejjejd�ed[d d!���Z eejjejd�ed\d"d#���Z!eejj�ed]d$d%���Z"ejjejjdd�ed&d'���Z#eejj�ed^d(d)���Z$ejjejjdd�ed*d+���Z%eejjdd�ed_d,d-���Z&ejjejjdd�ed.d/���Z'eejjdd�ed`d0d1���Z(eejjdd�edad2d3���Z)eejjdd�edbd4d5���Z*eejjdd�edcd6d7���Z+eejjdd�eddd8d9���Z,eejjdd�eded:d;���Z-eejjdd�edfd<d=���Z.eejjdd�edgd>d?���Z/eejjd@d�edhdAdB���Z0eejjd@d�edidCdD���Z1eejjdd�edjdEdF���Z2eejjdd�edkdGdH���Z3eejjddId
�edldJdK���Z4eejjdLd�edmdMdN���Z5eejjdLd�edndOdP���Z6eejjdd�edodQdR���Z7eejjdd�edpdSdT���Z8eejjddId
�edqdUdV���Z9�Z:S)r�FirewallDConfigIPSetzFirewallD main classTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.ipset.%d)
�superr�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_IPSET)�selfrZconfZipsetr�args�kwargs)�	__class__��"/usr/lib/python3.6/config_ipset.pyr;s

zFirewallDConfigIPSet.__init__cCsdS)Nr")rr"r"r#�__del__HszFirewallDConfigIPSet.__del__cCs|j�dS)N)Zremove_from_connection)rr"r"r#�
unregisterLszFirewallDConfigIPSet.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrr&r'rZBooleanr(r)�
exceptions�
DBusException)r�
property_namer"r"r#�
_get_propertyTsz"FirewallDConfigIPSet._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrrr+r,r.)r�interface_namer-�senderr"r"r#�Getes


zFirewallDConfigIPSet.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existr&r'rr(r)Zsv)�	signature)r&r'rr(r))rr2rr3rrrrr+r,r.Z
Dictionary)rr4r5�ret�xr"r"r#�GetAllvs

zFirewallDConfigIPSet.GetAllZssv)r0cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr2rr3rr�accessCheckrrrr+r,)rr4r-Z	new_valuer5r"r"r#�Set�s



zFirewallDConfigIPSet.Setzsa{sv}as)r8cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr2rr3r)rr4Zchanged_propertiesZinvalidated_propertiesr"r"r#�PropertiesChanged�s


z&FirewallDConfigIPSet.PropertiesChanged)r1cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rrr�
IntrospectrrZget_busrrrr)rr5�data)r!r"r#r?�s

zFirewallDConfigIPSet.IntrospectcCstjd|j�|jj|j�S)zget settings for ipset
        z%s.getSettings())rr3rrZget_ipset_configr)rr5r"r"r#�getSettings�sz FirewallDConfigIPSet.getSettingscCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)z"update settings for ipset
        z%s.update('...')N)rrr3rrr<rZset_ipset_configr�Updatedr&)r�settingsr5r"r"r#�update�s
zFirewallDConfigIPSet.updatecCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z0load default settings for builtin ipset
        z%s.loadDefaults()N)
rr3rrr<rZload_ipset_defaultsrrBr&)rr5r"r"r#�loadDefaults�sz!FirewallDConfigIPSet.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr3r)rr&r"r"r#rB�szFirewallDConfigIPSet.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove ipset
        z%s.remove()N)	rr3rrr<rZremove_ipsetrZremoveIPSet)rr5r"r"r#�remove�szFirewallDConfigIPSet.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr3r)rr&r"r"r#�Removed�szFirewallDConfigIPSet.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename ipset
        z%s.rename('%s')N)rr2rr3rrr<rZrename_ipsetr�Renamed)rr&r5r"r"r#�rename�s

zFirewallDConfigIPSet.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr3r)rr&r"r"r#rH�szFirewallDConfigIPSet.RenamedcCstjd|j�|j�dS)Nz%s.getVersion()r)rr3rrA)rr5r"r"r#�
getVersionszFirewallDConfigIPSet.getVersioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setVersion('%s')r)
rr2rr3rrr<�listrArD)r�versionr5rCr"r"r#�
setVersions
zFirewallDConfigIPSet.setVersioncCstjd|j�|j�dS)Nz
%s.getShort()r)rr3rrA)rr5r"r"r#�getShortszFirewallDConfigIPSet.getShortcCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setShort('%s')r)
rr2rr3rrr<rKrArD)rZshortr5rCr"r"r#�setShorts
zFirewallDConfigIPSet.setShortcCstjd|j�|j�dS)Nz%s.getDescription()�)rr3rrA)rr5r"r"r#�getDescription(sz#FirewallDConfigIPSet.getDescriptioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setDescription('%s')rP)
rr2rr3rrr<rKrArD)r�descriptionr5rCr"r"r#�setDescription/s

z#FirewallDConfigIPSet.setDescriptioncCstjd|j�|j�dS)Nz%s.getType()�)rr3rrA)rr5r"r"r#�getType=szFirewallDConfigIPSet.getTypecCs\t|t�}tjd|j|�|jj|�|tkr:tt	j
|��t|j��}||d<|j
|�dS)Nz%s.setType('%s')rT)rr2rr3rrr<rrrZINVALID_TYPErKrArD)rZ
ipset_typer5rCr"r"r#�setTypeDs
zFirewallDConfigIPSet.setTypeza{ss}cCstjd|j�|j�dS)Nz%s.getOptions()�)rr3rrA)rr5r"r"r#�
getOptionsSszFirewallDConfigIPSet.getOptionscCsLt|t�}tjd|jt|��|jj|�t|j	��}||d<|j
|�dS)Nz%s.setOptions('[%s]')rW)r�dictrr3r�reprrr<rKrArD)rZoptionsr5rCr"r"r#�
setOptionsZs


zFirewallDConfigIPSet.setOptionscCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||dkrn|d||krnt	t
jd||f��||d|<|j|�dS)Nz%s.addOption('%s', '%s')rWz
'%s': '%s')
rr2rr3rrr<rKrArr�ALREADY_ENABLEDrD)r�key�valuer5rCr"r"r#�	addOptionfs

zFirewallDConfigIPSet.addOptioncCsbt|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|d|=|j|�dS)Nz%s.removeOption('%s')rW)
rr2rr3rrr<rKrArr�NOT_ENABLEDrD)rr]r5rCr"r"r#�removeOptionus

z!FirewallDConfigIPSet.removeOption�bcCsNt|t�}t|t�}tjd|j||�t|j��}||dkoL|d||kS)Nz%s.queryOption('%s', '%s')rW)rr2rr3rrKrA)rr]r^r5rCr"r"r#�queryOption�s

z FirewallDConfigIPSet.queryOption�ascCstjd|j�|j�dS)Nz%s.getEntries()�)rr3rrA)rr5r"r"r#�
getEntries�szFirewallDConfigIPSet.getEntriescCs|t|t�}t|�tjd|jdj|��|jj|�t|j	��}d|dkrf|dddkrft
tj��||d<|j
|�dS)Nz%s.setEntries('[%s]')�,�timeoutrW�0re)rrKrrr3r�joinrr<rArr�IPSET_WITH_TIMEOUTrD)rZentriesr5rCr"r"r#�
setEntries�s


zFirewallDConfigIPSet.setEntriescCs�t|t�}t|�}tjd|j|�|jj|�t|j	��}d|dkr`|dddkr`t
tj��||dkrxt
tj
|��t||d�|dj|�|j|�dS)Nz%s.addEntry('%s')rhrWrire)rr2r	rr3rrr<rKrArrrkr\r
�appendrD)r�entryr5rCr"r"r#�addEntry�s

zFirewallDConfigIPSet.addEntrycCs�t|t�}t|�}tjd|j|�|jj|�t|j	��}d|dkr`|dddkr`t
tj��||dkrxt
tj
|��|dj|�|j|�dS)Nz%s.removeEntry('%s')rhrWrire)rr2r	rr3rrr<rKrArrrkr`rFrD)rrnr5rCr"r"r#�removeEntry�s

z FirewallDConfigIPSet.removeEntrycCs`t|t�}t|�}tjd|j|�t|j��}d|dkrT|dddkrTtt	j
��||dkS)Nz%s.queryEntry('%s')rhrWrire)rr2r	rr3rrKrArrrk)rrnr5rCr"r"r#�
queryEntry�s

zFirewallDConfigIPSet.queryEntry)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N);�__name__�
__module__�__qualname__�__doc__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredr
rrr$r%r.rZPROPERTIES_IFACEr6r;�slipZpolkitZrequire_authr=�service�signalr>ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr?rrZDBUS_SIGNATURErArDrErBrFrGrIrHrJrMrNrOrQrSrUrVrXr[r_rarcrfrlrorprq�
__classcell__r"r")r!r#r3s�
		




	


r)"Z
gi.repositoryr�sys�modulesrZdbus.serviceZ	slip.dbusrvZslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.io.ipsetrZfirewall.core.ipsetrr	r
rZfirewall.core.loggerrZfirewall.server.decoratorsr
rrrZfirewall.errorsrrwZObjectrr"r"r"r#�<module>s
server/__pycache__/config_ipset.cpython-36.opt-1.pyc000064400000031650150351351720016327 0ustar003

��gzI�@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZmZmZmZddlmZdd	lmZmZmZdd
l	mZddlmZGdd
�d
ejjj �Z!dS)�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�IPSet)�IPSET_TYPES�normalize_ipset_entry�check_entry_overlaps_existing�check_for_overlapping_entries)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�errors)�
FirewallErrorcseZdZdZdZejjZe	�fdd��Z
edd��Zedd��Z
ed	d
��Zeejddd
�edWdd���Zeejddd
�edXdd���Zejjjejj�eejdd�edYdd����Zejjejdd�dd��Zejjjejj�eejdd�edZ�fdd�	���Zeejjejd�ed[d d!���Z eejjejd�ed\d"d#���Z!eejj�ed]d$d%���Z"ejjejjdd�ed&d'���Z#eejj�ed^d(d)���Z$ejjejjdd�ed*d+���Z%eejjdd�ed_d,d-���Z&ejjejjdd�ed.d/���Z'eejjdd�ed`d0d1���Z(eejjdd�edad2d3���Z)eejjdd�edbd4d5���Z*eejjdd�edcd6d7���Z+eejjdd�eddd8d9���Z,eejjdd�eded:d;���Z-eejjdd�edfd<d=���Z.eejjdd�edgd>d?���Z/eejjd@d�edhdAdB���Z0eejjd@d�edidCdD���Z1eejjdd�edjdEdF���Z2eejjdd�edkdGdH���Z3eejjddId
�edldJdK���Z4eejjdLd�edmdMdN���Z5eejjdLd�edndOdP���Z6eejjdd�edodQdR���Z7eejjdd�edpdSdT���Z8eejjddId
�edqdUdV���Z9�Z:S)r�FirewallDConfigIPSetzFirewallD main classTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.ipset.%d)
�superr�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_IPSET)�selfrZconfZipsetr�args�kwargs)�	__class__��"/usr/lib/python3.6/config_ipset.pyr;s

zFirewallDConfigIPSet.__init__cCsdS)Nr")rr"r"r#�__del__HszFirewallDConfigIPSet.__del__cCs|j�dS)N)Zremove_from_connection)rr"r"r#�
unregisterLszFirewallDConfigIPSet.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrr&r'rZBooleanr(r)�
exceptions�
DBusException)r�
property_namer"r"r#�
_get_propertyTsz"FirewallDConfigIPSet._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrrr+r,r.)r�interface_namer-�senderr"r"r#�Getes


zFirewallDConfigIPSet.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existr&r'rr(r)Zsv)�	signature)r&r'rr(r))rr2rr3rrrrr+r,r.Z
Dictionary)rr4r5�ret�xr"r"r#�GetAllvs

zFirewallDConfigIPSet.GetAllZssv)r0cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr2rr3rr�accessCheckrrrr+r,)rr4r-Z	new_valuer5r"r"r#�Set�s



zFirewallDConfigIPSet.Setzsa{sv}as)r8cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr2rr3r)rr4Zchanged_propertiesZinvalidated_propertiesr"r"r#�PropertiesChanged�s


z&FirewallDConfigIPSet.PropertiesChanged)r1cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rrr�
IntrospectrrZget_busrrrr)rr5�data)r!r"r#r?�s

zFirewallDConfigIPSet.IntrospectcCstjd|j�|jj|j�S)zget settings for ipset
        z%s.getSettings())rr3rrZget_ipset_configr)rr5r"r"r#�getSettings�sz FirewallDConfigIPSet.getSettingscCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)z"update settings for ipset
        z%s.update('...')N)rrr3rrr<rZset_ipset_configr�Updatedr&)r�settingsr5r"r"r#�update�s
zFirewallDConfigIPSet.updatecCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z0load default settings for builtin ipset
        z%s.loadDefaults()N)
rr3rrr<rZload_ipset_defaultsrrBr&)rr5r"r"r#�loadDefaults�sz!FirewallDConfigIPSet.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr3r)rr&r"r"r#rB�szFirewallDConfigIPSet.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove ipset
        z%s.remove()N)	rr3rrr<rZremove_ipsetrZremoveIPSet)rr5r"r"r#�remove�szFirewallDConfigIPSet.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr3r)rr&r"r"r#�Removed�szFirewallDConfigIPSet.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename ipset
        z%s.rename('%s')N)rr2rr3rrr<rZrename_ipsetr�Renamed)rr&r5r"r"r#�rename�s

zFirewallDConfigIPSet.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr3r)rr&r"r"r#rH�szFirewallDConfigIPSet.RenamedcCstjd|j�|j�dS)Nz%s.getVersion()r)rr3rrA)rr5r"r"r#�
getVersionszFirewallDConfigIPSet.getVersioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setVersion('%s')r)
rr2rr3rrr<�listrArD)r�versionr5rCr"r"r#�
setVersions
zFirewallDConfigIPSet.setVersioncCstjd|j�|j�dS)Nz
%s.getShort()r)rr3rrA)rr5r"r"r#�getShortszFirewallDConfigIPSet.getShortcCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setShort('%s')r)
rr2rr3rrr<rKrArD)rZshortr5rCr"r"r#�setShorts
zFirewallDConfigIPSet.setShortcCstjd|j�|j�dS)Nz%s.getDescription()�)rr3rrA)rr5r"r"r#�getDescription(sz#FirewallDConfigIPSet.getDescriptioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setDescription('%s')rP)
rr2rr3rrr<rKrArD)r�descriptionr5rCr"r"r#�setDescription/s

z#FirewallDConfigIPSet.setDescriptioncCstjd|j�|j�dS)Nz%s.getType()�)rr3rrA)rr5r"r"r#�getType=szFirewallDConfigIPSet.getTypecCs\t|t�}tjd|j|�|jj|�|tkr:tt	j
|��t|j��}||d<|j
|�dS)Nz%s.setType('%s')rT)rr2rr3rrr<rrrZINVALID_TYPErKrArD)rZ
ipset_typer5rCr"r"r#�setTypeDs
zFirewallDConfigIPSet.setTypeza{ss}cCstjd|j�|j�dS)Nz%s.getOptions()�)rr3rrA)rr5r"r"r#�
getOptionsSszFirewallDConfigIPSet.getOptionscCsLt|t�}tjd|jt|��|jj|�t|j	��}||d<|j
|�dS)Nz%s.setOptions('[%s]')rW)r�dictrr3r�reprrr<rKrArD)rZoptionsr5rCr"r"r#�
setOptionsZs


zFirewallDConfigIPSet.setOptionscCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||dkrn|d||krnt	t
jd||f��||d|<|j|�dS)Nz%s.addOption('%s', '%s')rWz
'%s': '%s')
rr2rr3rrr<rKrArr�ALREADY_ENABLEDrD)r�key�valuer5rCr"r"r#�	addOptionfs

zFirewallDConfigIPSet.addOptioncCsbt|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|d|=|j|�dS)Nz%s.removeOption('%s')rW)
rr2rr3rrr<rKrArr�NOT_ENABLEDrD)rr]r5rCr"r"r#�removeOptionus

z!FirewallDConfigIPSet.removeOption�bcCsNt|t�}t|t�}tjd|j||�t|j��}||dkoL|d||kS)Nz%s.queryOption('%s', '%s')rW)rr2rr3rrKrA)rr]r^r5rCr"r"r#�queryOption�s

z FirewallDConfigIPSet.queryOption�ascCstjd|j�|j�dS)Nz%s.getEntries()�)rr3rrA)rr5r"r"r#�
getEntries�szFirewallDConfigIPSet.getEntriescCs|t|t�}t|�tjd|jdj|��|jj|�t|j	��}d|dkrf|dddkrft
tj��||d<|j
|�dS)Nz%s.setEntries('[%s]')�,�timeoutrW�0re)rrKrrr3r�joinrr<rArr�IPSET_WITH_TIMEOUTrD)rZentriesr5rCr"r"r#�
setEntries�s


zFirewallDConfigIPSet.setEntriescCs�t|t�}t|�}tjd|j|�|jj|�t|j	��}d|dkr`|dddkr`t
tj��||dkrxt
tj
|��t||d�|dj|�|j|�dS)Nz%s.addEntry('%s')rhrWrire)rr2r	rr3rrr<rKrArrrkr\r
�appendrD)r�entryr5rCr"r"r#�addEntry�s

zFirewallDConfigIPSet.addEntrycCs�t|t�}t|�}tjd|j|�|jj|�t|j	��}d|dkr`|dddkr`t
tj��||dkrxt
tj
|��|dj|�|j|�dS)Nz%s.removeEntry('%s')rhrWrire)rr2r	rr3rrr<rKrArrrkr`rFrD)rrnr5rCr"r"r#�removeEntry�s

z FirewallDConfigIPSet.removeEntrycCs`t|t�}t|�}tjd|j|�t|j��}d|dkrT|dddkrTtt	j
��||dkS)Nz%s.queryEntry('%s')rhrWrire)rr2r	rr3rrKrArrrk)rrnr5rCr"r"r#�
queryEntry�s

zFirewallDConfigIPSet.queryEntry)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N);�__name__�
__module__�__qualname__�__doc__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredr
rrr$r%r.rZPROPERTIES_IFACEr6r;�slipZpolkitZrequire_authr=�service�signalr>ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr?rrZDBUS_SIGNATURErArDrErBrFrGrIrHrJrMrNrOrQrSrUrVrXr[r_rarcrfrlrorprq�
__classcell__r"r")r!r#r3s�
		




	


r)"Z
gi.repositoryr�sys�modulesrZdbus.serviceZ	slip.dbusrvZslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.io.ipsetrZfirewall.core.ipsetrr	r
rZfirewall.core.loggerrZfirewall.server.decoratorsr
rrrZfirewall.errorsrrwZObjectrr"r"r"r#�<module>s
server/__pycache__/config.cpython-36.opt-1.pyc000064400000127767150351351720015142 0ustar003

��g��@sdddlmZddlZeejd<ddlZddlZddlZddlZddl	Zddl
mZddlm
Z
ddlmZddlmZddlmZmZmZdd	lmZdd
lmZddlmZddlmZdd
lmZddl m!Z!ddl"m#Z#ddl$m%Z%ddl&m'Z'ddl(m)Z)ddl*m+Z+ddl,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3ddl
m4Z4ddl5m6Z6Gdd�dejj7j8�Z9dS)�)�GObjectNZgobject)�config)�DEFAULT_ZONE_TARGET)�Watcher)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�FirewallDConfigIcmpType)�FirewallDConfigService)�FirewallDConfigZone)�FirewallDConfigPolicy)�FirewallDConfigIPSet)�FirewallDConfigHelper)�IcmpType)�IPSet)�Helper)�LockdownWhitelist)�Direct)�dbus_to_python�command_of_sender�context_of_sender�
uid_of_sender�user_of_uid�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�errors)�
FirewallErrorcs@eZdZdZdZejjZe	�fdd��Z
e	dd��Ze	dd��Ze	d	d
��Z
e	dd��Ze	d
d��Ze	dd��Ze	dd��Ze	dd��Ze	dd��Ze	dd��Ze	dd��Ze	dd��Ze	dd��Ze	dd ��Ze	d!d"��Ze	d#d$��Ze	d%d&��Ze	d'd(��Ze	d)d*��Ze	d+d,��Ze	d-d.��Ze	d/d0��Z e!d1d2��Z"e!d3d4��Z#e!d5d6��Z$e%ej&d7d8d9�e!d�d;d<���Z'e%ej&d=d>d9�e!d�d?d@���Z(e)jj*j+ejj�e%ej&dAdB�e!d�dCdD����Z,ej-j.ej&dEdF�dGdH��Z/e)jj*j+ejj0�e%ej1d=dI�e!d�fdJdK�	���Z2e%ejj3e4j5dI�e!d�dLdM���Z6e%ejj3e4j5dB�e!d�dNdO���Z7ej-j.ejj3�e!dPdQ���Z8e%ejj3d=dB�e!d�dRdS���Z9e%ejj3d=dB�e!d�dTdU���Z:e%ejj3d=dVd9�e!d�dWdX���Z;e%ejj3dYdI�e!d�dZd[���Z<e%ejj3d=dB�e!d�d\d]���Z=e%ejj3d=dB�e!d�d^d_���Z>e%ejj3d=dVd9�e!d�d`da���Z?e%ejj3dYdI�e!d�dbdc���Z@e%ejj3d=dB�e!d�ddde���ZAe%ejj3d=dB�e!d�dfdg���ZBe%ejj3d=dVd9�e!d�dhdi���ZCe%ejj3dYdI�e!d�djdk���ZDe%ejj3dldB�e!�ddmdn���ZEe%ejj3dldB�e!�ddodp���ZFe%ejj3dldVd9�e!�ddqdr���ZGe%ejj3dsdI�e!�ddtdu���ZHe%ejjIdvdI�e!�ddwdx���ZJe%ejjIdYdI�e!�ddydz���ZKe%ejjId=d{d9�e!�dd|d}���ZLe%ejjId=eMj5d{d9�e!�dd~d���ZNej-j.ejjId=dF�e!d�d����ZOe%ejjIdvdI�e!�dd�d����ZPe%ejjIdYdI�e!�d	d�d����ZQe%ejjId=d{d9�e!�d
d�d����ZRe%ejjId=eSj5d{d9�e!�dd�d����ZTej-j.ejjId=dF�e!d�d����ZUe%ejjIdvdI�e!�dd�d����ZVe%ejjIdYdI�e!�d
d�d����ZWe%ejjId=d{d9�e!�dd�d����ZXe%ejjId�d{d9�e!�dd�d����ZYe%ejjId�d{d9�e!�dd�d����ZZej-j.ejjId=dF�e!d�d����Z[e%ejjIdvdI�e!�dd�d����Z\e%ejjIdYdI�e!�dd�d����Z]e%ejjId=d{d9�e!�dd�d����Z^e%ejjId=d=d9�e!�dd�d����Z_e%ejjId=d=d9�e!�dd�d����Z`e%ejjId�d{d9�e!�dd�d����Zae%ejjId�d{d9�e!�dd�d����Zbej-j.ejjId=dF�e!d�d����Zce%ejjIdvdI�e!�dd�d����Zde%ejjIdYdI�e!�dd�d����Zee%ejjId=d{d9�e!�dd�d����Zfe%ejjId�d{d9�e!�dd�d����Zgej-j.ejjId=dF�e!d�d����Zhe%ejjIdvdI�e!�dd�d����Zie%ejjIdYdI�e!�dd�d����Zje%ejjId=d{d9�e!�dd�d����Zke%ejjId=elj5d{d9�e!�dd�d����Zmej-j.ejjId=dF�e!d�d����Zne%ejjoepj5dI�e!�d d�d����Zqe%ejjoepj5dB�e!�d!d�d„��Zrej-j.ejjo�e!d�dĄ��Zse%ejjod�dB�e!�d"d�dDŽ��Zte%ejjod�dB�e!�d#d�dɄ��Zue%ejjod�dVd9�e!�d$d�d˄��Zve%ejjod7dYd9�e!�d%d�d̈́��Zwe%ejjod�d�d9�e!�d&d�dф��Zxe%ejjod�dB�e!�d'd�dԄ��Zye%ejjod�dB�e!�d(d�dք��Zze%ejjod�dVd9�e!�d)d�d؄��Z{e%ejjod�dB�e!�d*d�dڄ��Z|e%ejjod�d�d9�e!�d+d�d݄��Z}e%ejjod�d�d9�e!�d,d�d���Z~e%ejjod�dB�e!�d-d�d���Ze%ejjod�dB�e!�d.d�d���Z�e%ejjod�dVd9�e!�d/d�d���Z�e%ejjod=d�d9�e!�d0d�d���Z�e%ejjod�dI�e!�d1d�d���Z��Z�S(2�FirewallDConfigzFirewallD main classTcs�tt|�j||�||_|d|_|d|_|j�t|jd�|_	|j	j
tj�|j	j
tj�|j	j
tj
�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�tjjtj��r>xBttjtj��D].}dtj|f}tjj|��r|j	j
|��qW|j	jtj�|j	jtj�|j	jtj�t |tj!j"ddddddddddddd��dS)Nr��z%s/%sZ	readwrite)�
CleanupOnExit�CleanupModulesOnExit�
IPv6_rpfilter�Lockdown�MinimalMark�IndividualCalls�	LogDenied�AutomaticHelpers�FirewallBackend�FlushAllOnReload�RFC3964_IPv4�AllowZoneDrifting)#�superr�__init__r�busname�path�
_init_varsr�
watch_updater�watcher�
add_watch_dir�FIREWALLD_IPSETS�ETC_FIREWALLD_IPSETS�FIREWALLD_ICMPTYPES�ETC_FIREWALLD_ICMPTYPES�FIREWALLD_HELPERS�ETC_FIREWALLD_HELPERS�FIREWALLD_SERVICES�ETC_FIREWALLD_SERVICES�FIREWALLD_ZONES�ETC_FIREWALLD_ZONES�FIREWALLD_POLICIES�ETC_FIREWALLD_POLICIES�os�exists�sorted�listdir�isdirZadd_watch_file�LOCKDOWN_WHITELIST�FIREWALLD_DIRECT�FIREWALLD_CONFr�dbus�DBUS_INTERFACE_CONFIG)�selfZconf�args�kwargs�filenamer0)�	__class__��/usr/lib/python3.6/config.pyr.FsP

zFirewallDConfig.__init__cCs2g|_d|_g|_d|_g|_d|_g|_d|_g|_d|_	g|_
d|_x$|jj
�D]}|j|jj|��qTWx$|jj�D]}|j|jj|��qzWx$|jj�D]}|j|jj|��q�Wx$|jj�D]}|j|jj|��q�Wx$|jj�D]}|j|jj|��q�Wx&|jj�D]}|j|jj|���qWdS)Nr)�ipsets�	ipset_idx�	icmptypes�icmptype_idx�services�service_idx�zones�zone_idx�helpers�
helper_idx�policy_objects�policy_object_idxrZ
get_ipsets�	_addIPSetZ	get_ipsetZ
get_icmptypes�_addIcmpTypeZget_icmptypeZget_services�_addServiceZget_serviceZ	get_zones�_addZoneZget_zoneZget_helpers�
_addHelperZ
get_helperZget_policy_objects�
_addPolicyZget_policy_object)rK�ipset�icmptype�service�zone�helper�policyrPrPrQr1ts0zFirewallDConfig._init_varscCsdS)NrP)rKrPrPrQ�__del__�szFirewallDConfig.__del__cCs�x&t|j�dkr&|jj�}|j�~qWx&t|j�dkrN|jj�}|j�~q*Wx&t|j�dkrv|jj�}|j�~qRWx&t|j�dkr�|jj�}|j�~qzWx&t|j�dkr�|jj�}|j�~q�Wx&t|j�dkr�|jj�}|j�~q�W|j	�dS)Nr)
�lenrR�pop�
unregisterrTrVrXrZr\r1)rK�itemrPrPrQ�reload�s2





zFirewallDConfig.reloadc	CsJ|tjkr�|jtjj�}tjdtj�y|jj�Wn2tk
rf}ztj	d||f�dSd}~XnX|jtjj�j
�}x2t|j��D]"}||kr�||||kr�||=q�Wt
|�dkr�|jtjj|g�dS|jtj�s�|jtj�o�|jd��r�y|jj|�\}}Wn4tk
�r<}ztj	d||f�dSd}~XnX|dk�rT|j|�n*|dk�rj|j|�n|dk�rF|j|��n�|jtj��s�|jtj��r8|jd��r8y|jj|�\}}Wn4tk
�r�}ztj	d	||f�dSd}~XnX|dk�r
|j|�n*|dk�r |j|�n|dk�rF|j|��n|jtj��sT|jtj��rr|jd��r�y|jj|�\}}Wn4tk
�r�}ztj	d
||f�dSd}~XnX|dk�r�|j |�n*|dk�r�|j!|�n|dk�rn|j"|�n�|jtj��rF|j#tjd�j$d�}t
|�d
k�s&d|k�r*dSt%j&j'|��rT|j(j)|��sn|j(j*|�n|j(j)|��rF|j(j+|��n�|jtj,��s�|jtj-��r(|jd��r(y|jj.|�\}}Wn4tk
�r�}ztj	d||f�dSd}~XnX|dk�r�|j/|�n*|dk�r|j0|�n|dk�rF|j1|��n|jtj2��sD|jtj3��r�|jd��r�y|jj4|�\}}Wn4tk
�r�}ztj	d||f�dSd}~XnX|dk�r�|j5|�n*|dk�r�|j6|�n|dk�rF|j7|��nh|tj8k�r:y|jj9�Wn4tk
�r,}ztj	d||f�dSd}~XnX|j:��n|tj;k�r�y|jj<�Wn4tk
�r�}ztj	d||f�dSd}~XnX|j=�n�|jtj>��s�|jtj?��rF|jd��rFy|jj@|�\}}Wn4tk
�r}ztj	d||f�dSd}~XnX|dk�r|jA|�n*|dk�r2|jB|�n|dk�rF|jC|�dS)Nz,config: Reloading firewalld config file '%s'z+Failed to load firewalld.conf file '%s': %srz.xmlz%Failed to load icmptype file '%s': %s�new�remove�updatez$Failed to load service file '%s': %sz!Failed to load zone file '%s': %s��/rz"Failed to load ipset file '%s': %sz#Failed to load helper file '%s': %sz/Failed to load lockdown whitelist file '%s': %sz)Failed to load direct rules file '%s': %sz#Failed to load policy file '%s': %s)DrrH�GetAllrIrJr�debug1Zupdate_firewalld_conf�	Exception�error�copy�list�keysrk�PropertiesChanged�
startswithr7r8�endswithZupdate_icmptype_from_pathr_�removeIcmpType�_updateIcmpTyper;r<Zupdate_service_from_pathr`�
removeService�_updateServicer=r>Zupdate_zone_from_pathra�
removeZone�_updateZone�replace�striprAr0rEr3Z	has_watchr4Zremove_watchr5r6Zupdate_ipset_from_pathr^�removeIPSet�_updateIPSetr9r:Zupdate_helper_from_pathrb�removeHelper�
_updateHelperrFZupdate_lockdown_whitelist�LockdownWhitelistUpdatedrGZ
update_direct�Updatedr?r@Zupdate_policy_object_from_pathrc�removePolicy�
_updatePolicy)	rK�nameZ	old_props�msgZprops�keyZwhat�obj�_namerPrPrQr2�s
























zFirewallDConfig.watch_updaterc	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
r
rrUr/rIZDBUS_PATH_CONFIG_ICMPTYPErT�append�
IcmpTypeAddedr�)rKr��config_icmptyperPrPrQr_AszFirewallDConfig._addIcmpTypecCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)rTr�r�r0rNr�)rKr�rerPrPrQr�MszFirewallDConfig._updateIcmpTypecCs�d}xT|jD]J}|j�}|j||kr||j|j�|jj|j|�|_|j|jj�qWx\|jD]R}|j�}d|krb|j|dkrb|dj|j�|jj	|j|�|_|j|jj�qbWx:|j
D]0}|j|kr�|j|j�|j�|j
j|�~q�WdS)N�Zicmp_blocks)
rX�getSettingsr�rqr�set_zone_configr�r�r\�set_policy_object_config_dictrT�Removedrm)rKr��indexrg�settingsrirerPrPrQrVs&
zFirewallDConfig.removeIcmpTypec	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
rrrWr/rIZDBUS_PATH_CONFIG_SERVICErVr��ServiceAddedr�)rKr��config_servicerPrPrQr`pszFirewallDConfig._addServicecCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)rVr�r�r0rNr�)rKr�rfrPrPrQr�{szFirewallDConfig._updateServicecCs�d}xT|jD]J}|j�}|j||kr||j|j�|jj|j|�|_|j|jj�qWx\|jD]R}|j�}d|krb|j|dkrb|dj|j�|jj	|j|�|_|j|jj�qbWx:|j
D]0}|j|kr�|j|j�|j�|j
j|�~q�WdS)Nr rV)
rXr�r�rqrr�r�r�r\r�rVr�rm)rKr�r�rgr�rirfrPrPrQr��s&
zFirewallDConfig.removeServicec	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
rrrYr/rIZDBUS_PATH_CONFIG_ZONErXr��	ZoneAddedr�)rKr��config_zonerPrPrQra�szFirewallDConfig._addZonecCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)rXr�r�r0rNr�)rKr�rgrPrPrQr��s
zFirewallDConfig._updateZonecCs@x:|jD]0}|j|kr|j|j�|j�|jj|�~qWdS)N)rXr�r�r�rmrq)rKr�rgrPrPrQr��s
zFirewallDConfig.removeZonec	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
r
rr]r/rIZDBUS_PATH_CONFIG_POLICYr\r��PolicyAddedr�)rKr��
config_policyrPrPrQrc�szFirewallDConfig._addPolicycCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)r\r�r�r0rNr�)rKr�rirPrPrQr��s
zFirewallDConfig._updatePolicycCs@x:|jD]0}|j|kr|j|j�|j�|jj|�~qWdS)N)r\r�r�r�rmrq)rKr�rirPrPrQr��s
zFirewallDConfig.removePolicyc	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
rrrSr/rIZDBUS_PATH_CONFIG_IPSETrRr��
IPSetAddedr�)rKr��config_ipsetrPrPrQr^�szFirewallDConfig._addIPSetcCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)rRr�r�r0rNr�)rKr�rdrPrPrQr��s
zFirewallDConfig._updateIPSetcCs@x:|jD]0}|j|kr|j|j�|j�|jj|�~qWdS)N)rRr�r�r�rmrq)rKr�rdrPrPrQr��s
zFirewallDConfig.removeIPSetc	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
rrr[r/rIZDBUS_PATH_CONFIG_HELPERrZr��HelperAddedr�)rKr��
config_helperrPrPrQrb�szFirewallDConfig._addHelpercCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)rZr�r�r0rNr�)rKr�rhrPrPrQr��s
zFirewallDConfig._updateHelpercCs@x:|jD]0}|j|kr|j|j�|j�|jj|�~qWdS)N)rZr�r�r�rmrq)rKr�rhrPrPrQr�s
zFirewallDConfig.removeHelpercCs�|jj�r�|dkr tjd�dStj�}t||�}|jjd|�rDdSt||�}|jjd|�r`dSt	|�}|jjd|�rzdSt
||�}|jjd|�r�dSttj
d��dS)Nz&Lockdown not possible, sender not set.�context�uid�user�commandzlockdown is enabled)rZlockdown_enabledrrxrIZ	SystemBusrZaccess_checkrrrrrZ
ACCESS_DENIED)rK�senderZbusr�r�r�r�rPrPrQ�accessChecks$




zFirewallDConfig.accessCheckcCsF|dkrtjjd|��|jj�j|�}|dkrH|dkr>tj}tj|�S|dkrr|dkr`tj}nt	|�}tj
|�S|dkr�|dkr�tjr�dnd}tj|�S|dkr�|dkr�tjr�dnd}tj|�S|dk�r�|dk�r�tj
�r�dnd}tj|�S|dk�r|dk�rtj�rdnd}tj|�S|dk�rL|dk�rBtj�r>dnd}tj|�S|dk�rp|dk�rftj}tj|�S|d	k�r�|dk�r�tj}tj|�S|d
k�r�|dk�r�tj}tj|�S|dk�r�|dk�r�tj�r�dnd}tj|�S|dk�r|dk�r
tj�rdnd}tj|�S|d
k�rB|dk�r8tj�r4dnd}tj|�SdS)N�DefaultZoner%r!r"r$r#r&r'r(r)r*r+r,zDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist�yes�no)
r�r%r!r"r$r#r&r'r(r)r*r+r,)rI�
exceptions�
DBusExceptionr�get_firewalld_conf�getZ
FALLBACK_ZONE�StringZFALLBACK_MINIMAL_MARK�int�Int32ZFALLBACK_CLEANUP_ON_EXITZ FALLBACK_CLEANUP_MODULES_ON_EXITZFALLBACK_LOCKDOWNZFALLBACK_IPV6_RPFILTERZFALLBACK_INDIVIDUAL_CALLSZFALLBACK_LOG_DENIEDZFALLBACK_AUTOMATIC_HELPERSZFALLBACK_FIREWALL_BACKENDZFALLBACK_FLUSH_ALL_ON_RELOADZFALLBACK_RFC3964_IPV4ZFALLBACK_ALLOW_ZONE_DRIFTING)rK�prop�valuerPrPrQ�
_get_property+s|





























zFirewallDConfig._get_propertycCsT|dkrtj|j|��S|dkr0tj|j|��S|dkrHtj|j|��S|dkr`tj|j|��S|dkrxtj|j|��S|dkr�tj|j|��S|dkr�tj|j|��S|dkr�tj|j|��S|d	kr�tj|j|��S|d
k�r�tj|j|��S|dk�rtj|j|��S|dk�r&tj|j|��S|d
k�r@tj|j|��Stjjd|��dS)Nr�r%r!r"r$r#r&r'r(r)r*r+r,zDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)rIr�r�r�r�r�)rKr�rPrPrQ�_get_dbus_propertyos:



z"FirewallDConfig._get_dbus_propertyZss�v)�in_signature�
out_signatureNcCsxt|t�}t|t�}tjd||�|tjjkr8|j|�S|tjjtjj	gkr^tj
jd|��ntj
jd|��|j|�S)Nzconfig.Get('%s', '%s')zDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not existzJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strrrvrrIrJr��DBUS_INTERFACE_CONFIG_DIRECT�DBUS_INTERFACE_CONFIG_POLICIESr�r�)rK�interface_name�
property_namer�rPrPrQ�Get�s



zFirewallDConfig.Get�sza{sv}c
Csxt|t�}tjd|�i}|tjjkrDxBdD]}|j|�||<q,Wn&|tjjtjj	gkrZntj
jd|��tj|dd�S)Nzconfig.GetAll('%s')r�r%r!r"r$r#r&r'r(r)r*r+r,zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existZsv)�	signature)
r�r%r!r"r$r#r&r'r(r)r*r+r,)
rr�rrvrrIrJr�r�r�r�r�Z
Dictionary)rKr�r��ret�xrPrPrQru�s"
zFirewallDConfig.GetAllZssv)r�cCs�t|t�}t|t�}t|�}tjd|||�|j|�|tjjk�r�|dk�rz|dkrv|j�dkrvt	t
jd||f��|dkr�|tjkr�t	t
jd||f��|dkr�|tj
kr�t	t
jd||f��|d	k�r�|j�dk�r�t	t
jd||f��|d
k�r|j�dk�rt	t
jd||f��|dk�rF|j�dk�rFt	t
jd||f��|jj�j||�|jj�j�|j|||ig�n|dk�r�ntjjd|��n8|tjjtjjgk�r�tjjd|��ntjjd|��dS)Nzconfig.Set('%s', '%s', '%s')r!r$r"r#r&r'r)r*r+r,r�r��true�falsez'%s' for %sr%r(zDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not existzJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)
r!r$r"r#r&r'r)r*r+r,)r!r$r"r#r&)r�r�r�r�)r�r�r�r�)r�r�r�r�)r�r�r�r�)r%r()rr�rrvr�rrIrJ�lowerrrZ
INVALID_VALUEZLOG_DENIED_VALUESZFIREWALL_BACKEND_VALUESr��set�writer|r�r�r�r�)rKr�r�Z	new_valuer�rPrPrQ�Set�sz










zFirewallDConfig.Setzsa{sv}as)r�cCs.t|t�}t|�}t|�}tjd|||�dS)Nz*config.PropertiesChanged('%s', '%s', '%s'))rr�rrv)rKr�Zchanged_propertiesZinvalidated_propertiesrPrPrQr|s

z!FirewallDConfig.PropertiesChanged)r�cs4tjd�tt|�j|j|jj��}t||t	j
j�S)Nzconfig.Introspect())rZdebug2r-r�
Introspectr0r/Zget_busrrrIrJ)rKr��data)rOrPrQr�s

zFirewallDConfig.IntrospectcCstjd�|jj�jj�S)Nz&config.policies.getLockdownWhitelist())rrvr�get_policies�lockdown_whitelist�
export_config)rKr�rPrPrQ�getLockdownWhitelists
z$FirewallDConfig.getLockdownWhitelistcCs@tjd�t|�}|jj�jj|�|jj�jj�|j�dS)Nz)config.policies.setLockdownWhitelist(...))	rrvrrr�r��
import_configr�r�)rKr�r�rPrPrQ�setLockdownWhitelist&s

z$FirewallDConfig.setLockdownWhitelistcCstjd�dS)Nz*config.policies.LockdownWhitelistUpdated())rrv)rKrPrPrQr�0sz(FirewallDConfig.LockdownWhitelistUpdatedcCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz1config.policies.addLockdownWhitelistCommand('%s')r)rrrvr�rzr�rr�ALREADY_ENABLEDr�r�)rKr�r�r�rPrPrQ�addLockdownWhitelistCommand7s
z+FirewallDConfig.addLockdownWhitelistCommandcCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz4config.policies.removeLockdownWhitelistCommand('%s')r)rrrvr�rzr�rr�NOT_ENABLEDrqr�)rKr�r�r�rPrPrQ�removeLockdownWhitelistCommandDs
z.FirewallDConfig.removeLockdownWhitelistCommand�bcCs$t|�}tjd|�||j�dkS)Nz3config.policies.queryLockdownWhitelistCommand('%s')r)rrrvr�)rKr�r�rPrPrQ�queryLockdownWhitelistCommandRsz-FirewallDConfig.queryLockdownWhitelistCommand�ascCstjd�|j�dS)Nz.config.policies.getLockdownWhitelistCommands()r)rrvr�)rKr�rPrPrQ�getLockdownWhitelistCommands[s
z,FirewallDConfig.getLockdownWhitelistCommandscCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz1config.policies.addLockdownWhitelistContext('%s')r)rrrvr�rzr�rrr�r�r�)rKr�r�r�rPrPrQ�addLockdownWhitelistContextds
z+FirewallDConfig.addLockdownWhitelistContextcCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz4config.policies.removeLockdownWhitelistContext('%s')r)rrrvr�rzr�rrr�rqr�)rKr�r�r�rPrPrQ�removeLockdownWhitelistContextqs
z.FirewallDConfig.removeLockdownWhitelistContextcCs$t|�}tjd|�||j�dkS)Nz3config.policies.queryLockdownWhitelistContext('%s')r)rrrvr�)rKr�r�rPrPrQ�queryLockdownWhitelistContextsz-FirewallDConfig.queryLockdownWhitelistContextcCstjd�|j�dS)Nz.config.policies.getLockdownWhitelistContexts()r)rrvr�)rKr�rPrPrQ�getLockdownWhitelistContexts�s
z,FirewallDConfig.getLockdownWhitelistContextscCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz.config.policies.addLockdownWhitelistUser('%s')�)rrrvr�rzr�rrr�r�r�)rKr�r�r�rPrPrQ�addLockdownWhitelistUser�s
z(FirewallDConfig.addLockdownWhitelistUsercCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz1config.policies.removeLockdownWhitelistUser('%s')r�)rrrvr�rzr�rrr�rqr�)rKr�r�r�rPrPrQ�removeLockdownWhitelistUser�s
z+FirewallDConfig.removeLockdownWhitelistUsercCs$t|�}tjd|�||j�dkS)Nz0config.policies.queryLockdownWhitelistUser('%s')r�)rrrvr�)rKr�r�rPrPrQ�queryLockdownWhitelistUser�sz*FirewallDConfig.queryLockdownWhitelistUsercCstjd�|j�dS)Nz+config.policies.getLockdownWhitelistUsers()r�)rrvr�)rKr�rPrPrQ�getLockdownWhitelistUsers�s
z)FirewallDConfig.getLockdownWhitelistUsers�icCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz+config.policies.addLockdownWhitelistUid(%d)�)rrrvr�rzr�rrr�r�r�)rKr�r�r�rPrPrQ�addLockdownWhitelistUid�s
z'FirewallDConfig.addLockdownWhitelistUidcCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz.config.policies.removeLockdownWhitelistUid(%d)r�)rrrvr�rzr�rrr�rqr�)rKr�r�r�rPrPrQ�removeLockdownWhitelistUid�s
z*FirewallDConfig.removeLockdownWhitelistUidcCs$t|�}tjd|�||j�dkS)Nz-config.policies.queryLockdownWhitelistUid(%d)r�)rrrvr�)rKr�r�rPrPrQ�queryLockdownWhitelistUid�sz)FirewallDConfig.queryLockdownWhitelistUidZaicCstjd�|j�dS)Nz*config.policies.getLockdownWhitelistUids()r�)rrvr�)rKr�rPrPrQ�getLockdownWhitelistUids�s
z(FirewallDConfig.getLockdownWhitelistUidsZaocCstjd�|jS)z"list ipsets objects paths
        zconfig.listIPSets())rrvrR)rKr�rPrPrQ�
listIPSets�s
zFirewallDConfig.listIPSetscCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget ipset names
        zconfig.getIPSetNames())rrvrRr�r�r�rC)rKr�rRr�rPrPrQ�
getIPSetNames�s

zFirewallDConfig.getIPSetNames�ocCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z-object path of ipset with given name
        zconfig.getIPSetByName('%s')N)
rr�rrvrRr�r�rrZ
INVALID_IPSET)rKrdr�r�rPrPrQ�getIPSetByName�s
zFirewallDConfig.getIPSetByNamecCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z/add ipset with given name and settings
        zconfig.addIPSet('%s'))rr�rrvr�rZ	new_ipsetr^)rKrdr�r�r�r�rPrPrQ�addIPSet	s


zFirewallDConfig.addIPSetcCst|t�}tjd|�dS)Nzconfig.IPSetAdded('%s'))rr�rrv)rKrdrPrPrQr�s
zFirewallDConfig.IPSetAddedcCstjd�|jS)z%list icmptypes objects paths
        zconfig.listIcmpTypes())rrvrT)rKr�rPrPrQ�
listIcmpTypes s
zFirewallDConfig.listIcmpTypescCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget icmptype names
        zconfig.getIcmpTypeNames())rrvrTr�r�r�rC)rKr�rTr�rPrPrQ�getIcmpTypeNames(s

z FirewallDConfig.getIcmpTypeNamescCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z0object path of icmptype with given name
        zconfig.getIcmpTypeByName('%s')N)
rr�rrvrTr�r�rrZINVALID_ICMPTYPE)rKrer�r�rPrPrQ�getIcmpTypeByName3s
z!FirewallDConfig.getIcmpTypeByNamecCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z2add icmptype with given name and settings
        zconfig.addIcmpType('%s'))rr�rrvr�rZnew_icmptyper_)rKrer�r�r�r�rPrPrQ�addIcmpType@s


zFirewallDConfig.addIcmpTypecCstjd|�dS)Nzconfig.IcmpTypeAdded('%s'))rrv)rKrerPrPrQr�OszFirewallDConfig.IcmpTypeAddedcCstjd�|jS)z$list services objects paths
        zconfig.listServices())rrvrV)rKr�rPrPrQ�listServicesVs
zFirewallDConfig.listServicescCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget service names
        zconfig.getServiceNames())rrvrVr�r�r�rC)rKr�rVr�rPrPrQ�getServiceNames^s

zFirewallDConfig.getServiceNamescCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z/object path of service with given name
        zconfig.getServiceByName('%s')N)
rr�rrvrVr�r�rrZINVALID_SERVICE)rKrfr�r�rPrPrQ�getServiceByNameis
z FirewallDConfig.getServiceByNamezs(sssa(ss)asa{ss}asa(ss))cCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z1add service with given name and settings
        zconfig.addService('%s'))rr�rrvr�rZnew_servicer`)rKrfr�r�r�r�rPrPrQ�
addServicevs


zFirewallDConfig.addServicezsa{sv}cCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z1add service with given name and settings
        zconfig.addService2('%s'))rr�rrvr�rZnew_service_dictr`)rKrfr�r�r�r�rPrPrQ�addService2�s


zFirewallDConfig.addService2cCstjd|�dS)Nzconfig.ServiceAdded('%s'))rrv)rKrfrPrPrQr��szFirewallDConfig.ServiceAddedcCstjd�|jS)z!list zones objects paths
        zconfig.listZones())rrvrX)rKr�rPrPrQ�	listZones�s
zFirewallDConfig.listZonescCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget zone names
        zconfig.getZoneNames())rrvrXr�r�r�rC)rKr�rXr�rPrPrQ�getZoneNames�s

zFirewallDConfig.getZoneNamescCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z,object path of zone with given name
        zconfig.getZoneByName('%s')N)
rr�rrvrXr�r�rrZINVALID_ZONE)rKrgr�r�rPrPrQ�
getZoneByName�s
zFirewallDConfig.getZoneByNamecCszt|t�}tjd|�g}x(|jD]}||jjkr"|j|jj�q"Wt	|�dkrjdj
|�d|t	|�fS|rv|dSdS)z4name of zone the given interface belongs to
        zconfig.getZoneOfInterface('%s')r� zE  (ERROR: interface '%s' is in %s zone XML files, can be only in one)rrs)rr�rrvrXr�Z
interfacesr�r�rk�join)rKZifacer�r�r�rPrPrQ�getZoneOfInterface�s
z"FirewallDConfig.getZoneOfInterfacecCszt|t�}tjd|�g}x(|jD]}||jjkr"|j|jj�q"Wt	|�dkrjdj
|�d|t	|�fS|rv|dSdS)z1name of zone the given source belongs to
        zconfig.getZoneOfSource('%s')rr�zB  (ERROR: source '%s' is in %s zone XML files, can be only in one)rrs)rr�rrvrXr�Zsourcesr�r�rkr)rK�sourcer�r�r�rPrPrQ�getZoneOfSource�s
zFirewallDConfig.getZoneOfSourcez's(sssbsasa(ss)asba(ssss)asasasasa(ss)b)cCsht|t�}t|�}tjd|�|j|�|ddkrLt|�}t|d<t|�}|jj	||�}|j
|�}|S)z.add zone with given name and settings
        zconfig.addZone('%s')��default)rr�rrvr�rzr�tuplerZnew_zonera)rKrgr�r�Z	_settingsr�r�rPrPrQ�addZone�s


zFirewallDConfig.addZonecCs`t|t�}t|�}tjd|�|j|�d|krD|ddkrDt|d<|jj||�}|j|�}|S)z.add zone with given name and settings
        zconfig.addZone('%s')�targetr)	rr�rrvr�rrZ
new_zone_dictra)rKrgr�r�r�r�rPrPrQ�addZone2�s


zFirewallDConfig.addZone2cCstjd|�dS)Nzconfig.ZoneAdded('%s'))rrv)rKrgrPrPrQr�szFirewallDConfig.ZoneAddedcCstjd�|jS)z$list policies objects paths
        zconfig.listPolicies())rrvr\)rKr�rPrPrQ�listPoliciess
zFirewallDConfig.listPoliciescCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget policy names
        zconfig.getPolicyNames())rrvr\r�r�r�rC)rKr�Zpoliciesr�rPrPrQ�getPolicyNamess

zFirewallDConfig.getPolicyNamescCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z.object path of policy with given name
        zconfig.getPolicyByName('%s')N)
rr�rrvr\r�r�rrZINVALID_POLICY)rKrir�r�rPrPrQ�getPolicyByName"s
zFirewallDConfig.getPolicyByNamecCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z0add policy with given name and settings
        zconfig.addPolicy('%s'))rr�rrvr�rZnew_policy_object_dictrc)rKrir�r�r�r�rPrPrQ�	addPolicy/s


zFirewallDConfig.addPolicycCstjd|�dS)Nzconfig.PolicyAdded('%s'))rrv)rKrirPrPrQr�>szFirewallDConfig.PolicyAddedcCstjd�|jS)z#list helpers objects paths
        zconfig.listHelpers())rrvrZ)rKr�rPrPrQ�listHelpersGs
zFirewallDConfig.listHelperscCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget helper names
        zconfig.getHelperNames())rrvrZr�r�r�rC)rKr�rZr�rPrPrQ�getHelperNamesOs

zFirewallDConfig.getHelperNamescCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z.object path of helper with given name
        zconfig.getHelperByName('%s')N)
rr�rrvrZr�r�rrZINVALID_HELPER)rKrhr�r�rPrPrQ�getHelperByNameZs
zFirewallDConfig.getHelperByNamecCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z0add helper with given name and settings
        zconfig.addHelper('%s'))rr�rrvr�rZ
new_helperrb)rKrhr�r�r�r�rPrPrQ�	addHelpergs


zFirewallDConfig.addHelpercCst|t�}tjd|�dS)Nzconfig.HelperAdded('%s'))rr�rrv)rKrhrPrPrQr�vs
zFirewallDConfig.HelperAddedcCstjd�|jj�j�S)Nzconfig.direct.getSettings())rrvr�
get_directr�)rKr�rPrPrQr�s
zFirewallDConfig.getSettingscCs<tjd�t|�}|jj�j|�|jj�j�|j�dS)Nzconfig.direct.update())rrvrrrr�r�r�)rKr�r�rPrPrQrr�s

zFirewallDConfig.updatecCstjd�dS)Nzconfig.direct.Updated())rrv)rKrPrPrQr��szFirewallDConfig.UpdatedZssscCs�t|�}t|�}t|�}tjd|||f�|j|�t|||f�}t|j��}||dkrrttj	d|||f��|dj
|�|j|�dS)Nz(config.direct.addChain('%s', '%s', '%s')rz chain '%s' already is in '%s:%s')rrrvr�rrzr�rrr�r�rr)rK�ipv�table�chainr��idxr�rPrPrQ�addChain�s
zFirewallDConfig.addChaincCs�t|�}t|�}t|�}tjd|||f�|j|�t|||f�}t|j��}||dkrrttj	d|||f��|dj
|�|j|�dS)Nz+config.direct.removeChain('%s', '%s', '%s')rzchain '%s' is not in '%s:%s')rrrvr�rrzr�rrr�rqrr)rKrrrr�rr�rPrPrQ�removeChain�s

zFirewallDConfig.removeChaincCsJt|�}t|�}t|�}tjd|||f�t|||f�}||j�dkS)Nz*config.direct.queryChain('%s', '%s', '%s')r)rrrvrr�)rKrrrr�rrPrPrQ�
queryChain�szFirewallDConfig.queryChaincCsft|�}t|�}tjd||f�g}x:|j�dD]*}|d|kr4|d|kr4|j|d�q4W|S)Nz#config.direct.getChains('%s', '%s')rrr�)rrrvr�r�)rKrrr�r�rrPrPrQ�	getChains�szFirewallDConfig.getChainsrsza(sss)cCstjd�|j�dS)Nzconfig.direct.getAllChains()r)rrvr�)rKr�rPrPrQ�getAllChains�s
zFirewallDConfig.getAllChainsZsssiasc	Cs�t|�}t|�}t|�}t|�}t|�}tjd||||dj|�f�|j|�|||||f}t|j��}||dkr�ttj	d||||f��|dj
|�|jt|��dS)Nz1config.direct.addRule('%s', '%s', '%s', %d, '%s')z','rz"rule '%s' already is in '%s:%s:%s')
rrrvrr�rzr�rrr�r�rrr)	rKrrr�priorityrLr�rr�rPrPrQ�addRule�s 
zFirewallDConfig.addRulec	Cs�t|�}t|�}t|�}t|�}t|�}tjd||||dj|�f�|j|�|||||f}t|j��}||dkr�ttj	d||||f��|dj
|�|jt|��dS)Nz4config.direct.removeRule('%s', '%s', '%s', %d, '%s')z','rzrule '%s' is not in '%s:%s:%s')
rrrvrr�rzr�rrr�rqrrr)	rKrrrrrLr�rr�rPrPrQ�
removeRule�s 
zFirewallDConfig.removeRulecCsdt|�}t|�}t|�}t|�}t|�}tjd||||dj|�f�|||||f}||j�dkS)Nz3config.direct.queryRule('%s', '%s', '%s', %d, '%s')z','r)rrrvrr�)rKrrrrrLr�rrPrPrQ�	queryRuleszFirewallDConfig.queryRulecCs�t|�}t|�}t|�}tjd|||f�|j|�t|j��}xF|ddd�D]2}|||f|d|d|dfkrT|dj|�qTW|jt|��dS)Nz+config.direct.removeRules('%s', '%s', '%s')rrr�)	rrrvr�rzr�rqrrr)rKrrrr�r�ZrulerPrPrQ�removeRuless
 zFirewallDConfig.removeRulesza(ias)cCs�t|�}t|�}t|�}tjd|||f�g}xN|j�dD]>}|d|kr>|d|kr>|d|kr>|j|d|df�q>W|S)Nz(config.direct.getRules('%s', '%s', '%s')rrr�r�r)rrrvr�r�)rKrrrr�r�rrPrPrQ�getRules)s$zFirewallDConfig.getRulesz	a(sssias)cCstjd�|j�dS)Nzconfig.direct.getAllRules()r)rrvr�)rKr�rPrPrQ�getAllRules8s
zFirewallDConfig.getAllRulesZsascCs�t|�}t|�}tjd|dj|�f�|j|�||f}t|j��}||dkrfttj	d||f��|dj
|�|j|�dS)Nz(config.direct.addPassthrough('%s', '%s')z','r�zpassthrough '%s', '%s')rrrvrr�rzr�rrr�r�rr)rKrrLr�rr�rPrPrQ�addPassthroughAs
zFirewallDConfig.addPassthroughcCs�t|�}t|�}tjd|dj|�f�|j|�||f}t|j��}||dkrfttj	d||f��|dj
|�|j|�dS)Nz+config.direct.removePassthrough('%s', '%s')z','r�zpassthrough '%s', '%s')rrrvrr�rzr�rrr�rqrr)rKrrLr�rr�rPrPrQ�removePassthroughSs
z!FirewallDConfig.removePassthroughcCs@t|�}t|�}tjd|dj|�f�||f}||j�dkS)Nz*config.direct.queryPassthrough('%s', '%s')z','r�)rrrvrr�)rKrrLr�rrPrPrQ�queryPassthroughdsz FirewallDConfig.queryPassthroughZaascCsNt|�}tjd|�g}x.|j�dD]}|d|kr(|j|d�q(W|S)Nz#config.direct.getPassthroughs('%s')r�rr)rrrvr�r�)rKrr�r�rrPrPrQ�getPassthroughsoszFirewallDConfig.getPassthroughsza(sas)cCstjd�|j�dS)Nz"config.direct.getAllPassthroughs()r�)rrvr�)rKr�rPrPrQ�getAllPassthroughs{s
z"FirewallDConfig.getAllPassthroughs)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)��__name__�
__module__�__qualname__�__doc__Z
persistentrrIZPK_ACTION_CONFIGZdefault_polkit_auth_requiredrr.r1rjror2r_r�rr`r�r�rar�r�rcr�r�r^r�r�rbr�r�rr�r�r�r	ZPROPERTIES_IFACEr�ru�slipZpolkitZrequire_authr�rf�signalr|ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr�r�rZDBUS_SIGNATUREr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rJr�r�r�rr�r�r�r�r�rr�r�r�r�r�r�r�r�r�r�r�rrrr	r�r
rrr
r�rrrrrr�r�rr�rrr�rrrrrrrrr r!r"r#r$r%r&r'�
__classcell__rPrP)rOrQr>sv.				D!D	





	

	

	

	




	

	

	

	r):Z
gi.repositoryr�sys�modulesrArIZdbus.serviceZ	slip.dbusr,Zslip.dbus.serviceZfirewallrZfirewall.core.baserZfirewall.core.watcherrZfirewall.core.loggerrZfirewall.server.decoratorsrrr	Zfirewall.server.config_icmptyper
Zfirewall.server.config_servicerZfirewall.server.config_zonerZfirewall.server.config_policyr
Zfirewall.server.config_ipsetrZfirewall.server.config_helperrZfirewall.core.io.icmptyperZfirewall.core.io.ipsetrZfirewall.core.io.helperrZ#firewall.core.io.lockdown_whitelistrZfirewall.core.io.directrZfirewall.dbus_utilsrrrrrrrrZfirewall.errorsrrfZObjectrrPrPrPrQ�<module>s6
$server/__pycache__/config_helper.cpython-36.pyc000064400000030613150351351720015521 0ustar003

��g�D�@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZddlmZmZmZdd	l	mZdd
lmZGdd�dejjj�ZdS)
�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�Helper)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�errors)�
FirewallErrorcseZdZdZdZejjZe	�fdd��Z
edd��Zedd��Z
ed	d
��Zeejddd
�edTdd���Zeejddd
�edUdd���Zejjjejj�eejdd�edVdd����Zejjejdd�dd��Zejjjejj�eejdd�edW�fdd�	���Zeejjejd�edXd d!���Z eejjejd�edYd"d#���Z!eejj�edZd$d%���Z"ejjejjdd�ed&d'���Z#eejj�ed[d(d)���Z$ejjejjdd�ed*d+���Z%eejjdd�ed\d,d-���Z&ejjejjdd�ed.d/���Z'eejjdd�ed]d0d1���Z(eejjdd�ed^d2d3���Z)eejjdd�ed_d4d5���Z*eejjdd�ed`d6d7���Z+eejjdd�edad8d9���Z,eejjdd�edbd:d;���Z-eejjdd�edcd<d=���Z.eejjdd�eddd>d?���Z/eejjdd@d
�ededAdB���Z0eejjdd�edfdCdD���Z1eejjdd�edgdEdF���Z2eejjdd@d
�edhdGdH���Z3eejjdId�edidJdK���Z4eejjdId�edjdLdM���Z5eejjdd�edkdNdO���Z6eejjdd�edldPdQ���Z7eejjdd@d
�edmdRdS���Z8�Z9S)n�FirewallDConfigHelperzFirewallD main classTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.helper.%d)
�superr�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_HELPER)�selfrZconf�helperr�args�kwargs)�	__class__��#/usr/lib/python3.6/config_helper.pyr8s

zFirewallDConfigHelper.__init__cCsdS)Nr)rrrr �__del__EszFirewallDConfigHelper.__del__cCs|j�dS)N)Zremove_from_connection)rrrr �
unregisterIsz FirewallDConfigHelper.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrr#r$rZBooleanr%r&�
exceptions�
DBusException)r�
property_namerrr �
_get_propertyQsz#FirewallDConfigHelper._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrrr(r)r+)r�interface_namer*�senderrrr �Getbs


zFirewallDConfigHelper.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existr#r$rr%r&Zsv)�	signature)r#r$rr%r&)rr/rr0rrrrr(r)r+Z
Dictionary)rr1r2�ret�xrrr �GetAllss

zFirewallDConfigHelper.GetAllZssv)r-cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr/rr0rr�accessCheckrrrr(r))rr1r*Z	new_valuer2rrr �Set�s



zFirewallDConfigHelper.Setzsa{sv}as)r5cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr/rr0r)rr1Zchanged_propertiesZinvalidated_propertiesrrr �PropertiesChanged�s


z'FirewallDConfigHelper.PropertiesChanged)r.cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rrr�
IntrospectrrZget_busrrrr)rr2�data)rrr r<�s

z FirewallDConfigHelper.IntrospectcCstjd|j�|jj|j�S)z get settings for helper
        z%s.getSettings())rr0rrZget_helper_configr)rr2rrr �getSettings�sz!FirewallDConfigHelper.getSettingscCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)z#update settings for helper
        z%s.update('...')N)rrr0rrr9rZset_helper_configr�Updatedr#)r�settingsr2rrr �update�s
zFirewallDConfigHelper.updatecCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z1load default settings for builtin helper
        z%s.loadDefaults()N)
rr0rrr9rZload_helper_defaultsrr?r#)rr2rrr �loadDefaults�sz"FirewallDConfigHelper.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr0r)rr#rrr r?�szFirewallDConfigHelper.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove helper
        z%s.removeHelper()N)	rr0rrr9rZ
remove_helperrZremoveHelper)rr2rrr �remove�szFirewallDConfigHelper.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr0r)rr#rrr �Removed�szFirewallDConfigHelper.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename helper
        z%s.rename('%s')N)rr/rr0rrr9rZ
rename_helperr�Renamed)rr#r2rrr �rename�s

zFirewallDConfigHelper.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr0r)rr#rrr rE�szFirewallDConfigHelper.RenamedcCstjd|j�|j�dS)Nz%s.getVersion()r)rr0rr>)rr2rrr �
getVersion�sz FirewallDConfigHelper.getVersioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setVersion('%s')r)
rr/rr0rrr9�listr>rA)r�versionr2r@rrr �
setVersions
z FirewallDConfigHelper.setVersioncCstjd|j�|j�dS)Nz
%s.getShort()r)rr0rr>)rr2rrr �getShortszFirewallDConfigHelper.getShortcCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setShort('%s')r)
rr/rr0rrr9rHr>rA)rZshortr2r@rrr �setShorts
zFirewallDConfigHelper.setShortcCstjd|j�|j�dS)Nz%s.getDescription()�)rr0rr>)rr2rrr �getDescription$sz$FirewallDConfigHelper.getDescriptioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setDescription('%s')rM)
rr/rr0rrr9rHr>rA)r�descriptionr2r@rrr �setDescription+s

z$FirewallDConfigHelper.setDescriptioncCs.tjd|j�|jj|�t|j��}|dS)Nz%s.getFamily()�)rr0rrr9rHr>)rr2r@rrr �	getFamily9szFirewallDConfigHelper.getFamilycCsdt|t�}tjd|j|�|jj|�t|j��}|d|krNt	t
jd|��||d<|j|�dS)Nz%s.setFamily('%s')rQz'%s')
rr/rr0rrr9rHr>r
r�ALREADY_ENABLEDrA)r�ipvr2r@rrr �	setFamilyBs
zFirewallDConfigHelper.setFamily�bcCs.t|t�}tjd|j|�|j�}|d|kS)Nz%s.queryFamily('%s')rQ)rr/rr0rr>)rrTr2r@rrr �queryFamilyOs
z!FirewallDConfigHelper.queryFamilycCs.tjd|j�|jj|�t|j��}|dS)Nz%s.getModule()�)rr0rrr9rHr>)rr2r@rrr �	getModuleZszFirewallDConfigHelper.getModulecCsdt|t�}tjd|j|�|jj|�t|j��}|d|krNt	t
jd|��||d<|j|�dS)Nz%s.setModule('%s')rXz'%s')
rr/rr0rrr9rHr>r
rrSrA)r�moduler2r@rrr �	setModulecs
zFirewallDConfigHelper.setModulecCs.t|t�}tjd|j|�|j�}|d|kS)Nz%s.queryModule('%s')rX)rr/rr0rr>)rrZr2r@rrr �queryModuleps
z!FirewallDConfigHelper.queryModuleza(ss)cCstjd|j�|j�dS)Nz
%s.getPorts()�)rr0rr>)rr2rrr �getPorts{szFirewallDConfigHelper.getPortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setPorts('[%s]')�,css"|]}d|d|dfVqdS)z('%s, '%s')rrNr)�.0�portrrr �	<genexpr>�sz1FirewallDConfigHelper.setPorts.<locals>.<genexpr>r])
rrH�
isinstance�append�tuplerr0r�joinrr9r>rA)rZportsr2Z_portsrar@rrr �setPorts�s

zFirewallDConfigHelper.setPortscCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.addPort('%s', '%s')r]z%s:%s)rr/rr0rrr9rHr>r
rrSrdrA)rra�protocolr2r@rrr �addPort�s

zFirewallDConfigHelper.addPortcCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.removePort('%s', '%s')r]z%s:%s)rr/rr0rrr9rHr>r
rZNOT_ENABLEDrCrA)rrarhr2r@rrr �
removePort�s

z FirewallDConfigHelper.removePortcCs:t|t�}t|t�}tjd|j||�||f|j�dkS)Nz%s.queryPort('%s', '%s')r])rr/rr0rr>)rrarhr2rrr �	queryPort�s


zFirewallDConfigHelper.queryPort)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N):�__name__�
__module__�__qualname__�__doc__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredr	rr
r!r"r+rZPROPERTIES_IFACEr3r8�slipZpolkitZrequire_authr:�service�signalr;ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr<rrZDBUS_SIGNATUREr>rArBr?rCrDrFrErGrJrKrLrNrPrRrUrWrYr[r\r^rgrirjrk�
__classcell__rr)rr r0s�
		

	




r)Z
gi.repositoryr�sys�modulesrZdbus.serviceZ	slip.dbusrpZslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.io.helperrZfirewall.core.loggerrZfirewall.server.decoratorsr	r
rrZfirewall.errorsr
rqZObjectrrrrr �<module>s
server/__pycache__/server.cpython-36.pyc000064400000004547150351351720014232 0ustar003

��g��@s�dgZddlZddlZddlmZmZeejd<ddlZddlZddl	Zddl
Zddlm
Z
ddlmZddlmZdd	�Zd
d�Zdd
d�ZdS)�
run_server�N)�GObject�GLibZgobject)�config)�log)�	FirewallDcCs|j�dS)NT)�reload)�service�r
�/usr/lib/python3.6/server.py�sighup4srcCs|j�dS)N)�quit)�mainloopr
r
r�sigterm8srFcsxd}|rFddlm�ddl��j��j�j�d�����fdd��y�tjjj	dd�tj
�}tjjt
jj|d	�}t|t
jj�}tj�}tjjj|�|r�tj���ttd
�r�tj}ntj}|tjtjt|�|tjtjt|�|j�Wnvt k
�rt!j"d�YnXt#k
�r,t!j$d�Yn:t%k
�rd}zt!j$d
|j&j't(|��WYdd}~XnX|�rt|j)�dS)zI Main function for firewall server. Handles D-Bus and GLib mainloop.
    Nr)�pformat�
csr�j�t�j�dkrbtd�tdt�j��x(�jD]}tt|�d�t�|��q8Wtd�tj���dS)NrzP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
zGARBAGE OBJECTS (%d):
z
  zP
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
)Zcollect�lenZgarbage�print�typer�timeout_add_seconds)�x)�gc�
gc_collect�
gc_timeoutrr
rrLszrun_server.<locals>.gc_collectT)Zset_as_default)�bus�unix_signal_addz
Stopping..z Raising SystemExit in run_serverzException %s: %s)*�pprintrr�enableZ	set_debugZ
DEBUG_LEAK�dbusrZglibZ
DBusGMainLoopZ	SystemBusr	ZBusNamerZDBUS_INTERFACErZ	DBUS_PATHrZMainLoop�slipZset_mainloopr�hasattrrZunix_signal_add_fullZ
PRIORITY_HIGH�signal�SIGHUPr�SIGTERMrZrun�KeyboardInterruptrZdebug1�
SystemExit�error�	Exception�	__class__�__name__�str�stop)Zdebug_gcr	r�namerr�er
)rrrrrrAsB



()F)�__all__�sysr!Z
gi.repositoryrr�modulesrZdbus.serviceZdbus.mainloop.glibZ	slip.dbusrZfirewallrZfirewall.core.loggerrZfirewall.server.firewalldrrrrr
r
r
r�<module>s
	server/__pycache__/server.cpython-36.opt-1.pyc000064400000004547150351351720015171 0ustar003

��g��@s�dgZddlZddlZddlmZmZeejd<ddlZddlZddl	Zddl
Zddlm
Z
ddlmZddlmZdd	�Zd
d�Zdd
d�ZdS)�
run_server�N)�GObject�GLibZgobject)�config)�log)�	FirewallDcCs|j�dS)NT)�reload)�service�r
�/usr/lib/python3.6/server.py�sighup4srcCs|j�dS)N)�quit)�mainloopr
r
r�sigterm8srFcsxd}|rFddlm�ddl��j��j�j�d�����fdd��y�tjjj	dd�tj
�}tjjt
jj|d	�}t|t
jj�}tj�}tjjj|�|r�tj���ttd
�r�tj}ntj}|tjtjt|�|tjtjt|�|j�Wnvt k
�rt!j"d�YnXt#k
�r,t!j$d�Yn:t%k
�rd}zt!j$d
|j&j't(|��WYdd}~XnX|�rt|j)�dS)zI Main function for firewall server. Handles D-Bus and GLib mainloop.
    Nr)�pformat�
csr�j�t�j�dkrbtd�tdt�j��x(�jD]}tt|�d�t�|��q8Wtd�tj���dS)NrzP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
zGARBAGE OBJECTS (%d):
z
  zP
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
)Zcollect�lenZgarbage�print�typer�timeout_add_seconds)�x)�gc�
gc_collect�
gc_timeoutrr
rrLszrun_server.<locals>.gc_collectT)Zset_as_default)�bus�unix_signal_addz
Stopping..z Raising SystemExit in run_serverzException %s: %s)*�pprintrr�enableZ	set_debugZ
DEBUG_LEAK�dbusrZglibZ
DBusGMainLoopZ	SystemBusr	ZBusNamerZDBUS_INTERFACErZ	DBUS_PATHrZMainLoop�slipZset_mainloopr�hasattrrZunix_signal_add_fullZ
PRIORITY_HIGH�signal�SIGHUPr�SIGTERMrZrun�KeyboardInterruptrZdebug1�
SystemExit�error�	Exception�	__class__�__name__�str�stop)Zdebug_gcr	r�namerr�er
)rrrrrrAsB



()F)�__all__�sysr!Z
gi.repositoryrr�modulesrZdbus.serviceZdbus.mainloop.glibZ	slip.dbusrZfirewallrZfirewall.core.loggerrZfirewall.server.firewalldrrrrr
r
r
r�<module>s
	server/__pycache__/config.cpython-36.pyc000064400000127767150351351720014203 0ustar003

��g��@sdddlmZddlZeejd<ddlZddlZddlZddlZddl	Zddl
mZddlm
Z
ddlmZddlmZddlmZmZmZdd	lmZdd
lmZddlmZddlmZdd
lmZddl m!Z!ddl"m#Z#ddl$m%Z%ddl&m'Z'ddl(m)Z)ddl*m+Z+ddl,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3ddl
m4Z4ddl5m6Z6Gdd�dejj7j8�Z9dS)�)�GObjectNZgobject)�config)�DEFAULT_ZONE_TARGET)�Watcher)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�FirewallDConfigIcmpType)�FirewallDConfigService)�FirewallDConfigZone)�FirewallDConfigPolicy)�FirewallDConfigIPSet)�FirewallDConfigHelper)�IcmpType)�IPSet)�Helper)�LockdownWhitelist)�Direct)�dbus_to_python�command_of_sender�context_of_sender�
uid_of_sender�user_of_uid�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�errors)�
FirewallErrorcs@eZdZdZdZejjZe	�fdd��Z
e	dd��Ze	dd��Ze	d	d
��Z
e	dd��Ze	d
d��Ze	dd��Ze	dd��Ze	dd��Ze	dd��Ze	dd��Ze	dd��Ze	dd��Ze	dd��Ze	dd ��Ze	d!d"��Ze	d#d$��Ze	d%d&��Ze	d'd(��Ze	d)d*��Ze	d+d,��Ze	d-d.��Ze	d/d0��Z e!d1d2��Z"e!d3d4��Z#e!d5d6��Z$e%ej&d7d8d9�e!d�d;d<���Z'e%ej&d=d>d9�e!d�d?d@���Z(e)jj*j+ejj�e%ej&dAdB�e!d�dCdD����Z,ej-j.ej&dEdF�dGdH��Z/e)jj*j+ejj0�e%ej1d=dI�e!d�fdJdK�	���Z2e%ejj3e4j5dI�e!d�dLdM���Z6e%ejj3e4j5dB�e!d�dNdO���Z7ej-j.ejj3�e!dPdQ���Z8e%ejj3d=dB�e!d�dRdS���Z9e%ejj3d=dB�e!d�dTdU���Z:e%ejj3d=dVd9�e!d�dWdX���Z;e%ejj3dYdI�e!d�dZd[���Z<e%ejj3d=dB�e!d�d\d]���Z=e%ejj3d=dB�e!d�d^d_���Z>e%ejj3d=dVd9�e!d�d`da���Z?e%ejj3dYdI�e!d�dbdc���Z@e%ejj3d=dB�e!d�ddde���ZAe%ejj3d=dB�e!d�dfdg���ZBe%ejj3d=dVd9�e!d�dhdi���ZCe%ejj3dYdI�e!d�djdk���ZDe%ejj3dldB�e!�ddmdn���ZEe%ejj3dldB�e!�ddodp���ZFe%ejj3dldVd9�e!�ddqdr���ZGe%ejj3dsdI�e!�ddtdu���ZHe%ejjIdvdI�e!�ddwdx���ZJe%ejjIdYdI�e!�ddydz���ZKe%ejjId=d{d9�e!�dd|d}���ZLe%ejjId=eMj5d{d9�e!�dd~d���ZNej-j.ejjId=dF�e!d�d����ZOe%ejjIdvdI�e!�dd�d����ZPe%ejjIdYdI�e!�d	d�d����ZQe%ejjId=d{d9�e!�d
d�d����ZRe%ejjId=eSj5d{d9�e!�dd�d����ZTej-j.ejjId=dF�e!d�d����ZUe%ejjIdvdI�e!�dd�d����ZVe%ejjIdYdI�e!�d
d�d����ZWe%ejjId=d{d9�e!�dd�d����ZXe%ejjId�d{d9�e!�dd�d����ZYe%ejjId�d{d9�e!�dd�d����ZZej-j.ejjId=dF�e!d�d����Z[e%ejjIdvdI�e!�dd�d����Z\e%ejjIdYdI�e!�dd�d����Z]e%ejjId=d{d9�e!�dd�d����Z^e%ejjId=d=d9�e!�dd�d����Z_e%ejjId=d=d9�e!�dd�d����Z`e%ejjId�d{d9�e!�dd�d����Zae%ejjId�d{d9�e!�dd�d����Zbej-j.ejjId=dF�e!d�d����Zce%ejjIdvdI�e!�dd�d����Zde%ejjIdYdI�e!�dd�d����Zee%ejjId=d{d9�e!�dd�d����Zfe%ejjId�d{d9�e!�dd�d����Zgej-j.ejjId=dF�e!d�d����Zhe%ejjIdvdI�e!�dd�d����Zie%ejjIdYdI�e!�dd�d����Zje%ejjId=d{d9�e!�dd�d����Zke%ejjId=elj5d{d9�e!�dd�d����Zmej-j.ejjId=dF�e!d�d����Zne%ejjoepj5dI�e!�d d�d����Zqe%ejjoepj5dB�e!�d!d�d„��Zrej-j.ejjo�e!d�dĄ��Zse%ejjod�dB�e!�d"d�dDŽ��Zte%ejjod�dB�e!�d#d�dɄ��Zue%ejjod�dVd9�e!�d$d�d˄��Zve%ejjod7dYd9�e!�d%d�d̈́��Zwe%ejjod�d�d9�e!�d&d�dф��Zxe%ejjod�dB�e!�d'd�dԄ��Zye%ejjod�dB�e!�d(d�dք��Zze%ejjod�dVd9�e!�d)d�d؄��Z{e%ejjod�dB�e!�d*d�dڄ��Z|e%ejjod�d�d9�e!�d+d�d݄��Z}e%ejjod�d�d9�e!�d,d�d���Z~e%ejjod�dB�e!�d-d�d���Ze%ejjod�dB�e!�d.d�d���Z�e%ejjod�dVd9�e!�d/d�d���Z�e%ejjod=d�d9�e!�d0d�d���Z�e%ejjod�dI�e!�d1d�d���Z��Z�S(2�FirewallDConfigzFirewallD main classTcs�tt|�j||�||_|d|_|d|_|j�t|jd�|_	|j	j
tj�|j	j
tj�|j	j
tj
�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�|j	j
tj�tjjtj��r>xBttjtj��D].}dtj|f}tjj|��r|j	j
|��qW|j	jtj�|j	jtj�|j	jtj�t |tj!j"ddddddddddddd��dS)Nr��z%s/%sZ	readwrite)�
CleanupOnExit�CleanupModulesOnExit�
IPv6_rpfilter�Lockdown�MinimalMark�IndividualCalls�	LogDenied�AutomaticHelpers�FirewallBackend�FlushAllOnReload�RFC3964_IPv4�AllowZoneDrifting)#�superr�__init__r�busname�path�
_init_varsr�
watch_updater�watcher�
add_watch_dir�FIREWALLD_IPSETS�ETC_FIREWALLD_IPSETS�FIREWALLD_ICMPTYPES�ETC_FIREWALLD_ICMPTYPES�FIREWALLD_HELPERS�ETC_FIREWALLD_HELPERS�FIREWALLD_SERVICES�ETC_FIREWALLD_SERVICES�FIREWALLD_ZONES�ETC_FIREWALLD_ZONES�FIREWALLD_POLICIES�ETC_FIREWALLD_POLICIES�os�exists�sorted�listdir�isdirZadd_watch_file�LOCKDOWN_WHITELIST�FIREWALLD_DIRECT�FIREWALLD_CONFr�dbus�DBUS_INTERFACE_CONFIG)�selfZconf�args�kwargs�filenamer0)�	__class__��/usr/lib/python3.6/config.pyr.FsP

zFirewallDConfig.__init__cCs2g|_d|_g|_d|_g|_d|_g|_d|_g|_d|_	g|_
d|_x$|jj
�D]}|j|jj|��qTWx$|jj�D]}|j|jj|��qzWx$|jj�D]}|j|jj|��q�Wx$|jj�D]}|j|jj|��q�Wx$|jj�D]}|j|jj|��q�Wx&|jj�D]}|j|jj|���qWdS)Nr)�ipsets�	ipset_idx�	icmptypes�icmptype_idx�services�service_idx�zones�zone_idx�helpers�
helper_idx�policy_objects�policy_object_idxrZ
get_ipsets�	_addIPSetZ	get_ipsetZ
get_icmptypes�_addIcmpTypeZget_icmptypeZget_services�_addServiceZget_serviceZ	get_zones�_addZoneZget_zoneZget_helpers�
_addHelperZ
get_helperZget_policy_objects�
_addPolicyZget_policy_object)rK�ipset�icmptype�service�zone�helper�policyrPrPrQr1ts0zFirewallDConfig._init_varscCsdS)NrP)rKrPrPrQ�__del__�szFirewallDConfig.__del__cCs�x&t|j�dkr&|jj�}|j�~qWx&t|j�dkrN|jj�}|j�~q*Wx&t|j�dkrv|jj�}|j�~qRWx&t|j�dkr�|jj�}|j�~qzWx&t|j�dkr�|jj�}|j�~q�Wx&t|j�dkr�|jj�}|j�~q�W|j	�dS)Nr)
�lenrR�pop�
unregisterrTrVrXrZr\r1)rK�itemrPrPrQ�reload�s2





zFirewallDConfig.reloadc	CsJ|tjkr�|jtjj�}tjdtj�y|jj�Wn2tk
rf}ztj	d||f�dSd}~XnX|jtjj�j
�}x2t|j��D]"}||kr�||||kr�||=q�Wt
|�dkr�|jtjj|g�dS|jtj�s�|jtj�o�|jd��r�y|jj|�\}}Wn4tk
�r<}ztj	d||f�dSd}~XnX|dk�rT|j|�n*|dk�rj|j|�n|dk�rF|j|��n�|jtj��s�|jtj��r8|jd��r8y|jj|�\}}Wn4tk
�r�}ztj	d	||f�dSd}~XnX|dk�r
|j|�n*|dk�r |j|�n|dk�rF|j|��n|jtj��sT|jtj��rr|jd��r�y|jj|�\}}Wn4tk
�r�}ztj	d
||f�dSd}~XnX|dk�r�|j |�n*|dk�r�|j!|�n|dk�rn|j"|�n�|jtj��rF|j#tjd�j$d�}t
|�d
k�s&d|k�r*dSt%j&j'|��rT|j(j)|��sn|j(j*|�n|j(j)|��rF|j(j+|��n�|jtj,��s�|jtj-��r(|jd��r(y|jj.|�\}}Wn4tk
�r�}ztj	d||f�dSd}~XnX|dk�r�|j/|�n*|dk�r|j0|�n|dk�rF|j1|��n|jtj2��sD|jtj3��r�|jd��r�y|jj4|�\}}Wn4tk
�r�}ztj	d||f�dSd}~XnX|dk�r�|j5|�n*|dk�r�|j6|�n|dk�rF|j7|��nh|tj8k�r:y|jj9�Wn4tk
�r,}ztj	d||f�dSd}~XnX|j:��n|tj;k�r�y|jj<�Wn4tk
�r�}ztj	d||f�dSd}~XnX|j=�n�|jtj>��s�|jtj?��rF|jd��rFy|jj@|�\}}Wn4tk
�r}ztj	d||f�dSd}~XnX|dk�r|jA|�n*|dk�r2|jB|�n|dk�rF|jC|�dS)Nz,config: Reloading firewalld config file '%s'z+Failed to load firewalld.conf file '%s': %srz.xmlz%Failed to load icmptype file '%s': %s�new�remove�updatez$Failed to load service file '%s': %sz!Failed to load zone file '%s': %s��/rz"Failed to load ipset file '%s': %sz#Failed to load helper file '%s': %sz/Failed to load lockdown whitelist file '%s': %sz)Failed to load direct rules file '%s': %sz#Failed to load policy file '%s': %s)DrrH�GetAllrIrJr�debug1Zupdate_firewalld_conf�	Exception�error�copy�list�keysrk�PropertiesChanged�
startswithr7r8�endswithZupdate_icmptype_from_pathr_�removeIcmpType�_updateIcmpTyper;r<Zupdate_service_from_pathr`�
removeService�_updateServicer=r>Zupdate_zone_from_pathra�
removeZone�_updateZone�replace�striprAr0rEr3Z	has_watchr4Zremove_watchr5r6Zupdate_ipset_from_pathr^�removeIPSet�_updateIPSetr9r:Zupdate_helper_from_pathrb�removeHelper�
_updateHelperrFZupdate_lockdown_whitelist�LockdownWhitelistUpdatedrGZ
update_direct�Updatedr?r@Zupdate_policy_object_from_pathrc�removePolicy�
_updatePolicy)	rK�nameZ	old_props�msgZprops�keyZwhat�obj�_namerPrPrQr2�s
























zFirewallDConfig.watch_updaterc	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
r
rrUr/rIZDBUS_PATH_CONFIG_ICMPTYPErT�append�
IcmpTypeAddedr�)rKr��config_icmptyperPrPrQr_AszFirewallDConfig._addIcmpTypecCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)rTr�r�r0rNr�)rKr�rerPrPrQr�MszFirewallDConfig._updateIcmpTypecCs�d}xT|jD]J}|j�}|j||kr||j|j�|jj|j|�|_|j|jj�qWx\|jD]R}|j�}d|krb|j|dkrb|dj|j�|jj	|j|�|_|j|jj�qbWx:|j
D]0}|j|kr�|j|j�|j�|j
j|�~q�WdS)N�Zicmp_blocks)
rX�getSettingsr�rqr�set_zone_configr�r�r\�set_policy_object_config_dictrT�Removedrm)rKr��indexrg�settingsrirerPrPrQrVs&
zFirewallDConfig.removeIcmpTypec	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
rrrWr/rIZDBUS_PATH_CONFIG_SERVICErVr��ServiceAddedr�)rKr��config_servicerPrPrQr`pszFirewallDConfig._addServicecCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)rVr�r�r0rNr�)rKr�rfrPrPrQr�{szFirewallDConfig._updateServicecCs�d}xT|jD]J}|j�}|j||kr||j|j�|jj|j|�|_|j|jj�qWx\|jD]R}|j�}d|krb|j|dkrb|dj|j�|jj	|j|�|_|j|jj�qbWx:|j
D]0}|j|kr�|j|j�|j�|j
j|�~q�WdS)Nr rV)
rXr�r�rqrr�r�r�r\r�rVr�rm)rKr�r�rgr�rirfrPrPrQr��s&
zFirewallDConfig.removeServicec	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
rrrYr/rIZDBUS_PATH_CONFIG_ZONErXr��	ZoneAddedr�)rKr��config_zonerPrPrQra�szFirewallDConfig._addZonecCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)rXr�r�r0rNr�)rKr�rgrPrPrQr��s
zFirewallDConfig._updateZonecCs@x:|jD]0}|j|kr|j|j�|j�|jj|�~qWdS)N)rXr�r�r�rmrq)rKr�rgrPrPrQr��s
zFirewallDConfig.removeZonec	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
r
rr]r/rIZDBUS_PATH_CONFIG_POLICYr\r��PolicyAddedr�)rKr��
config_policyrPrPrQrc�szFirewallDConfig._addPolicycCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)r\r�r�r0rNr�)rKr�rirPrPrQr��s
zFirewallDConfig._updatePolicycCs@x:|jD]0}|j|kr|j|j�|j�|jj|�~qWdS)N)r\r�r�r�rmrq)rKr�rirPrPrQr��s
zFirewallDConfig.removePolicyc	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
rrrSr/rIZDBUS_PATH_CONFIG_IPSETrRr��
IPSetAddedr�)rKr��config_ipsetrPrPrQr^�szFirewallDConfig._addIPSetcCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)rRr�r�r0rNr�)rKr�rdrPrPrQr��s
zFirewallDConfig._updateIPSetcCs@x:|jD]0}|j|kr|j|j�|j�|jj|�~qWdS)N)rRr�r�r�rmrq)rKr�rdrPrPrQr��s
zFirewallDConfig.removeIPSetc	CsPt||j||j|jdtjj|jf�}|jj|�|jd7_|j|j	�|S)Nz%s/%dr)
rrr[r/rIZDBUS_PATH_CONFIG_HELPERrZr��HelperAddedr�)rKr��
config_helperrPrPrQrb�szFirewallDConfig._addHelpercCsPxJ|jD]@}|jj|jkr|jj|jkr|jj|jkr||_|j|j�qWdS)N)rZr�r�r0rNr�)rKr�rhrPrPrQr��s
zFirewallDConfig._updateHelpercCs@x:|jD]0}|j|kr|j|j�|j�|jj|�~qWdS)N)rZr�r�r�rmrq)rKr�rhrPrPrQr�s
zFirewallDConfig.removeHelpercCs�|jj�r�|dkr tjd�dStj�}t||�}|jjd|�rDdSt||�}|jjd|�r`dSt	|�}|jjd|�rzdSt
||�}|jjd|�r�dSttj
d��dS)Nz&Lockdown not possible, sender not set.�context�uid�user�commandzlockdown is enabled)rZlockdown_enabledrrxrIZ	SystemBusrZaccess_checkrrrrrZ
ACCESS_DENIED)rK�senderZbusr�r�r�r�rPrPrQ�accessChecks$




zFirewallDConfig.accessCheckcCsF|dkrtjjd|��|jj�j|�}|dkrH|dkr>tj}tj|�S|dkrr|dkr`tj}nt	|�}tj
|�S|dkr�|dkr�tjr�dnd}tj|�S|dkr�|dkr�tjr�dnd}tj|�S|dk�r�|dk�r�tj
�r�dnd}tj|�S|dk�r|dk�rtj�rdnd}tj|�S|dk�rL|dk�rBtj�r>dnd}tj|�S|dk�rp|dk�rftj}tj|�S|d	k�r�|dk�r�tj}tj|�S|d
k�r�|dk�r�tj}tj|�S|dk�r�|dk�r�tj�r�dnd}tj|�S|dk�r|dk�r
tj�rdnd}tj|�S|d
k�rB|dk�r8tj�r4dnd}tj|�SdS)N�DefaultZoner%r!r"r$r#r&r'r(r)r*r+r,zDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist�yes�no)
r�r%r!r"r$r#r&r'r(r)r*r+r,)rI�
exceptions�
DBusExceptionr�get_firewalld_conf�getZ
FALLBACK_ZONE�StringZFALLBACK_MINIMAL_MARK�int�Int32ZFALLBACK_CLEANUP_ON_EXITZ FALLBACK_CLEANUP_MODULES_ON_EXITZFALLBACK_LOCKDOWNZFALLBACK_IPV6_RPFILTERZFALLBACK_INDIVIDUAL_CALLSZFALLBACK_LOG_DENIEDZFALLBACK_AUTOMATIC_HELPERSZFALLBACK_FIREWALL_BACKENDZFALLBACK_FLUSH_ALL_ON_RELOADZFALLBACK_RFC3964_IPV4ZFALLBACK_ALLOW_ZONE_DRIFTING)rK�prop�valuerPrPrQ�
_get_property+s|





























zFirewallDConfig._get_propertycCsT|dkrtj|j|��S|dkr0tj|j|��S|dkrHtj|j|��S|dkr`tj|j|��S|dkrxtj|j|��S|dkr�tj|j|��S|dkr�tj|j|��S|dkr�tj|j|��S|d	kr�tj|j|��S|d
k�r�tj|j|��S|dk�rtj|j|��S|dk�r&tj|j|��S|d
k�r@tj|j|��Stjjd|��dS)Nr�r%r!r"r$r#r&r'r(r)r*r+r,zDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)rIr�r�r�r�r�)rKr�rPrPrQ�_get_dbus_propertyos:



z"FirewallDConfig._get_dbus_propertyZss�v)�in_signature�
out_signatureNcCsxt|t�}t|t�}tjd||�|tjjkr8|j|�S|tjjtjj	gkr^tj
jd|��ntj
jd|��|j|�S)Nzconfig.Get('%s', '%s')zDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not existzJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strrrvrrIrJr��DBUS_INTERFACE_CONFIG_DIRECT�DBUS_INTERFACE_CONFIG_POLICIESr�r�)rK�interface_name�
property_namer�rPrPrQ�Get�s



zFirewallDConfig.Get�sza{sv}c
Csxt|t�}tjd|�i}|tjjkrDxBdD]}|j|�||<q,Wn&|tjjtjj	gkrZntj
jd|��tj|dd�S)Nzconfig.GetAll('%s')r�r%r!r"r$r#r&r'r(r)r*r+r,zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existZsv)�	signature)
r�r%r!r"r$r#r&r'r(r)r*r+r,)
rr�rrvrrIrJr�r�r�r�r�Z
Dictionary)rKr�r��ret�xrPrPrQru�s"
zFirewallDConfig.GetAllZssv)r�cCs�t|t�}t|t�}t|�}tjd|||�|j|�|tjjk�r�|dk�rz|dkrv|j�dkrvt	t
jd||f��|dkr�|tjkr�t	t
jd||f��|dkr�|tj
kr�t	t
jd||f��|d	k�r�|j�dk�r�t	t
jd||f��|d
k�r|j�dk�rt	t
jd||f��|dk�rF|j�dk�rFt	t
jd||f��|jj�j||�|jj�j�|j|||ig�n|dk�r�ntjjd|��n8|tjjtjjgk�r�tjjd|��ntjjd|��dS)Nzconfig.Set('%s', '%s', '%s')r!r$r"r#r&r'r)r*r+r,r�r��true�falsez'%s' for %sr%r(zDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not existzJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)
r!r$r"r#r&r'r)r*r+r,)r!r$r"r#r&)r�r�r�r�)r�r�r�r�)r�r�r�r�)r�r�r�r�)r%r()rr�rrvr�rrIrJ�lowerrrZ
INVALID_VALUEZLOG_DENIED_VALUESZFIREWALL_BACKEND_VALUESr��set�writer|r�r�r�r�)rKr�r�Z	new_valuer�rPrPrQ�Set�sz










zFirewallDConfig.Setzsa{sv}as)r�cCs.t|t�}t|�}t|�}tjd|||�dS)Nz*config.PropertiesChanged('%s', '%s', '%s'))rr�rrv)rKr�Zchanged_propertiesZinvalidated_propertiesrPrPrQr|s

z!FirewallDConfig.PropertiesChanged)r�cs4tjd�tt|�j|j|jj��}t||t	j
j�S)Nzconfig.Introspect())rZdebug2r-r�
Introspectr0r/Zget_busrrrIrJ)rKr��data)rOrPrQr�s

zFirewallDConfig.IntrospectcCstjd�|jj�jj�S)Nz&config.policies.getLockdownWhitelist())rrvr�get_policies�lockdown_whitelist�
export_config)rKr�rPrPrQ�getLockdownWhitelists
z$FirewallDConfig.getLockdownWhitelistcCs@tjd�t|�}|jj�jj|�|jj�jj�|j�dS)Nz)config.policies.setLockdownWhitelist(...))	rrvrrr�r��
import_configr�r�)rKr�r�rPrPrQ�setLockdownWhitelist&s

z$FirewallDConfig.setLockdownWhitelistcCstjd�dS)Nz*config.policies.LockdownWhitelistUpdated())rrv)rKrPrPrQr�0sz(FirewallDConfig.LockdownWhitelistUpdatedcCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz1config.policies.addLockdownWhitelistCommand('%s')r)rrrvr�rzr�rr�ALREADY_ENABLEDr�r�)rKr�r�r�rPrPrQ�addLockdownWhitelistCommand7s
z+FirewallDConfig.addLockdownWhitelistCommandcCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz4config.policies.removeLockdownWhitelistCommand('%s')r)rrrvr�rzr�rr�NOT_ENABLEDrqr�)rKr�r�r�rPrPrQ�removeLockdownWhitelistCommandDs
z.FirewallDConfig.removeLockdownWhitelistCommand�bcCs$t|�}tjd|�||j�dkS)Nz3config.policies.queryLockdownWhitelistCommand('%s')r)rrrvr�)rKr�r�rPrPrQ�queryLockdownWhitelistCommandRsz-FirewallDConfig.queryLockdownWhitelistCommand�ascCstjd�|j�dS)Nz.config.policies.getLockdownWhitelistCommands()r)rrvr�)rKr�rPrPrQ�getLockdownWhitelistCommands[s
z,FirewallDConfig.getLockdownWhitelistCommandscCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz1config.policies.addLockdownWhitelistContext('%s')r)rrrvr�rzr�rrr�r�r�)rKr�r�r�rPrPrQ�addLockdownWhitelistContextds
z+FirewallDConfig.addLockdownWhitelistContextcCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz4config.policies.removeLockdownWhitelistContext('%s')r)rrrvr�rzr�rrr�rqr�)rKr�r�r�rPrPrQ�removeLockdownWhitelistContextqs
z.FirewallDConfig.removeLockdownWhitelistContextcCs$t|�}tjd|�||j�dkS)Nz3config.policies.queryLockdownWhitelistContext('%s')r)rrrvr�)rKr�r�rPrPrQ�queryLockdownWhitelistContextsz-FirewallDConfig.queryLockdownWhitelistContextcCstjd�|j�dS)Nz.config.policies.getLockdownWhitelistContexts()r)rrvr�)rKr�rPrPrQ�getLockdownWhitelistContexts�s
z,FirewallDConfig.getLockdownWhitelistContextscCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz.config.policies.addLockdownWhitelistUser('%s')�)rrrvr�rzr�rrr�r�r�)rKr�r�r�rPrPrQ�addLockdownWhitelistUser�s
z(FirewallDConfig.addLockdownWhitelistUsercCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz1config.policies.removeLockdownWhitelistUser('%s')r�)rrrvr�rzr�rrr�rqr�)rKr�r�r�rPrPrQ�removeLockdownWhitelistUser�s
z+FirewallDConfig.removeLockdownWhitelistUsercCs$t|�}tjd|�||j�dkS)Nz0config.policies.queryLockdownWhitelistUser('%s')r�)rrrvr�)rKr�r�rPrPrQ�queryLockdownWhitelistUser�sz*FirewallDConfig.queryLockdownWhitelistUsercCstjd�|j�dS)Nz+config.policies.getLockdownWhitelistUsers()r�)rrvr�)rKr�rPrPrQ�getLockdownWhitelistUsers�s
z)FirewallDConfig.getLockdownWhitelistUsers�icCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz+config.policies.addLockdownWhitelistUid(%d)�)rrrvr�rzr�rrr�r�r�)rKr�r�r�rPrPrQ�addLockdownWhitelistUid�s
z'FirewallDConfig.addLockdownWhitelistUidcCs^t|�}tjd|�|j|�t|j��}||dkrBttj|��|dj	|�|j
|�dS)Nz.config.policies.removeLockdownWhitelistUid(%d)r�)rrrvr�rzr�rrr�rqr�)rKr�r�r�rPrPrQ�removeLockdownWhitelistUid�s
z*FirewallDConfig.removeLockdownWhitelistUidcCs$t|�}tjd|�||j�dkS)Nz-config.policies.queryLockdownWhitelistUid(%d)r�)rrrvr�)rKr�r�rPrPrQ�queryLockdownWhitelistUid�sz)FirewallDConfig.queryLockdownWhitelistUidZaicCstjd�|j�dS)Nz*config.policies.getLockdownWhitelistUids()r�)rrvr�)rKr�rPrPrQ�getLockdownWhitelistUids�s
z(FirewallDConfig.getLockdownWhitelistUidsZaocCstjd�|jS)z"list ipsets objects paths
        zconfig.listIPSets())rrvrR)rKr�rPrPrQ�
listIPSets�s
zFirewallDConfig.listIPSetscCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget ipset names
        zconfig.getIPSetNames())rrvrRr�r�r�rC)rKr�rRr�rPrPrQ�
getIPSetNames�s

zFirewallDConfig.getIPSetNames�ocCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z-object path of ipset with given name
        zconfig.getIPSetByName('%s')N)
rr�rrvrRr�r�rrZ
INVALID_IPSET)rKrdr�r�rPrPrQ�getIPSetByName�s
zFirewallDConfig.getIPSetByNamecCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z/add ipset with given name and settings
        zconfig.addIPSet('%s'))rr�rrvr�rZ	new_ipsetr^)rKrdr�r�r�r�rPrPrQ�addIPSet	s


zFirewallDConfig.addIPSetcCst|t�}tjd|�dS)Nzconfig.IPSetAdded('%s'))rr�rrv)rKrdrPrPrQr�s
zFirewallDConfig.IPSetAddedcCstjd�|jS)z%list icmptypes objects paths
        zconfig.listIcmpTypes())rrvrT)rKr�rPrPrQ�
listIcmpTypes s
zFirewallDConfig.listIcmpTypescCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget icmptype names
        zconfig.getIcmpTypeNames())rrvrTr�r�r�rC)rKr�rTr�rPrPrQ�getIcmpTypeNames(s

z FirewallDConfig.getIcmpTypeNamescCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z0object path of icmptype with given name
        zconfig.getIcmpTypeByName('%s')N)
rr�rrvrTr�r�rrZINVALID_ICMPTYPE)rKrer�r�rPrPrQ�getIcmpTypeByName3s
z!FirewallDConfig.getIcmpTypeByNamecCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z2add icmptype with given name and settings
        zconfig.addIcmpType('%s'))rr�rrvr�rZnew_icmptyper_)rKrer�r�r�r�rPrPrQ�addIcmpType@s


zFirewallDConfig.addIcmpTypecCstjd|�dS)Nzconfig.IcmpTypeAdded('%s'))rrv)rKrerPrPrQr�OszFirewallDConfig.IcmpTypeAddedcCstjd�|jS)z$list services objects paths
        zconfig.listServices())rrvrV)rKr�rPrPrQ�listServicesVs
zFirewallDConfig.listServicescCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget service names
        zconfig.getServiceNames())rrvrVr�r�r�rC)rKr�rVr�rPrPrQ�getServiceNames^s

zFirewallDConfig.getServiceNamescCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z/object path of service with given name
        zconfig.getServiceByName('%s')N)
rr�rrvrVr�r�rrZINVALID_SERVICE)rKrfr�r�rPrPrQ�getServiceByNameis
z FirewallDConfig.getServiceByNamezs(sssa(ss)asa{ss}asa(ss))cCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z1add service with given name and settings
        zconfig.addService('%s'))rr�rrvr�rZnew_servicer`)rKrfr�r�r�r�rPrPrQ�
addServicevs


zFirewallDConfig.addServicezsa{sv}cCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z1add service with given name and settings
        zconfig.addService2('%s'))rr�rrvr�rZnew_service_dictr`)rKrfr�r�r�r�rPrPrQ�addService2�s


zFirewallDConfig.addService2cCstjd|�dS)Nzconfig.ServiceAdded('%s'))rrv)rKrfrPrPrQr��szFirewallDConfig.ServiceAddedcCstjd�|jS)z!list zones objects paths
        zconfig.listZones())rrvrX)rKr�rPrPrQ�	listZones�s
zFirewallDConfig.listZonescCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget zone names
        zconfig.getZoneNames())rrvrXr�r�r�rC)rKr�rXr�rPrPrQ�getZoneNames�s

zFirewallDConfig.getZoneNamescCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z,object path of zone with given name
        zconfig.getZoneByName('%s')N)
rr�rrvrXr�r�rrZINVALID_ZONE)rKrgr�r�rPrPrQ�
getZoneByName�s
zFirewallDConfig.getZoneByNamecCszt|t�}tjd|�g}x(|jD]}||jjkr"|j|jj�q"Wt	|�dkrjdj
|�d|t	|�fS|rv|dSdS)z4name of zone the given interface belongs to
        zconfig.getZoneOfInterface('%s')r� zE  (ERROR: interface '%s' is in %s zone XML files, can be only in one)rrs)rr�rrvrXr�Z
interfacesr�r�rk�join)rKZifacer�r�r�rPrPrQ�getZoneOfInterface�s
z"FirewallDConfig.getZoneOfInterfacecCszt|t�}tjd|�g}x(|jD]}||jjkr"|j|jj�q"Wt	|�dkrjdj
|�d|t	|�fS|rv|dSdS)z1name of zone the given source belongs to
        zconfig.getZoneOfSource('%s')rr�zB  (ERROR: source '%s' is in %s zone XML files, can be only in one)rrs)rr�rrvrXr�Zsourcesr�r�rkr)rK�sourcer�r�r�rPrPrQ�getZoneOfSource�s
zFirewallDConfig.getZoneOfSourcez's(sssbsasa(ss)asba(ssss)asasasasa(ss)b)cCsht|t�}t|�}tjd|�|j|�|ddkrLt|�}t|d<t|�}|jj	||�}|j
|�}|S)z.add zone with given name and settings
        zconfig.addZone('%s')��default)rr�rrvr�rzr�tuplerZnew_zonera)rKrgr�r�Z	_settingsr�r�rPrPrQ�addZone�s


zFirewallDConfig.addZonecCs`t|t�}t|�}tjd|�|j|�d|krD|ddkrDt|d<|jj||�}|j|�}|S)z.add zone with given name and settings
        zconfig.addZone('%s')�targetr)	rr�rrvr�rrZ
new_zone_dictra)rKrgr�r�r�r�rPrPrQ�addZone2�s


zFirewallDConfig.addZone2cCstjd|�dS)Nzconfig.ZoneAdded('%s'))rrv)rKrgrPrPrQr�szFirewallDConfig.ZoneAddedcCstjd�|jS)z$list policies objects paths
        zconfig.listPolicies())rrvr\)rKr�rPrPrQ�listPoliciess
zFirewallDConfig.listPoliciescCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget policy names
        zconfig.getPolicyNames())rrvr\r�r�r�rC)rKr�Zpoliciesr�rPrPrQ�getPolicyNamess

zFirewallDConfig.getPolicyNamescCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z.object path of policy with given name
        zconfig.getPolicyByName('%s')N)
rr�rrvr\r�r�rrZINVALID_POLICY)rKrir�r�rPrPrQ�getPolicyByName"s
zFirewallDConfig.getPolicyByNamecCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z0add policy with given name and settings
        zconfig.addPolicy('%s'))rr�rrvr�rZnew_policy_object_dictrc)rKrir�r�r�r�rPrPrQ�	addPolicy/s


zFirewallDConfig.addPolicycCstjd|�dS)Nzconfig.PolicyAdded('%s'))rrv)rKrirPrPrQr�>szFirewallDConfig.PolicyAddedcCstjd�|jS)z#list helpers objects paths
        zconfig.listHelpers())rrvrZ)rKr�rPrPrQ�listHelpersGs
zFirewallDConfig.listHelperscCs4tjd�g}x|jD]}|j|jj�qWt|�S)zget helper names
        zconfig.getHelperNames())rrvrZr�r�r�rC)rKr�rZr�rPrPrQ�getHelperNamesOs

zFirewallDConfig.getHelperNamescCsFt|t�}tjd|�x|jD]}|jj|kr|SqWttj	|��dS)z.object path of helper with given name
        zconfig.getHelperByName('%s')N)
rr�rrvrZr�r�rrZINVALID_HELPER)rKrhr�r�rPrPrQ�getHelperByNameZs
zFirewallDConfig.getHelperByNamecCsDt|t�}t|�}tjd|�|j|�|jj||�}|j|�}|S)z0add helper with given name and settings
        zconfig.addHelper('%s'))rr�rrvr�rZ
new_helperrb)rKrhr�r�r�r�rPrPrQ�	addHelpergs


zFirewallDConfig.addHelpercCst|t�}tjd|�dS)Nzconfig.HelperAdded('%s'))rr�rrv)rKrhrPrPrQr�vs
zFirewallDConfig.HelperAddedcCstjd�|jj�j�S)Nzconfig.direct.getSettings())rrvr�
get_directr�)rKr�rPrPrQr�s
zFirewallDConfig.getSettingscCs<tjd�t|�}|jj�j|�|jj�j�|j�dS)Nzconfig.direct.update())rrvrrrr�r�r�)rKr�r�rPrPrQrr�s

zFirewallDConfig.updatecCstjd�dS)Nzconfig.direct.Updated())rrv)rKrPrPrQr��szFirewallDConfig.UpdatedZssscCs�t|�}t|�}t|�}tjd|||f�|j|�t|||f�}t|j��}||dkrrttj	d|||f��|dj
|�|j|�dS)Nz(config.direct.addChain('%s', '%s', '%s')rz chain '%s' already is in '%s:%s')rrrvr�rrzr�rrr�r�rr)rK�ipv�table�chainr��idxr�rPrPrQ�addChain�s
zFirewallDConfig.addChaincCs�t|�}t|�}t|�}tjd|||f�|j|�t|||f�}t|j��}||dkrrttj	d|||f��|dj
|�|j|�dS)Nz+config.direct.removeChain('%s', '%s', '%s')rzchain '%s' is not in '%s:%s')rrrvr�rrzr�rrr�rqrr)rKrrrr�rr�rPrPrQ�removeChain�s

zFirewallDConfig.removeChaincCsJt|�}t|�}t|�}tjd|||f�t|||f�}||j�dkS)Nz*config.direct.queryChain('%s', '%s', '%s')r)rrrvrr�)rKrrrr�rrPrPrQ�
queryChain�szFirewallDConfig.queryChaincCsft|�}t|�}tjd||f�g}x:|j�dD]*}|d|kr4|d|kr4|j|d�q4W|S)Nz#config.direct.getChains('%s', '%s')rrr�)rrrvr�r�)rKrrr�r�rrPrPrQ�	getChains�szFirewallDConfig.getChainsrsza(sss)cCstjd�|j�dS)Nzconfig.direct.getAllChains()r)rrvr�)rKr�rPrPrQ�getAllChains�s
zFirewallDConfig.getAllChainsZsssiasc	Cs�t|�}t|�}t|�}t|�}t|�}tjd||||dj|�f�|j|�|||||f}t|j��}||dkr�ttj	d||||f��|dj
|�|jt|��dS)Nz1config.direct.addRule('%s', '%s', '%s', %d, '%s')z','rz"rule '%s' already is in '%s:%s:%s')
rrrvrr�rzr�rrr�r�rrr)	rKrrr�priorityrLr�rr�rPrPrQ�addRule�s 
zFirewallDConfig.addRulec	Cs�t|�}t|�}t|�}t|�}t|�}tjd||||dj|�f�|j|�|||||f}t|j��}||dkr�ttj	d||||f��|dj
|�|jt|��dS)Nz4config.direct.removeRule('%s', '%s', '%s', %d, '%s')z','rzrule '%s' is not in '%s:%s:%s')
rrrvrr�rzr�rrr�rqrrr)	rKrrrrrLr�rr�rPrPrQ�
removeRule�s 
zFirewallDConfig.removeRulecCsdt|�}t|�}t|�}t|�}t|�}tjd||||dj|�f�|||||f}||j�dkS)Nz3config.direct.queryRule('%s', '%s', '%s', %d, '%s')z','r)rrrvrr�)rKrrrrrLr�rrPrPrQ�	queryRuleszFirewallDConfig.queryRulecCs�t|�}t|�}t|�}tjd|||f�|j|�t|j��}xF|ddd�D]2}|||f|d|d|dfkrT|dj|�qTW|jt|��dS)Nz+config.direct.removeRules('%s', '%s', '%s')rrr�)	rrrvr�rzr�rqrrr)rKrrrr�r�ZrulerPrPrQ�removeRuless
 zFirewallDConfig.removeRulesza(ias)cCs�t|�}t|�}t|�}tjd|||f�g}xN|j�dD]>}|d|kr>|d|kr>|d|kr>|j|d|df�q>W|S)Nz(config.direct.getRules('%s', '%s', '%s')rrr�r�r)rrrvr�r�)rKrrrr�r�rrPrPrQ�getRules)s$zFirewallDConfig.getRulesz	a(sssias)cCstjd�|j�dS)Nzconfig.direct.getAllRules()r)rrvr�)rKr�rPrPrQ�getAllRules8s
zFirewallDConfig.getAllRulesZsascCs�t|�}t|�}tjd|dj|�f�|j|�||f}t|j��}||dkrfttj	d||f��|dj
|�|j|�dS)Nz(config.direct.addPassthrough('%s', '%s')z','r�zpassthrough '%s', '%s')rrrvrr�rzr�rrr�r�rr)rKrrLr�rr�rPrPrQ�addPassthroughAs
zFirewallDConfig.addPassthroughcCs�t|�}t|�}tjd|dj|�f�|j|�||f}t|j��}||dkrfttj	d||f��|dj
|�|j|�dS)Nz+config.direct.removePassthrough('%s', '%s')z','r�zpassthrough '%s', '%s')rrrvrr�rzr�rrr�rqrr)rKrrLr�rr�rPrPrQ�removePassthroughSs
z!FirewallDConfig.removePassthroughcCs@t|�}t|�}tjd|dj|�f�||f}||j�dkS)Nz*config.direct.queryPassthrough('%s', '%s')z','r�)rrrvrr�)rKrrLr�rrPrPrQ�queryPassthroughdsz FirewallDConfig.queryPassthroughZaascCsNt|�}tjd|�g}x.|j�dD]}|d|kr(|j|d�q(W|S)Nz#config.direct.getPassthroughs('%s')r�rr)rrrvr�r�)rKrr�r�rrPrPrQ�getPassthroughsoszFirewallDConfig.getPassthroughsza(sas)cCstjd�|j�dS)Nz"config.direct.getAllPassthroughs()r�)rrvr�)rKr�rPrPrQ�getAllPassthroughs{s
z"FirewallDConfig.getAllPassthroughs)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)��__name__�
__module__�__qualname__�__doc__Z
persistentrrIZPK_ACTION_CONFIGZdefault_polkit_auth_requiredrr.r1rjror2r_r�rr`r�r�rar�r�rcr�r�r^r�r�rbr�r�rr�r�r�r	ZPROPERTIES_IFACEr�ru�slipZpolkitZrequire_authr�rf�signalr|ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr�r�rZDBUS_SIGNATUREr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rJr�r�r�rr�r�r�r�r�rr�r�r�r�r�r�r�r�r�r�r�rrrr	r�r
rrr
r�rrrrrr�r�rr�rrr�rrrrrrrrr r!r"r#r$r%r&r'�
__classcell__rPrP)rOrQr>sv.				D!D	





	

	

	

	




	

	

	

	r):Z
gi.repositoryr�sys�modulesrArIZdbus.serviceZ	slip.dbusr,Zslip.dbus.serviceZfirewallrZfirewall.core.baserZfirewall.core.watcherrZfirewall.core.loggerrZfirewall.server.decoratorsrrr	Zfirewall.server.config_icmptyper
Zfirewall.server.config_servicerZfirewall.server.config_zonerZfirewall.server.config_policyr
Zfirewall.server.config_ipsetrZfirewall.server.config_helperrZfirewall.core.io.icmptyperZfirewall.core.io.ipsetrZfirewall.core.io.helperrZ#firewall.core.io.lockdown_whitelistrZfirewall.core.io.directrZfirewall.dbus_utilsrrrrrrrrZfirewall.errorsrrfZObjectrrPrPrPrQ�<module>s6
$server/__pycache__/config_policy.cpython-36.opt-1.pyc000064400000015354150351351720016505 0ustar003

��g-!�@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZmZmZGdd	�d	ejjj�ZdS)
�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_methodcs�eZdZdZejjZe�fdd��Z	e
dd��Ze
dd��Ze
dd	��Z
eejd
dd�e
d/dd���Zeejddd�e
d0dd���Zejjjejj�eejdd�e
d1dd����Zejjejdd�dd��Zejjjejj�eejdd�e
d2�fdd�	���Zeejjdd�e
d3dd ���Zeejjdd�e
d4d!d"���Zeejj�e
d5d#d$���Zejjejjdd�e
d%d&���Z eejj�e
d6d'd(���Z!ejjejjdd�e
d)d*���Z"eejjdd�e
d7d+d,���Z#ejjejjdd�e
d-d.���Z$�Z%S)8�FirewallDConfigPolicyTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.policy.%d)
�superr�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_POLICY)�selfrZconfZpolicyr�args�kwargs)�	__class__��#/usr/lib/python3.6/config_policy.pyrs

zFirewallDConfigPolicy.__init__cCsdS)Nr)rrrr�__del__(szFirewallDConfigPolicy.__del__cCs|j�dS)N)Zremove_from_connection)rrrr�
unregister,sz FirewallDConfigPolicy.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrrr rZBooleanr!r"�
exceptions�
DBusException)r�
property_namerrr�
_get_property4sz#FirewallDConfigPolicy._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrrr$r%r')r�interface_namer&�senderrrr�GetEs


zFirewallDConfigPolicy.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existrr rr!r"Zsv)�	signature)rr rr!r")rr+rr,rrrrr$r%r'Z
Dictionary)rr-r.�ret�xrrr�GetAllVs

zFirewallDConfigPolicy.GetAllZssv)r)cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr+rr,rr�accessCheckrrrr$r%)rr-r&Z	new_valuer.rrr�Setgs



zFirewallDConfigPolicy.Setzsa{sv}as)r1cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr+rr,r)rr-Zchanged_propertiesZinvalidated_propertiesrrr�PropertiesChanged{s


z'FirewallDConfigPolicy.PropertiesChanged)r*cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rr
r�
IntrospectrrZget_busrrrr)rr.�data)rrrr8�s

z FirewallDConfigPolicy.IntrospectcCs tjd|j�|jj|j�}|S)z get settings for policy
        z%s.getSettings())rr,rrZget_policy_object_config_dictr)rr.�settingsrrr�getSettings�sz!FirewallDConfigPolicy.getSettingscCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)z#update settings for policy
        z%s.update('...')N)rrr,rrr5rZset_policy_object_config_dictr�Updatedr)rr:r.rrr�update�s
zFirewallDConfigPolicy.updatecCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z1load default settings for builtin policy
        z%s.loadDefaults()N)
rr,rrr5rZload_policy_object_defaultsrr<r)rr.rrr�loadDefaults�sz"FirewallDConfigPolicy.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr,r)rrrrrr<�szFirewallDConfigPolicy.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove policy
        z%s.removePolicy()N)	rr,rrr5rZremove_policy_objectrZremovePolicy)rr.rrr�remove�szFirewallDConfigPolicy.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr,r)rrrrr�Removed�szFirewallDConfigPolicy.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename policy
        z%s.rename('%s')N)rr+rr,rrr5rZrename_policy_objectr�Renamed)rrr.rrr�rename�s

zFirewallDConfigPolicy.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr,r)rrrrrrA�szFirewallDConfigPolicy.Renamed)N)N)N)N)N)N)N)N)N)&�__name__�
__module__�__qualname__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredrrr	rrr'r
ZPROPERTIES_IFACEr/r4�slipZpolkitZrequire_authr6�service�signalr7ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr8rr;r=r>r<r?r@rBrA�
__classcell__rr)rrrs^
		

	r)Z
gi.repositoryr�sys�modulesrZdbus.serviceZ	slip.dbusrFZslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.loggerrZfirewall.server.decoratorsrr	r
rGZObjectrrrrr�<module>s
server/__pycache__/config_zone.cpython-36.opt-1.pyc000064400000101501150351351720016147 0ustar003

��gW��@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZddlmZdd	lmZdd
lmZddlmZmZmZddl	mZdd
lmZddl m!Z!m"Z"m#Z#m$Z$Gdd�dejj%j&�Z'dS)�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�Zone)�ifcfg_set_zone_of_interface)�DEFAULT_ZONE_TARGET)�	Rich_Rule)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�errors)�
FirewallError)�portStr�portInPortRange�coalescePortRange�breakPortRangecs�	eZdZdZdZejjZe	�fdd��Z
edd��Zedd��Z
ed	d
��Zeejddd
�ed�dd���Zeejddd
�ed�dd���Zejjjejj�eejdd�ed�dd����Zejjejdd�dd��Zejjjejj�eejdd�ed��fdd�	���Zeejjd d�ed�d!d"���Zeejjdd�ed�d#d$���Zd%d&�Z eejjd d�ed�d'd(���Z!eejjdd�ed�d)d*���Z"eejj�ed�d+d,���Z#ejjejjdd�ed-d.���Z$eejj�ed�d/d0���Z%ejjejjdd�ed1d2���Z&eejjdd�ed�d3d4���Z'ejjejjdd�ed5d6���Z(eejjdd�ed�d7d8���Z)eejjdd�ed�d9d:���Z*eejjdd�ed�d;d<���Z+eejjdd�ed�d=d>���Z,eejjdd�ed�d?d@���Z-eejjdd�ed�dAdB���Z.eejjdd�ed�dCdD���Z/eejjdd�ed�dEdF���Z0eejjdGd�ed�dHdI���Z1eejjdGd�ed�dJdK���Z2eejjdd�ed�dLdM���Z3eejjdd�ed�dNdO���Z4eejjddPd
�ed�dQdR���Z5eejjdSd�ed�dTdU���Z6eejjdSd�ed�dVdW���Z7eejjdd�ed�dXdY���Z8eejjdd�ed�dZd[���Z9eejjddPd
�ed�d\d]���Z:eejjdGd�ed�d^d_���Z;eejjdGd�ed�d`da���Z<eejjdd�ed�dbdc���Z=eejjdd�ed�ddde���Z>eejjddPd
�ed�dfdg���Z?eejjdSd�ed�dhdi���Z@eejjdSd�ed�djdk���ZAeejjdd�ed�dldm���ZBeejjdd�ed�dndo���ZCeejjddPd
�ed�dpdq���ZDeejjdGd�ed�drds���ZEeejjdGd�ed�dtdu���ZFeejjdd�ed�dvdw���ZGeejjdd�ed�dxdy���ZHeejjddPd
�ed�dzd{���ZIeejjdPd�ed�d|d}���ZJeejjdPd�ed�d~d���ZKeejj�ed�d�d����ZLeejj�ed�d�d����ZMeejjdPd�ed�d�d����ZNeejjdPd�ed�d�d����ZOeejjdPd�ed�d�d����ZPeejj�ed�d�d����ZQeejj�ed�d�d����ZReejjdPd�ed�d�d����ZSeejjd�d�ed�d�d����ZTeejjd�d�ed�d�d����ZUeejjd�d�ed�d�d����ZVeejjd�d�ed�d�d����ZWeejjd�dPd
�ed�d�d����ZXeejjdGd�ed�d�d����ZYeejjdGd�ed�d�d����ZZeejjdd�ed�d�d����Z[eejjdd�ed�d�d����Z\eejjddPd
�ed�d�d����Z]eejjdGd�ed�d�d����Z^eejjdGd�ed�d�d����Z_eejjdd�ed�d�d����Z`eejjdd�ed�d�d����ZaeejjddPd
�ed�d�d����ZbeejjdGd�ed�d�d����ZceejjdGd�e�dd�d����Zdeejjdd�e�dd�d����Zeeejjdd�e�dd�d����ZfeejjddPd
�e�dd�d����Zg�ZhS(�FirewallDConfigZonezFirewallD main classTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.zone.%d)
�superr�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_ZONE)�selfrZconfZzoner�args�kwargs)�	__class__��!/usr/lib/python3.6/config_zone.pyr=s

zFirewallDConfigZone.__init__cCsdS)Nr%)r!r%r%r&�__del__JszFirewallDConfigZone.__del__cCs|j�dS)N)Zremove_from_connection)r!r%r%r&�
unregisterNszFirewallDConfigZone.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrr)r*rZBooleanr+r,�
exceptions�
DBusException)r!�
property_namer%r%r&�
_get_propertyVsz!FirewallDConfigZone._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrr r.r/r1)r!�interface_namer0�senderr%r%r&�Getgs


zFirewallDConfigZone.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existr)r*rr+r,Zsv)�	signature)r)r*rr+r,)rr5rr6rrrr r.r/r1Z
Dictionary)r!r7r8�ret�xr%r%r&�GetAllxs

zFirewallDConfigZone.GetAllZssv)r3cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr5rr6rr�accessCheckrrr r.r/)r!r7r0Z	new_valuer8r%r%r&�Set�s



zFirewallDConfigZone.Setzsa{sv}as)r;cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr5rr6r)r!r7Zchanged_propertiesZinvalidated_propertiesr%r%r&�PropertiesChanged�s


z%FirewallDConfigZone.PropertiesChanged)r4cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rrr�
IntrospectrrZget_busrrrr )r!r8�data)r$r%r&rB�s

zFirewallDConfigZone.Introspectz&(sssbsasa(ss)asba(ssss)asasasasa(ss)b)cCsDtjd|j�|jj|j�}|dtkr@t|�}d|d<t|�}|S)zget settings for zone
        z%s.getSettings()�r+)	rr6rrZget_zone_configrr	�list�tuple)r!r8�settings�	_settingsr%r%r&�getSettings�szFirewallDConfigZone.getSettingscCs4tjd|j�|jj|j�}|dtkr0d|d<|S)zget settings for zone
        z%s.getSettings2()�targetr+)rr6rr�get_zone_config_dictrr	)r!r8rGr%r%r&�getSettings2�s
z FirewallDConfigZone.getSettings2cCs|jj|j�}d|kr"t|d�nt�}d|kr<t|d�nt�}t|t�rzt|tjd��|}t|tjd��|}nDd|kr�t|d�nt�}d|kr�t|d�nt�}||}||}x$|D]}	|jj	|	�r�t
tj|	��q�Wx$|D]}
|jj
|
�r�t
tj|
��q�WdS)a
Assignment of interfaces/sources to zones is different from other
           zone settings in the sense that particular interface/zone can be
           part of only one zone. So make sure added interfaces/sources have
           not already been bound to another zone.�
interfaces�sourcesN)rrKr�set�
isinstancerFrZindex_ofrZgetZoneOfInterfacerrZ
ZONE_CONFLICTZgetZoneOfSource)r!rGZold_settingsZ
old_ifacesZold_sourcesZadded_ifacesZ
added_sourcesZ
new_ifacesZnew_sourcesZiface�sourcer%r%r&� _checkDuplicateInterfacesSources�s 


z4FirewallDConfigZone._checkDuplicateInterfacesSourcescCstt|�}tjd|j�|jj|�|ddkrFt|�}t|d<t|�}|j	|�|j
j|j|�|_|j
|jj�dS)z!update settings for zone
        z%s.update('...')rDr+N)rrr6rrr?rEr	rFrRrZset_zone_configr�Updatedr))r!rGr8rHr%r%r&�update�s
zFirewallDConfigZone.updatecCslt|�}tjd|j�|jj|�d|kr>|ddkr>t|d<|j|�|jj	|j
|�|_
|j|j
j�dS)z!update settings for zone
        z%s.update2('...')rJr+N)
rrr6rrr?r	rRrZset_zone_config_dictrrSr))r!rGr8r%r%r&�update2�s
zFirewallDConfigZone.update2cCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z/load default settings for builtin zone
        z%s.loadDefaults()N)
rr6rrr?rZload_zone_defaultsrrSr))r!r8r%r%r&�loadDefaultssz FirewallDConfigZone.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr6r)r!r)r%r%r&rSszFirewallDConfigZone.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove zone
        z%s.removeZone()N)	rr6rrr?rZremove_zonerZ
removeZone)r!r8r%r%r&�removeszFirewallDConfigZone.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr6r)r!r)r%r%r&�Removed#szFirewallDConfigZone.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename zone
        z%s.rename('%s')N)rr5rr6rrr?rZrename_zoner�Renamed)r!r)r8r%r%r&�rename*s

zFirewallDConfigZone.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr6r)r!r)r%r%r&rY6szFirewallDConfigZone.RenamedcCstjd|j�|j�dS)Nz%s.getVersion()r)rr6rrI)r!r8r%r%r&�
getVersion=szFirewallDConfigZone.getVersioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setVersion('%s')r)
rr5rr6rrr?rErIrT)r!�versionr8rGr%r%r&�
setVersionDs
zFirewallDConfigZone.setVersioncCstjd|j�|j�dS)Nz
%s.getShort()r)rr6rrI)r!r8r%r%r&�getShortQszFirewallDConfigZone.getShortcCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setShort('%s')r)
rr5rr6rrr?rErIrT)r!Zshortr8rGr%r%r&�setShortXs
zFirewallDConfigZone.setShortcCstjd|j�|j�dS)Nz%s.getDescription()�)rr6rrI)r!r8r%r%r&�getDescriptionesz"FirewallDConfigZone.getDescriptioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setDescription('%s')r`)
rr5rr6rrr?rErIrT)r!�descriptionr8rGr%r%r&�setDescriptionls
z"FirewallDConfigZone.setDescriptioncCs.tjd|j�|j�}|dtkr*|dSdS)Nz%s.getTarget()rDr+)rr6rrIr	)r!r8rGr%r%r&�	getTarget|szFirewallDConfigZone.getTargetcCsTt|t�}tjd|j|�|jj|�t|j��}|dkr>|nt	|d<|j
|�dS)Nz%s.setTarget('%s')r+rD)rr5rr6rrr?rErIr	rT)r!rJr8rGr%r%r&�	setTarget�s
zFirewallDConfigZone.setTarget�ascCstjd|j�|j�dS)Nz%s.getServices()�)rr6rrI)r!r8r%r%r&�getServices�szFirewallDConfigZone.getServicescCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setServices('[%s]')�,rg)
rrErr6r�joinrr?rIrT)r!Zservicesr8rGr%r%r&�setServices�s

zFirewallDConfigZone.setServicescCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addService('%s')rg)rr5rr6rrr?rErIrr�ALREADY_ENABLED�appendrT)r!�servicer8rGr%r%r&�
addService�s
zFirewallDConfigZone.addServicecCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.removeService('%s')rg)rr5rr6rrr?rErIrr�NOT_ENABLEDrWrT)r!rnr8rGr%r%r&�
removeService�s
z!FirewallDConfigZone.removeService�bcCs*t|t�}tjd|j|�||j�dkS)Nz%s.queryService('%s')rg)rr5rr6rrI)r!rnr8r%r%r&�queryService�s
z FirewallDConfigZone.queryServiceza(ss)cCstjd|j�|j�dS)Nz
%s.getPorts()�)rr6rrI)r!r8r%r%r&�getPorts�szFirewallDConfigZone.getPortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setPorts('[%s]')ricss"|]}d|d|dfVqdS)z('%s, '%s')rrNr%)�.0�portr%r%r&�	<genexpr>�sz/FirewallDConfigZone.setPorts.<locals>.<genexpr>rt)
rrErPrmrFrr6rrjrr?rIrT)r!�portsr8�_portsrwrGr%r%r&�setPorts�s

zFirewallDConfigZone.setPortsc
s�t|t�}t�t��tjd|j|��|jj|�t|j��}tt	�fdd�|d��}x.|D]&}t
||d�r^ttj
d|�f��q^Wt|dd�|D��\}}x$|D]}	|djt|	d	��f�q�Wx$|D]}	|djt|	d	��f�q�W|j|�dS)
Nz%s.addPort('%s', '%s')cs|d�kS)Nrr%)r=)�protocolr%r&�<lambda>�sz-FirewallDConfigZone.addPort.<locals>.<lambda>rtrz%s:%scSsg|]\}}|�qSr%r%)rv�_port�	_protocolr%r%r&�
<listcomp>�sz/FirewallDConfigZone.addPort.<locals>.<listcomp>�-)rr5rr6rrr?rErI�filterrrrrlrrWrrmrT)
r!rwr|r8rG�existing_port_ids�port_id�added_ranges�removed_ranges�ranger%)r|r&�addPort�s"




zFirewallDConfigZone.addPortc
s�t|t�}t�t��tjd|j|��|jj|�t|j��}tt	�fdd�|d��}x0|D]}t
||d�r^Pq^Wttj
d|�f��t|dd�|D��\}}x$|D]}	|djt|	d	��f�q�Wx$|D]}	|djt|	d	��f�q�W|j|�dS)
Nz%s.removePort('%s', '%s')cs|d�kS)Nrr%)r=)r|r%r&r}sz0FirewallDConfigZone.removePort.<locals>.<lambda>rtrz%s:%scSsg|]\}}|�qSr%r%)rvr~rr%r%r&r�sz2FirewallDConfigZone.removePort.<locals>.<listcomp>r�)rr5rr6rrr?rErIr�rrrrprrWrrmrT)
r!rwr|r8rGr�r�r�r�r�r%)r|r&�
removePort�s"




zFirewallDConfigZone.removePortcCsZt|t�}t|t�}tjd|j||�x.|j�dD]\}}t||�r4||kr4dSq4WdS)Nz%s.queryPort('%s', '%s')rtTF)rr5rr6rrIr)r!rwr|r8r~rr%r%r&�	queryPorts

zFirewallDConfigZone.queryPortcCstjd|j�|j�dS)Nz%s.getProtocols()�
)rr6rrI)r!r8r%r%r&�getProtocolssz FirewallDConfigZone.getProtocolscCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setProtocols('[%s]')rir�)
rrErr6rrjrr?rIrT)r!Z	protocolsr8rGr%r%r&�setProtocols&s

z FirewallDConfigZone.setProtocolscCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addProtocol('%s')r�)rr5rr6rrr?rErIrrrlrmrT)r!r|r8rGr%r%r&�addProtocol2s
zFirewallDConfigZone.addProtocolcCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.removeProtocol('%s')r�)rr5rr6rrr?rErIrrrprWrT)r!r|r8rGr%r%r&�removeProtocol?s
z"FirewallDConfigZone.removeProtocolcCs*t|t�}tjd|j|�||j�dkS)Nz%s.queryProtocol('%s')r�)rr5rr6rrI)r!r|r8r%r%r&�
queryProtocolLs
z!FirewallDConfigZone.queryProtocolcCstjd|j�|j�dS)Nz%s.getSourcePorts()�)rr6rrI)r!r8r%r%r&�getSourcePortsVsz"FirewallDConfigZone.getSourcePortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setSourcePorts('[%s]')ricss"|]}d|d|dfVqdS)z('%s, '%s')rrNr%)rvrwr%r%r&rxjsz5FirewallDConfigZone.setSourcePorts.<locals>.<genexpr>r�)
rrErPrmrFrr6rrjrr?rIrT)r!ryr8rzrwrGr%r%r&�setSourcePorts]s

z"FirewallDConfigZone.setSourcePortsc
s�t|t�}t�t��tjd|j|��|jj|�t|j��}tt	�fdd�|d��}x.|D]&}t
||d�r^ttj
d|�f��q^Wt|dd�|D��\}}x$|D]}	|djt|	d	��f�q�Wx$|D]}	|djt|	d	��f�q�W|j|�dS)
Nz%s.addSourcePort('%s', '%s')cs|d�kS)Nrr%)r=)r|r%r&r}zsz3FirewallDConfigZone.addSourcePort.<locals>.<lambda>r�rz%s:%scSsg|]\}}|�qSr%r%)rvr~rr%r%r&r�sz5FirewallDConfigZone.addSourcePort.<locals>.<listcomp>r�)rr5rr6rrr?rErIr�rrrrlrrWrrmrT)
r!rwr|r8rGr�r�r�r�r�r%)r|r&�
addSourcePortps"




z!FirewallDConfigZone.addSourcePortc
s�t|t�}t�t��tjd|j|��|jj|�t|j��}tt	�fdd�|d��}x0|D]}t
||d�r^Pq^Wttj
d|�f��t|dd�|D��\}}x$|D]}	|djt|	d	��f�q�Wx$|D]}	|djt|	d	��f�q�W|j|�dS)
Nz%s.removeSourcePort('%s', '%s')cs|d�kS)Nrr%)r=)r|r%r&r}�sz6FirewallDConfigZone.removeSourcePort.<locals>.<lambda>r�rz%s:%scSsg|]\}}|�qSr%r%)rvr~rr%r%r&r��sz8FirewallDConfigZone.removeSourcePort.<locals>.<listcomp>r�)rr5rr6rrr?rErIr�rrrrprrWrrmrT)
r!rwr|r8rGr�r�r�r�r�r%)r|r&�removeSourcePort�s"




z$FirewallDConfigZone.removeSourcePortcCsZt|t�}t|t�}tjd|j||�x.|j�dD]\}}t||�r4||kr4dSq4WdS)Nz%s.querySourcePort('%s', '%s')r�TF)rr5rr6rrIr)r!rwr|r8r~rr%r%r&�querySourcePort�s

z#FirewallDConfigZone.querySourcePortcCstjd|j�|j�dS)Nz%s.getIcmpBlocks()�)rr6rrI)r!r8r%r%r&�
getIcmpBlocks�sz!FirewallDConfigZone.getIcmpBlockscCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setIcmpBlocks('[%s]')rir�)
rrErr6rrjrr?rIrT)r!Z	icmptypesr8rGr%r%r&�
setIcmpBlocks�s

z!FirewallDConfigZone.setIcmpBlockscCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addIcmpBlock('%s')r�)rr5rr6rrr?rErIrrrlrmrT)r!�icmptyper8rGr%r%r&�addIcmpBlock�s
z FirewallDConfigZone.addIcmpBlockcCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.removeIcmpBlock('%s')r�)rr5rr6rrr?rErIrrrprWrT)r!r�r8rGr%r%r&�removeIcmpBlock�s
z#FirewallDConfigZone.removeIcmpBlockcCs*t|t�}tjd|j|�||j�dkS)Nz%s.queryIcmpBlock('%s')r�)rr5rr6rrI)r!r�r8r%r%r&�queryIcmpBlock�s
z"FirewallDConfigZone.queryIcmpBlockcCstjd|j�|j�dS)Nz%s.getIcmpBlockInversion()�)rr6rrI)r!r8r%r%r&�getIcmpBlockInversion�sz)FirewallDConfigZone.getIcmpBlockInversioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setIcmpBlockInversion('%s')r�)
r�boolrr6rrr?rErIrT)r!�flagr8rGr%r%r&�setIcmpBlockInversion�s
z)FirewallDConfigZone.setIcmpBlockInversioncCsPtjd|j�|jj|�t|j��}|dr:ttj	d��d|d<|j
|�dS)Nz%s.addIcmpBlockInversion()r�zicmp-block-inversionT)rr6rrr?rErIrrrlrT)r!r8rGr%r%r&�addIcmpBlockInversion�sz)FirewallDConfigZone.addIcmpBlockInversioncCsPtjd|j�|jj|�t|j��}|ds:ttj	d��d|d<|j
|�dS)Nz%s.removeIcmpBlockInversion()r�zicmp-block-inversionF)rr6rrr?rErIrrrprT)r!r8rGr%r%r&�removeIcmpBlockInversionsz,FirewallDConfigZone.removeIcmpBlockInversioncCstjd|j�|j�dS)Nz%s.queryIcmpBlockInversion()r�)rr6rrI)r!r8r%r%r&�queryIcmpBlockInversionsz+FirewallDConfigZone.queryIcmpBlockInversioncCstjd|j�|j�dS)Nz%s.getMasquerade()�)rr6rrI)r!r8r%r%r&�
getMasqueradesz!FirewallDConfigZone.getMasqueradecCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setMasquerade('%s')r�)
rr�rr6rrr?rErIrT)r!�
masquerader8rGr%r%r&�
setMasquerades
z!FirewallDConfigZone.setMasqueradecCsPtjd|j�|jj|�t|j��}|dr:ttj	d��d|d<|j
|�dS)Nz%s.addMasquerade()r�r�T)rr6rrr?rErIrrrlrT)r!r8rGr%r%r&�
addMasquerade'sz!FirewallDConfigZone.addMasqueradecCsPtjd|j�|jj|�t|j��}|ds:ttj	d��d|d<|j
|�dS)Nz%s.removeMasquerade()r�r�F)rr6rrr?rErIrrrprT)r!r8rGr%r%r&�removeMasquerade2sz$FirewallDConfigZone.removeMasqueradecCstjd|j�|j�dS)Nz%s.queryMasquerade()r�)rr6rrI)r!r8r%r%r&�queryMasquerade=sz#FirewallDConfigZone.queryMasqueradeza(ssss)cCstjd|j�|j�dS)Nz%s.getForwardPorts()�	)rr6rrI)r!r8r%r%r&�getForwardPortsFsz#FirewallDConfigZone.getForwardPortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setForwardPorts('[%s]')ricss.|]&}d|d|d|d|dfVqdS)z('%s, '%s', '%s', '%s')rrr`�Nr%)rvrwr%r%r&rxZsz6FirewallDConfigZone.setForwardPorts.<locals>.<genexpr>r�)
rrErPrmrFrr6rrjrr?rIrT)r!ryr8rzrwrGr%r%r&�setForwardPortsMs


z#FirewallDConfigZone.setForwardPortsZsssscCs�t|t�}t|t�}t|t�}t|t�}tjd|j||||�|jj|�||t|�t|�f}t|j��}||dkr�t	t
jd||||f��|dj|�|j
|�dS)Nz)%s.addForwardPort('%s', '%s', '%s', '%s')r�z%s:%s:%s:%s)rr5rr6rrr?rErIrrrlrmrT)r!rwr|�toport�toaddrr8�fwp_idrGr%r%r&�addForwardPortas




z"FirewallDConfigZone.addForwardPortcCs�t|t�}t|t�}t|t�}t|t�}tjd|j||||�|jj|�||t|�t|�f}t|j��}||dkr�t	t
jd||||f��|dj|�|j
|�dS)Nz,%s.removeForwardPort('%s', '%s', '%s', '%s')r�z%s:%s:%s:%s)rr5rr6rrr?rErIrrrprWrT)r!rwr|r�r�r8r�rGr%r%r&�removeForwardPortus




z%FirewallDConfigZone.removeForwardPortcCsbt|t�}t|t�}t|t�}t|t�}tjd|j||||�||t|�t|�f}||j�dkS)Nz+%s.queryForwardPort('%s', '%s', '%s', '%s')r�)rr5rr6rrI)r!rwr|r�r�r8r�r%r%r&�queryForwardPort�s



z$FirewallDConfigZone.queryForwardPortcCstjd|j�|j�dS)Nz%s.getInterfaces()�
)rr6rrI)r!r8r%r%r&�
getInterfaces�sz!FirewallDConfigZone.getInterfacescCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setInterfaces('[%s]')rir�)
rrErr6rrjrr?rIrT)r!rMr8rGr%r%r&�
setInterfaces�s

z!FirewallDConfigZone.setInterfacescCstt|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�t|jj|�dS)Nz%s.addInterface('%s')r�)rr5rr6rrr?rErIrrrlrmrTrrr))r!�	interfacer8rGr%r%r&�addInterface�s

z FirewallDConfigZone.addInterfacecCspt|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�td|�dS)Nz%s.removeInterface('%s')r��)rr5rr6rrr?rErIrrrprWrTr)r!r�r8rGr%r%r&�removeInterface�s

z#FirewallDConfigZone.removeInterfacecCs*t|t�}tjd|j|�||j�dkS)Nz%s.queryInterface('%s')r�)rr5rr6rrI)r!r�r8r%r%r&�queryInterface�s
z"FirewallDConfigZone.queryInterfacecCstjd|j�|j�dS)Nz%s.getSources()�)rr6rrI)r!r8r%r%r&�
getSources�szFirewallDConfigZone.getSourcescCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setSources('[%s]')rir�)
rrErr6rrjrr?rIrT)r!rNr8rGr%r%r&�
setSources�s

zFirewallDConfigZone.setSourcescCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addSource('%s')r�)rr5rr6rrr?rErIrrrlrmrT)r!rQr8rGr%r%r&�	addSource�s
zFirewallDConfigZone.addSourcecCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.removeSource('%s')r�)rr5rr6rrr?rErIrrrprWrT)r!rQr8rGr%r%r&�removeSource�s
z FirewallDConfigZone.removeSourcecCs*t|t�}tjd|j|�||j�dkS)Nz%s.querySource('%s')r�)rr5rr6rrI)r!rQr8r%r%r&�querySources
zFirewallDConfigZone.querySourcecCstjd|j�|j�dS)Nz%s.getRichRules()�)rr6rrI)r!r8r%r%r&�getRichRulessz FirewallDConfigZone.getRichRulescCs\t|t�}tjd|jdj|��|jj|�t|j��}dd�|D�}||d<|j	|�dS)Nz%s.setRichRules('[%s]')ricSsg|]}tt|d���qS))�rule_str)r5r
)rv�rr%r%r&r�sz4FirewallDConfigZone.setRichRules.<locals>.<listcomp>r�)
rrErr6rrjrr?rIrT)r!Zrulesr8rGr%r%r&�setRichRuless

z FirewallDConfigZone.setRichRulescCstt|t�}tjd|j|�|jj|�t|j��}tt	|d��}||dkrXt
tj|��|dj
|�|j|�dS)Nz%s.addRichRule('%s'))r�r�)rr5rr6rrr?rErIr
rrrlrmrT)r!�ruler8rGr�r%r%r&�addRichRule s
zFirewallDConfigZone.addRichRulecCstt|t�}tjd|j|�|jj|�t|j��}tt	|d��}||dkrXt
tj|��|dj
|�|j|�dS)Nz%s.removeRichRule('%s'))r�r�)rr5rr6rrr?rErIr
rrrprWrT)r!r�r8rGr�r%r%r&�removeRichRule.s
z"FirewallDConfigZone.removeRichRulecCs8t|t�}tjd|j|�tt|d��}||j�dkS)Nz%s.queryRichRule('%s'))r�r�)rr5rr6rr
rI)r!r�r8r�r%r%r&�
queryRichRule<s
z!FirewallDConfigZone.queryRichRule)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)i�__name__�
__module__�__qualname__�__doc__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredrrr
r'r(r1rZPROPERTIES_IFACEr9r>�slipZpolkitZrequire_authr@rn�signalrAZPK_ACTION_INFOZINTROSPECTABLE_IFACErBr rIrLrRrTrUrVrSrWrXrZrYr[r]r^r_rarcrdrerhrkrorqrsrur{r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r��
__classcell__r%r%)r$r&r5sf
		

	



	


	


	


	
	
	
			


r)(Z
gi.repositoryr�sys�modulesrZdbus.serviceZ	slip.dbusr�Zslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.io.zonerZfirewall.core.fw_ifcfgrZfirewall.core.baser	Zfirewall.core.richr
Zfirewall.core.loggerrZfirewall.server.decoratorsrr
rrZfirewall.errorsrZfirewall.functionsrrrrrnZObjectrr%r%r%r&�<module>s$
	server/__pycache__/config_helper.cpython-36.opt-1.pyc000064400000030613150351351720016460 0ustar003

��g�D�@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZddlmZmZmZdd	l	mZdd
lmZGdd�dejjj�ZdS)
�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�Helper)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�errors)�
FirewallErrorcseZdZdZdZejjZe	�fdd��Z
edd��Zedd��Z
ed	d
��Zeejddd
�edTdd���Zeejddd
�edUdd���Zejjjejj�eejdd�edVdd����Zejjejdd�dd��Zejjjejj�eejdd�edW�fdd�	���Zeejjejd�edXd d!���Z eejjejd�edYd"d#���Z!eejj�edZd$d%���Z"ejjejjdd�ed&d'���Z#eejj�ed[d(d)���Z$ejjejjdd�ed*d+���Z%eejjdd�ed\d,d-���Z&ejjejjdd�ed.d/���Z'eejjdd�ed]d0d1���Z(eejjdd�ed^d2d3���Z)eejjdd�ed_d4d5���Z*eejjdd�ed`d6d7���Z+eejjdd�edad8d9���Z,eejjdd�edbd:d;���Z-eejjdd�edcd<d=���Z.eejjdd�eddd>d?���Z/eejjdd@d
�ededAdB���Z0eejjdd�edfdCdD���Z1eejjdd�edgdEdF���Z2eejjdd@d
�edhdGdH���Z3eejjdId�edidJdK���Z4eejjdId�edjdLdM���Z5eejjdd�edkdNdO���Z6eejjdd�edldPdQ���Z7eejjdd@d
�edmdRdS���Z8�Z9S)n�FirewallDConfigHelperzFirewallD main classTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.helper.%d)
�superr�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_HELPER)�selfrZconf�helperr�args�kwargs)�	__class__��#/usr/lib/python3.6/config_helper.pyr8s

zFirewallDConfigHelper.__init__cCsdS)Nr)rrrr �__del__EszFirewallDConfigHelper.__del__cCs|j�dS)N)Zremove_from_connection)rrrr �
unregisterIsz FirewallDConfigHelper.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrr#r$rZBooleanr%r&�
exceptions�
DBusException)r�
property_namerrr �
_get_propertyQsz#FirewallDConfigHelper._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrrr(r)r+)r�interface_namer*�senderrrr �Getbs


zFirewallDConfigHelper.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existr#r$rr%r&Zsv)�	signature)r#r$rr%r&)rr/rr0rrrrr(r)r+Z
Dictionary)rr1r2�ret�xrrr �GetAllss

zFirewallDConfigHelper.GetAllZssv)r-cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr/rr0rr�accessCheckrrrr(r))rr1r*Z	new_valuer2rrr �Set�s



zFirewallDConfigHelper.Setzsa{sv}as)r5cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr/rr0r)rr1Zchanged_propertiesZinvalidated_propertiesrrr �PropertiesChanged�s


z'FirewallDConfigHelper.PropertiesChanged)r.cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rrr�
IntrospectrrZget_busrrrr)rr2�data)rrr r<�s

z FirewallDConfigHelper.IntrospectcCstjd|j�|jj|j�S)z get settings for helper
        z%s.getSettings())rr0rrZget_helper_configr)rr2rrr �getSettings�sz!FirewallDConfigHelper.getSettingscCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)z#update settings for helper
        z%s.update('...')N)rrr0rrr9rZset_helper_configr�Updatedr#)r�settingsr2rrr �update�s
zFirewallDConfigHelper.updatecCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z1load default settings for builtin helper
        z%s.loadDefaults()N)
rr0rrr9rZload_helper_defaultsrr?r#)rr2rrr �loadDefaults�sz"FirewallDConfigHelper.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr0r)rr#rrr r?�szFirewallDConfigHelper.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove helper
        z%s.removeHelper()N)	rr0rrr9rZ
remove_helperrZremoveHelper)rr2rrr �remove�szFirewallDConfigHelper.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr0r)rr#rrr �Removed�szFirewallDConfigHelper.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename helper
        z%s.rename('%s')N)rr/rr0rrr9rZ
rename_helperr�Renamed)rr#r2rrr �rename�s

zFirewallDConfigHelper.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr0r)rr#rrr rE�szFirewallDConfigHelper.RenamedcCstjd|j�|j�dS)Nz%s.getVersion()r)rr0rr>)rr2rrr �
getVersion�sz FirewallDConfigHelper.getVersioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setVersion('%s')r)
rr/rr0rrr9�listr>rA)r�versionr2r@rrr �
setVersions
z FirewallDConfigHelper.setVersioncCstjd|j�|j�dS)Nz
%s.getShort()r)rr0rr>)rr2rrr �getShortszFirewallDConfigHelper.getShortcCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setShort('%s')r)
rr/rr0rrr9rHr>rA)rZshortr2r@rrr �setShorts
zFirewallDConfigHelper.setShortcCstjd|j�|j�dS)Nz%s.getDescription()�)rr0rr>)rr2rrr �getDescription$sz$FirewallDConfigHelper.getDescriptioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setDescription('%s')rM)
rr/rr0rrr9rHr>rA)r�descriptionr2r@rrr �setDescription+s

z$FirewallDConfigHelper.setDescriptioncCs.tjd|j�|jj|�t|j��}|dS)Nz%s.getFamily()�)rr0rrr9rHr>)rr2r@rrr �	getFamily9szFirewallDConfigHelper.getFamilycCsdt|t�}tjd|j|�|jj|�t|j��}|d|krNt	t
jd|��||d<|j|�dS)Nz%s.setFamily('%s')rQz'%s')
rr/rr0rrr9rHr>r
r�ALREADY_ENABLEDrA)r�ipvr2r@rrr �	setFamilyBs
zFirewallDConfigHelper.setFamily�bcCs.t|t�}tjd|j|�|j�}|d|kS)Nz%s.queryFamily('%s')rQ)rr/rr0rr>)rrTr2r@rrr �queryFamilyOs
z!FirewallDConfigHelper.queryFamilycCs.tjd|j�|jj|�t|j��}|dS)Nz%s.getModule()�)rr0rrr9rHr>)rr2r@rrr �	getModuleZszFirewallDConfigHelper.getModulecCsdt|t�}tjd|j|�|jj|�t|j��}|d|krNt	t
jd|��||d<|j|�dS)Nz%s.setModule('%s')rXz'%s')
rr/rr0rrr9rHr>r
rrSrA)r�moduler2r@rrr �	setModulecs
zFirewallDConfigHelper.setModulecCs.t|t�}tjd|j|�|j�}|d|kS)Nz%s.queryModule('%s')rX)rr/rr0rr>)rrZr2r@rrr �queryModuleps
z!FirewallDConfigHelper.queryModuleza(ss)cCstjd|j�|j�dS)Nz
%s.getPorts()�)rr0rr>)rr2rrr �getPorts{szFirewallDConfigHelper.getPortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setPorts('[%s]')�,css"|]}d|d|dfVqdS)z('%s, '%s')rrNr)�.0�portrrr �	<genexpr>�sz1FirewallDConfigHelper.setPorts.<locals>.<genexpr>r])
rrH�
isinstance�append�tuplerr0r�joinrr9r>rA)rZportsr2Z_portsrar@rrr �setPorts�s

zFirewallDConfigHelper.setPortscCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.addPort('%s', '%s')r]z%s:%s)rr/rr0rrr9rHr>r
rrSrdrA)rra�protocolr2r@rrr �addPort�s

zFirewallDConfigHelper.addPortcCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.removePort('%s', '%s')r]z%s:%s)rr/rr0rrr9rHr>r
rZNOT_ENABLEDrCrA)rrarhr2r@rrr �
removePort�s

z FirewallDConfigHelper.removePortcCs:t|t�}t|t�}tjd|j||�||f|j�dkS)Nz%s.queryPort('%s', '%s')r])rr/rr0rr>)rrarhr2rrr �	queryPort�s


zFirewallDConfigHelper.queryPort)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N):�__name__�
__module__�__qualname__�__doc__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredr	rr
r!r"r+rZPROPERTIES_IFACEr3r8�slipZpolkitZrequire_authr:�service�signalr;ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr<rrZDBUS_SIGNATUREr>rArBr?rCrDrFrErGrJrKrLrNrPrRrUrWrYr[r\r^rgrirjrk�
__classcell__rr)rr r0s�
		

	




r)Z
gi.repositoryr�sys�modulesrZdbus.serviceZ	slip.dbusrpZslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.io.helperrZfirewall.core.loggerrZfirewall.server.decoratorsr	r
rrZfirewall.errorsr
rqZObjectrrrrr �<module>s
server/__pycache__/config_policy.cpython-36.pyc000064400000015354150351351720015546 0ustar003

��g-!�@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZmZmZGdd	�d	ejjj�ZdS)
�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_methodcs�eZdZdZejjZe�fdd��Z	e
dd��Ze
dd��Ze
dd	��Z
eejd
dd�e
d/dd���Zeejddd�e
d0dd���Zejjjejj�eejdd�e
d1dd����Zejjejdd�dd��Zejjjejj�eejdd�e
d2�fdd�	���Zeejjdd�e
d3dd ���Zeejjdd�e
d4d!d"���Zeejj�e
d5d#d$���Zejjejjdd�e
d%d&���Z eejj�e
d6d'd(���Z!ejjejjdd�e
d)d*���Z"eejjdd�e
d7d+d,���Z#ejjejjdd�e
d-d.���Z$�Z%S)8�FirewallDConfigPolicyTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.policy.%d)
�superr�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_POLICY)�selfrZconfZpolicyr�args�kwargs)�	__class__��#/usr/lib/python3.6/config_policy.pyrs

zFirewallDConfigPolicy.__init__cCsdS)Nr)rrrr�__del__(szFirewallDConfigPolicy.__del__cCs|j�dS)N)Zremove_from_connection)rrrr�
unregister,sz FirewallDConfigPolicy.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrrr rZBooleanr!r"�
exceptions�
DBusException)r�
property_namerrr�
_get_property4sz#FirewallDConfigPolicy._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrrr$r%r')r�interface_namer&�senderrrr�GetEs


zFirewallDConfigPolicy.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existrr rr!r"Zsv)�	signature)rr rr!r")rr+rr,rrrrr$r%r'Z
Dictionary)rr-r.�ret�xrrr�GetAllVs

zFirewallDConfigPolicy.GetAllZssv)r)cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr+rr,rr�accessCheckrrrr$r%)rr-r&Z	new_valuer.rrr�Setgs



zFirewallDConfigPolicy.Setzsa{sv}as)r1cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr+rr,r)rr-Zchanged_propertiesZinvalidated_propertiesrrr�PropertiesChanged{s


z'FirewallDConfigPolicy.PropertiesChanged)r*cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rr
r�
IntrospectrrZget_busrrrr)rr.�data)rrrr8�s

z FirewallDConfigPolicy.IntrospectcCs tjd|j�|jj|j�}|S)z get settings for policy
        z%s.getSettings())rr,rrZget_policy_object_config_dictr)rr.�settingsrrr�getSettings�sz!FirewallDConfigPolicy.getSettingscCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)z#update settings for policy
        z%s.update('...')N)rrr,rrr5rZset_policy_object_config_dictr�Updatedr)rr:r.rrr�update�s
zFirewallDConfigPolicy.updatecCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z1load default settings for builtin policy
        z%s.loadDefaults()N)
rr,rrr5rZload_policy_object_defaultsrr<r)rr.rrr�loadDefaults�sz"FirewallDConfigPolicy.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr,r)rrrrrr<�szFirewallDConfigPolicy.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove policy
        z%s.removePolicy()N)	rr,rrr5rZremove_policy_objectrZremovePolicy)rr.rrr�remove�szFirewallDConfigPolicy.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr,r)rrrrr�Removed�szFirewallDConfigPolicy.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename policy
        z%s.rename('%s')N)rr+rr,rrr5rZrename_policy_objectr�Renamed)rrr.rrr�rename�s

zFirewallDConfigPolicy.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr,r)rrrrrrA�szFirewallDConfigPolicy.Renamed)N)N)N)N)N)N)N)N)N)&�__name__�
__module__�__qualname__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredrrr	rrr'r
ZPROPERTIES_IFACEr/r4�slipZpolkitZrequire_authr6�service�signalr7ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr8rr;r=r>r<r?r@rBrA�
__classcell__rr)rrrs^
		

	r)Z
gi.repositoryr�sys�modulesrZdbus.serviceZ	slip.dbusrFZslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.loggerrZfirewall.server.decoratorsrr	r
rGZObjectrrrrr�<module>s
server/__pycache__/decorators.cpython-36.opt-1.pyc000064400000004023150351351720016015 0ustar003

��go�@s�dZddddgZddlZddlZddlZddlmZddlmZdd	lm	Z	dd
l
mZddlmZddl
mZGd
d�dej�Zedd��Zedd��Zdd�ZdS)z>This module contains decorators for use with and without D-Bus�FirewallDBusException�handle_exceptions�dbus_handle_exceptions�dbus_service_method�N)�
DBusException)�	decorator)�config)�
FirewallError)�errors)�logc@seZdZdZdejjZdS)rz%s.ExceptionN)�__name__�
__module__�__qualname__�__doc__r�dbusZDBUS_INTERFACEZ_dbus_error_name�rr� /usr/lib/python3.6/decorators.pyr+scOsdy
|||�Stk
rD}ztjtj��tj|�WYdd}~Xntk
r^tj�YnXdS)zTDecorator to handle exceptions and log them. Used if not conneced
    to D-Bus.
    N)r	r�debug1�	traceback�
format_exc�error�	Exception�	exception)�func�args�kwargsrrrrr/s
cOs�y
|||�Stk
r�}zdtjt|��}|tjtjtjtjgkrRtj	t|��ntj
tj��tj
t|��tt|���WYdd}~XnZtk
r�}z
|�WYdd}~Xn6tk
r�}ztj�tt|���WYdd}~XnXdS)z�Decorator to handle exceptions, log and report them into D-Bus

    :Raises DBusException: on a firewall error code problems.
    N)r	�get_code�strr
ZALREADY_ENABLEDZNOT_ENABLEDZZONE_ALREADY_SETZALREADY_SETrZwarningrrrrrrrr)rrrr�codeZexrrrr<s

cOs|jdd�tjj||�S)zAdd sender argument for D-BusZsender_keywordZsender)�
setdefaultrZservice�method)rrrrrrTs)r�__all__rZdbus.servicerZdbus.exceptionsrrZfirewallrZfirewall.errorsr	r
Zfirewall.core.loggerrrrrrrrrr�<module>s
server/__pycache__/config_icmptype.cpython-36.opt-1.pyc000064400000024677150351351720017050 0ustar003

��gS:�@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZddlmZmZmZdd	l	mZdd
lmZGdd�dejjj�ZdS)
�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�IcmpType)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�errors)�
FirewallErrorcsHeZdZdZdZejjZe	�fdd��Z
edd��Zedd��Z
ed	d
��Zeejddd
�edHdd���Zeejddd
�edIdd���Zejjjejj�eejdd�edJdd����Zejjejdd�dd��Zejjjejj�eejdd�edK�fdd�	���Zeejjejd�edLd d!���Z eejjejd�edMd"d#���Z!eejj�edNd$d%���Z"ejjejjdd�ed&d'���Z#eejj�edOd(d)���Z$ejjejjdd�ed*d+���Z%eejjdd�edPd,d-���Z&ejjejjdd�ed.d/���Z'eejjdd�edQd0d1���Z(eejjdd�edRd2d3���Z)eejjdd�edSd4d5���Z*eejjdd�edTd6d7���Z+eejjdd�edUd8d9���Z,eejjdd�edVd:d;���Z-eejjd<d�edWd=d>���Z.eejjd<d�edXd?d@���Z/eejjdd�edYdAdB���Z0eejjdd�edZdCdD���Z1eejjddEd
�ed[dFdG���Z2�Z3S)\�FirewallDConfigIcmpTypezFirewallD main classTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.icmptype.%d)
�superr�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_ICMPTYPE)�selfrZconfZicmptyper�args�kwargs)�	__class__��%/usr/lib/python3.6/config_icmptype.pyr8s

z FirewallDConfigIcmpType.__init__cCsdS)Nr)rrrr�__del__EszFirewallDConfigIcmpType.__del__cCs|j�dS)N)Zremove_from_connection)rrrr�
unregisterIsz"FirewallDConfigIcmpType.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrr"r#rZBooleanr$r%�
exceptions�
DBusException)r�
property_namerrr�
_get_propertyQsz%FirewallDConfigIcmpType._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrrr'r(r*)r�interface_namer)�senderrrr�Getbs


zFirewallDConfigIcmpType.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existr"r#rr$r%Zsv)�	signature)r"r#rr$r%)rr.rr/rrrrr'r(r*Z
Dictionary)rr0r1�ret�xrrr�GetAllss

zFirewallDConfigIcmpType.GetAllZssv)r,cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr.rr/rr�accessCheckrrrr'r()rr0r)Z	new_valuer1rrr�Set�s



zFirewallDConfigIcmpType.Setzsa{sv}as)r4cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr.rr/r)rr0Zchanged_propertiesZinvalidated_propertiesrrr�PropertiesChanged�s


z)FirewallDConfigIcmpType.PropertiesChanged)r-cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rrr�
IntrospectrrZget_busrrrr)rr1�data)rrrr;�s

z"FirewallDConfigIcmpType.IntrospectcCstjd|j�|jj|j�S)z"get settings for icmptype
        z%s.getSettings())rr/rrZget_icmptype_configr)rr1rrr�getSettings�sz#FirewallDConfigIcmpType.getSettingscCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)z%update settings for icmptype
        z%s.update('...')N)rrr/rrr8rZset_icmptype_configr�Updatedr")r�settingsr1rrr�update�s
zFirewallDConfigIcmpType.updatecCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z3load default settings for builtin icmptype
        z%s.loadDefaults()N)
rr/rrr8rZload_icmptype_defaultsrr>r")rr1rrr�loadDefaults�sz$FirewallDConfigIcmpType.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr/r)rr"rrrr>�szFirewallDConfigIcmpType.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove icmptype
        z%s.removeIcmpType()N)	rr/rrr8rZremove_icmptyperZremoveIcmpType)rr1rrr�remove�szFirewallDConfigIcmpType.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr/r)rr"rrr�Removed�szFirewallDConfigIcmpType.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename icmptype
        z%s.rename('%s')N)rr.rr/rrr8rZrename_icmptyper�Renamed)rr"r1rrr�rename�s

zFirewallDConfigIcmpType.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr/r)rr"rrrrD�szFirewallDConfigIcmpType.RenamedcCstjd|j�|j�dS)Nz%s.getVersion()r)rr/rr=)rr1rrr�
getVersion�sz"FirewallDConfigIcmpType.getVersioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setVersion('%s')r)
rr.rr/rrr8�listr=r@)r�versionr1r?rrr�
setVersions
z"FirewallDConfigIcmpType.setVersioncCstjd|j�|j�dS)Nz
%s.getShort()r)rr/rr=)rr1rrr�getShortsz FirewallDConfigIcmpType.getShortcCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setShort('%s')r)
rr.rr/rrr8rGr=r@)rZshortr1r?rrr�setShorts
z FirewallDConfigIcmpType.setShortcCstjd|j�|j�dS)Nz%s.getDescription()�)rr/rr=)rr1rrr�getDescription$sz&FirewallDConfigIcmpType.getDescriptioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setDescription('%s')rL)
rr.rr/rrr8rGr=r@)r�descriptionr1r?rrr�setDescription+s

z&FirewallDConfigIcmpType.setDescription�ascCstjd|j�t|j�d�S)Nz%s.getDestinations()�)rr/r�sortedr=)rr1rrr�getDestinations9sz'FirewallDConfigIcmpType.getDestinationscCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setDestinations('[%s]')�,rQ)
rrGrr/r�joinrr8r=r@)rZdestinationsr1r?rrr�setDestinations@s

z'FirewallDConfigIcmpType.setDestinationscCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addDestination('%s')rQ)rr.rr/rrr8rGr=r
rZALREADY_ENABLED�appendr@)r�destinationr1r?rrr�addDestinationLs

z&FirewallDConfigIcmpType.addDestinationcCs�t|t�}tjd|j|�|jj|�t|j��}|drd||dkrTt	t
j|��q�|dj|�ntt
ddg�t
|g��|d<|j|�dS)Nz%s.removeDestination('%s')rQZipv4Zipv6)rr.rr/rrr8rGr=r
rZNOT_ENABLEDrB�setr@)rrXr1r?rrr�removeDestinationZs

z)FirewallDConfigIcmpType.removeDestination�bcCs8t|t�}tjd|j|�|j�}|dp6||dkS)Nz%s.queryDestination('%s')rQ)rr.rr/rr=)rrXr1r?rrr�queryDestinationms


z(FirewallDConfigIcmpType.queryDestination)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)4�__name__�
__module__�__qualname__�__doc__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredr	rr
r r!r*rZPROPERTIES_IFACEr2r7�slipZpolkitZrequire_authr9�service�signalr:ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr;rrZDBUS_SIGNATUREr=r@rAr>rBrCrErDrFrIrJrKrMrOrSrVrYr[r]�
__classcell__rr)rrr0s�
		

	

	r)Z
gi.repositoryr�sys�modulesrZdbus.serviceZ	slip.dbusrbZslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.io.icmptyperZfirewall.core.loggerrZfirewall.server.decoratorsr	r
rrZfirewall.errorsr
rcZObjectrrrrr�<module>s
server/__pycache__/firewalld.cpython-36.opt-1.pyc000064400000217455150351351720015640 0ustar003

��gb��@sVdgZddlmZmZddlZeejd<ddlZddlZddlZddl	Z
ddlZ
ddlm
Z
ddlmZddlmZddlmZdd	lmZdd
lmZmZmZmZddlmZddlmZmZm Z m!Z!m"Z"m#Z#m$Z$dd
l%m&Z&ddl'm(Z(ddl)m*Z*ddl+m,Z,ddl-m.Z.m/Z/m0Z0ddl1m2Z2ddlm3Z3ddl4m5Z5Gdd�de
jj6j7�Z8dS)�	FirewallD�)�GLib�GObjectNZgobject)�config)�Firewall)�	Rich_Rule)�log)�FirewallClientZoneSettings)�dbus_handle_exceptions�dbus_service_method�handle_exceptions�FirewallDBusException)�FirewallDConfig)�dbus_to_python�command_of_sender�context_of_sender�
uid_of_sender�user_of_uid�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�check_config)�IPSet)�IcmpType)�Helper)�nm_get_bus_name�nm_get_connection_of_interface�nm_set_zone_of_connection)�ifcfg_set_zone_of_interface)�errors)�
FirewallErrorcs�"eZdZdZdZejjZe	�fdd��Z
dd�Ze	dd��Ze	d	d
��Z
edd��Zed
d��Zedd��Zedd��Zedd��Zeejddd�e�d�dd���Zeejddd�e�d�dd���Zejjjejj�eejdd �e�d�d!d"����Zejjejd#d$�d%d&��Zejjjejj�eej dd'�e�d��fd(d)�	���Z!ejjjejj�eejj"d*d*d�e�d�d+d,����Z#ejjjejj�eejj"d*d*d�e�d�d-d.����Z$ejjejj"�ed/d0���Z%ejjjejj�eejj"d*d*d�e�d�d1d2����Z&ejjjejj�eejj"d*d*d�e�d�d3d4����Z'ejjjejj(�eejj)d*d*d�e�d�d5d6����Z*ejjjejj(�eejj)d*d*d�e�d�d7d8����Z+ejjjejj,�eejj)d*d9d�e�d�d:d;����Z-ejjejj)d*d$�ed<d=���Z.ejjejj)d*d$�ed>d?���Z/ejjjejj(�eejj)dd*d�e�d�d@dA����Z0ejjjejj(�eejj)dd*d�e�d�dBdC����Z1ejjjejj,�eejj)dd9d�e�d�dDdE����Z2ejjjejj,�eejj)d*dFd�e�d�dGdH����Z3ejjejj)dd$�edIdJ���Z4ejjejj)dd$�edKdL���Z5ejjjejj(�eejj)dMd*d�e�d�dNdO����Z6ejjjejj(�eejj)dMd*d�e�d�dPdQ����Z7ejjjejj,�eejj)dMd9d�e�d�dRdS����Z8ejjjejj,�eejj)d*dTd�e�d�dUdV����Z9ejjejj)dMd$�edWdX���Z:ejjejj)dMd$�edYdZ���Z;ejjjejj(�eejj)dd*d�e�d�d[d\����Z<ejjjejj(�eejj)dd*d�e�d�d]d^����Z=ejjjejj,�eejj)dd9d�e�d�d_d`����Z>ejjjejj,�eejj)d*dFd�e�d�dadb����Z?ejjejj)dd$�edcdd���Z@ejjejj)dd$�ededf���ZAejjjejj(�eejj)dd*d�e�d�dgdh����ZBejjjejj(�eejj)dd*d�e�d�didj����ZCejjjejj,�eejj)dd9d�e�d�dkdl����ZDejjjejj,�eejj)d*dFd�e�d�dmdn����ZEejjejj)dd$�edodp���ZFejjejj)dd$�edqdr���ZGejjjejj�eejj"d*d*d�e�d�dsdt����ZHejjjejj�eejj"d*d*d�e�d�dudv����ZIejjjejj�eejj"d*d9d�e�d�dwdx����ZJejjejj"d*d$�edydz���ZKejjejj"d*d$�ed{d|���ZLejjjejjM�eejj"dd}d�e�d�d~d����ZNejjjejjM�eejjOddd�e�d�d�d�����ZPejjjejjM�eejjOd�d �e�d�d�d�����ZQejjejjOd�d$�ed�d����ZRejjjejjM�eejjSddd�e�d�d�d�����ZTejjjejjM�eejjSd�d �e�d�d�d�����ZUejjejjSd�d$�ed�d����ZVejjjejj�eejj"d*dFd�e�d�d�d�����ZWejjjejjM�eejj"dd�d�e�d�d�d�����ZXejjjejjM�eejj"ddd�e�d�d�d�����ZYejjjejj�eejj"d*dFd�e�d�d�d�����ZZejjjejjM�eejj"de[j\d�e�d�d�d�����Z]ejjjejjM�eejj"d*dd�e�d�d�d�����Z^ejjjejj�eejj"dd*d�e�d�d�d�����Z_ejjejj"dd$�ed�d����Z`ejjjejjM�eejj"d*dd�e�d�d�d�����Zaejjjejj�eejj"dd*d�e�d�d�d�����Zbejjejj"dd$�ed�d����Zcejjjejj�eejj"d*dd�e�d�d�d�����Zdejjjejj�eejj"dd*d�e�d�d�d�����Zeejjejj"dd$�ed�d����Zfejjjejj�eejjSd*dFd�e�d�d�d�����Zgejjjejj�eejjSd*d�d�e�d�d�d�����Zhejjjejj�eejjOd*dFd�e�d�d�d�����Ziejjjejj�eejjOd*d�d�e�d�d�d�����Zjejjjejj�eejjOddd�e�d�d�d�����Zkejjjejj�eejjOddd�e�d�d�d�����ZlejjjejjM�eejjOdd9d�e�d�d�d�����Zmejjjejj�eejjOddd�e�d�d�d�����Znejjjejj�eejjOddd�e�d�d�d�����Zoejjjejj�eejjOddd�e�d�d�d�����Zpejjjejj�eejjOddd�e�d�d�d�����ZqejjjejjM�eejjOdd9d�e�d�d�d„���ZrejjjejjM�eejjOddFd�e�d�d�dĄ���ZsejjejjOdd$�ed�dƄ��ZtejjejjOdd$�ed�dȄ��ZuejjejjOdd$�ed�dʄ��ZvejjejjOdd$�ed�d̄��Zwejjjejj�eejjOddd�e�d�d�d΄���Zxejjjejj�eejjOddd�e�d�d�dЄ���Zyejjjejj�eejjOddd�e�d�d�d҄���ZzejjjejjM�eejjOdd9d�e�d�d�dԄ���Z{ejjjejjM�eejjOddFd�e�d�d�dք���Z|ejjejjOdd$�ed�d؄��Z}ejjejjOdd$�ed�dڄ��Z~ejjejjOdd$�ed�d܄��Zed�dބ�Z�ejjjejj�eejjOd�dd�e�d�d�d����Z�ejjjejj�eejjOddd�e�d�d�d����Z�ejjjejjM�eejjOdd9d�e�d�d�d����Z�ejjjejjM�eejjOddFd�e�d�d�d����Z�ejjejjOd�d$�ed�d���Z�ejjejjOdd$�ed�d���Z�ed�d��Z�ejjjejj�eejjOd�dd�e�d�d�d����Z�ejjjejj�eejjOddd�e�d�d�d����Z�ejjjejjM�eejjOdd9d�e�d�d�d����Z�ejjjejjM�eejjOddFd�e�d�d�d�����Z�ejjejjOd�d$�ed�d����Z�ejjejjOdd$�ed�d����Z�ed�d���Z�ejjjejj�eejjOd�dd�e�d�d�d�����Z�ejjjejj�eejjOd�dd�e�d��d�d����Z�ejjjejjM�eejjOd�d9d�e�d��d�d����Z�ejjjejjM�eejjOd�dd�e�d��d�d����Z�ejjejjOd�d$�e�d��d�d	���Z�ejjejjOd�d$�e�d
�d���Z�e�d�d
��Z�ejjjejj�eejjOd�dd�e�d��d�d����Z�ejjjejj�eejjOddd�e�d��d�d����Z�ejjjejjM�eejjOdd9d�e�d��d�d����Z�ejjjejjM�eejjOddFd�e�d��d�d����Z�ejjejjOd�d$�e�d��d�d���Z�ejjejjOdd$�e�d�d���Z�e�d�d��Z�ejjjejj�eejjOd�dd�e�d��d�d����Z�ejjjejj�eejjOd�dd�e�d�d�d����Z�ejjjejjM�eejjOd�d9d�e�d�d �d!����Z�ejjjejjM�eejjOd�dd�e�d�d"�d#����Z�ejjejjOd�d$�e�d�d$�d%���Z�ejjejjOd�d$�e�d&�d'���Z�e�d(�d)��Z�ejjjejj�eejjO�d*dd�e�d�d+�d,����Z�ejjjejj�eejjOddd�e�d�d-�d.����Z�ejjjejjM�eejjOdd9d�e�d�d/�d0����Z�ejjejjO�d*d$�e�d�d1�d2���Z�ejjejjOdd$�e�d3�d4���Z�e�d5�d6��Z�ejjjejj�eejjO�d7dd�e�d�d8�d9����Z�ejjjejj�eejjO�d:dd�e�d	�d;�d<����Z�ejjjejjM�eejjO�d:d9d�e�d
�d=�d>����Z�ejjjejjM�eejjOd�dd�e�d�d?�d@����Z�ejjejjO�d7d$�e�d�dA�dB���Z�ejjejjO�d:d$�e�dC�dD���Z�e�dE�dF��Z�ejjjejj�eejjOd�dd�e�d
�dG�dH����Z�ejjjejj�eejjOddd�e�d�dI�dJ����Z�ejjjejjM�eejjOdd9d�e�d�dK�dL����Z�ejjjejjM�eejjOddFd�e�d�dM�dN����Z�ejjejjOd�d$�e�d�dO�dP���Z�ejjejjOdd$�e�dQ�dR���Z�ejjjejj�eejjOddd�e�d�dS�dT����Z�ejjjejj�eejjOddd�e�d�dU�dV����Z�ejjjejjM�eejjOdd9d�e�d�dW�dX����Z�ejjejjOdd$�e�dY�dZ���Z�ejjejjOdd$�e�d[�d\���Z�ejjjejj��eejj�d�d*d�e�d�d]�d^����Z�ejjjejj��eejj�d�d*d�e�d�d_�d`����Z�ejjjejj��eejj�d�d9d�e�d�da�db����Z�ejjjejj��eejj�ddFd�e�d�dc�dd����Z�ejjjejj��eejj�d*�ded�e�d�df�dg����Z�ejjejj�d�d$�e�dh�di���Z�ejjejj�d�d$�e�dj�dk���Z�ejjjejj��eejj��dld*d�e�d�dm�dn����Z�ejjjejj��eejj��dld*d�e�d�do�dp����Z�ejjjejj��eejj�d�d*d�e�d�dq�dr����Z�ejjjejj��eejj��dld9d�e�d�ds�dt����Z�ejjjejj��eejj�d��dud�e�d�dv�dw����Z�ejjjejj��eejj�d*�dxd�e�d�dy�dz����Z�ejjejj��dld$�e�d{�d|���Z�ejjejj��dld$�e�d}�d~���Z�ejjjejj��eejj��ddd�e�d �d��d�����Z�ejjjejj��eejj��dd*d�e�d!�d��d�����Z�ejjjejj��eejj��dd*d�e�d"�d��d�����Z�ejjjejj��eejj��dd9d�e�d#�d��d�����Z�ejjjejj��eejj�d*�d�d�e�d$�d��d�����Z�ejjjejj��eejj�d*d*d�e�d%�d��d�����Z�ejjjejj��eejj�d�dd�e�d&�d��d�����Z�ejjejj��dd$�e�d��d����Z�ejjejj��dd$�e�d��d����Z�ejjjejj׃eejj"d*d*d�e�d'�d��d�����Z�ejjjejj�eejj�dd9d�e�d(�d��d�����Z�ejjjejj�eejj�d*dFd�e�d)�d��d�����Z�ejjjejjM�eejj�de�j\d�e�d*�d��d�����Z�ejjjejj�eejj�dd*d�e�d+�d��d�����Z�ejjjejj�eejj�dd*d�e�d,�d��d�����Z�ejjjejj�eejj�dd9d�e�d-�d��d�����Z�ejjjejj�eejj�ddFd�e�d.�d��d�����Z�ejjjejj�eejjِdd �e�d/�d��d�����Z�ejjejj�dd$�e�d��d����Z�ejjejj�dd$�e�d��d����Z�ejjjejj�eejj"d*dFd�e�d0�d��d�����Z�ejjjejjM�eejj"de�j\d�e�d1�d��d�����Z�Z�S(2rzFirewallD main classTcs`tt|�j||�t�|_|d|_|d|_|j�t|t	j
j�t|jj	|jt	j
j
�|_	dS)Nr�)�superr�__init__r�fw�busname�path�startrr�dbus�DBUS_INTERFACErZDBUS_PATH_CONFIG)�self�args�kwargs)�	__class__��/usr/lib/python3.6/firewalld.pyr"Is

zFirewallD.__init__cCs|j�dS)N)�stop)r)r-r-r.�__del__TszFirewallD.__del__cCstjd�i|_|jj�S)Nzstart())r�debug1�	_timeoutsr#r&)r)r-r-r.r&Ws
zFirewallD.startcCstjd�|jj�S)Nzstop())rr1r#r/)r)r-r-r.r/_s
zFirewallD.stopcCs�|jjj�r�|dkr"tjd�dStj�}t||�}|jjjd|�rHdSt	||�}|jjjd|�rfdSt
|�}|jjjd|�r�dSt||�}|jjjd|�r�dStt
jd��dS)Nz&Lockdown not possible, sender not set.�context�uid�user�commandzlockdown is enabled)r#�policies�query_lockdownr�errorr'Z	SystemBusrZaccess_checkrrrrrZ
ACCESS_DENIED)r)�senderZbusr3r4r5r6r-r-r.�accessCheckhs$



zFirewallD.accessCheckcCs&||jkri|j|<||j||<dS)N)r2)r)�zone�x�tagr-r-r.�
addTimeouts

zFirewallD.addTimeoutcCs<||jkr8||j|kr8tj|j||�|j||=dS)N)r2r�
source_remove)r)r<r=r-r-r.�
removeTimeout�szFirewallD.removeTimeoutcCsTxD|jD]:}x&|j|D]}tj|j||�qW|j|j�qW|jj�dS)N)r2rr@�clear)r)r<r=r-r-r.�cleanup_timeouts�s
zFirewallD.cleanup_timeoutscCsd|dkrtjtj�S|dkr6tjdtjjtjjf�S|dkrNtj|jj��S|dkrhtj|jj	d��S|dkr�tj
|jjd�S|d	kr�tj|jj	d
��S|dkr�tj|jj�S|dkr�tj
|jj
d�S|d
kr�tj|jj�S|dk�r�tj|jj�S|dk�rtj
|jjd�S|dk�r$tjd�S|dk�r:tjid�S|dk�rPtjid�Stjjd|��dS)N�version�interface_versionz%d.%d�state�IPv4�ipv4�
IPv4ICMPTypes�s�IPv6�ipv6�
IPv6_rpfilter�
IPv6ICMPTypes�BRIDGEr�
IPSetTypes�nf_conntrack_helper_settingF�nf_conntrack_helpers�sas�nf_nat_helperszDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r'�Stringr�VERSIONZDBUS_INTERFACE_VERSIONZDBUS_INTERFACE_REVISIONr#Z	get_stateZBooleanZis_ipv_enabledZArrayZipv4_supported_icmp_typesZipv6_rpfilter_enabledZipv6_supported_icmp_typesZebtables_enabledZ
ipset_enabledZipset_supported_types�
Dictionary�
exceptions�
DBusException)r)Zpropr-r-r.�
_get_property�s@





zFirewallD._get_propertyZss�v)�in_signature�
out_signatureNcCs~t|t�}t|t�}tjd||�|tjjkr8|j|�S|tjjtjj	tjj
tjjgkrjtjj
d|��ntjj
d|��dS)NzGet('%s', '%s')zDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not existzJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strrr1rr'r(rZ�DBUS_INTERFACE_ZONE�DBUS_INTERFACE_DIRECT�DBUS_INTERFACE_POLICIES�DBUS_INTERFACE_IPSETrXrY)r)�interface_name�
property_namer:r-r-r.�Get�s



z
FirewallD.GetrJza{sv}cCs�t|t�}tjd|�i}|tjjkrDxNdD]}|j|�||<q,Wn2|tjjtjj	tjj
tjjgkrfntjj
d|��tj|dd�S)NzGetAll('%s')rDrErFrGrKrMrOrrPrQrRrTrIrNzJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existZsv)�	signature)rDrErFrGrKrMrOrrPrQrRrTrIrN)rr^rr1rr'r(rZr_r`rarbrXrYrW)r)rcr:�retr=r-r-r.�GetAll�s&
zFirewallD.GetAllZssv)r\cCs�t|t�}t|t�}t|�}tjd|||�|j|�|tjjkrn|dkr\tjj	d|��q�tjj	d|��nB|tjj
tjjtjjtjj
gkr�tjj	d|��ntjj	d|��dS)NzSet('%s', '%s', '%s')rDrErFrGrKrMrOrrPrQrRrTrIrNzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-onlyzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not existzJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)rDrErFrGrKrMrOrrPrQrRrTrIrN)rr^rr1r;rr'r(rXrYr_r`rarb)r)rcrdZ	new_valuer:r-r-r.�Set�s:






z
FirewallD.Setzsa{sv}as)rfcCs.t|t�}t|�}t|�}tjd|||�dS)Nz#PropertiesChanged('%s', '%s', '%s'))rr^rr1)r)rcZchanged_propertiesZinvalidated_propertiesr-r-r.�PropertiesChangeds

zFirewallD.PropertiesChanged)r]cs4tjd�tt|�j|j|jj��}t||t	j
j�S)NzIntrospect())rZdebug2r!r�
Introspectr%r$Zget_busrrr'r()r)r:�data)r,r-r.rk&s

zFirewallD.Introspect�cCs*tjd�|jj�|jj�|j�dS)z#Reload the firewall rules.
        zreload()N)rr1r#�reloadr�Reloaded)r)r:r-r-r.rn4s


zFirewallD.reloadcCs,tjd�|jjd�|jj�|j�dS)z�Completely reload the firewall.

        Completely reload the firewall: Stops firewall, unloads modules and 
        starts the firewall again.
        zcompleteReload()TN)rr1r#rnrro)r)r:r-r-r.�completeReloadCs


zFirewallD.completeReloadcCstjd�dS)Nz
Reloaded())rr1)r)r-r-r.roSszFirewallD.ReloadedcCstjd�t|j�dS)z&Check permanent configuration
        zcheckPermanentConfig()N)rr1rr#)r)r:r-r-r.�checkPermanentConfigXs
zFirewallD.checkPermanentConfigc
Cs�tjd�d}|jj�}x�|jjj�D]�}|j|�}yj||kr�|jj|�}|j	�|krptjd|�|j
|�q�tjd|�ntjd|�|jj||�Wq&tk
r�}ztj
d||f�d}WYdd}~Xq&Xq&W|jj�}x�|jjj�D]�}|j|�}yn||k�rR|jj|�}|j	�|k�rBtjd	|�|j
|�ntjd
|�ntjd|�|jj||�Wq�tk
�r�}ztj
d||f�d}WYdd}~Xq�Xq�W|jj�}x�|jjj�D]�}yx|j|�}||k�r&|jj|�}|j	�|k�rtjd
|�|j
|�ntjd|�ntjd|�|jj||�Wn:tk
�r~}ztj
d||f�d}WYdd}~XnX�q�W|jj�}t�}�x�|jjj�D�]�}|j|�}t|�}	|dk	�r~d}
xH|	j �D]<}|jjj!||�|k�r�tjd||f�|	j"|�d}
�q�WxV|	j �D]J}y,t#|�}|�rNt$||��rN|	j"|�d}
Wntk
�rfYnX�q W|
�r~~|	j%�}x|	j �D]}t&||��q�WyP||k�r�|jj'|�}tjd|�|j(|�ntjd|�|jj)||�Wn:tk
�r&}ztj
d||f�d}WYdd}~XnX�q�W|jj*�}x�|jj+j,�D]�}|j-|�}yB||k�rx|jj.|�}|j
|�ntjd|�|jj/||�Wn:tk
�r�}ztj
d||f�d}WYdd}~XnX�qFW|jj0�}x�|jj1j2�D]�}|j3|�}yn||k�rN|jj4|�}|j	�|k�r>tjd|�|j
|�ntjd|�ntjd|�|jj5||�Wn:tk
�r�}ztj
d||f�d}WYdd}~XnX�q�W|jj6j7�|jj6j8�|jj6j9�f}y6|jj	�|k�r�tjd�|jj
|�n
tjd�Wn6tk
�r<}ztj
d|�d}WYdd}~XnX|jj:j;j<�}y6|jj	�|k�rvtjd�|jj=|�n
tjd�Wn6tk
�r�}ztj
d |�d}WYdd}~XnX|�r�t>t?j@��dS)!z-Make runtime configuration permanent
        zcopyRuntimeToPermanent()FzCopying service '%s' settingsz$Service '%s' is identical, ignoring.zCreating service '%s'z/Runtime To Permanent failed on service '%s': %sTNzCopying icmptype '%s' settingsz%IcmpType '%s' is identical, ignoring.zCreating icmptype '%s'z0Runtime To Permanent failed on icmptype '%s': %szCopying ipset '%s' settingsz"IPSet '%s' is identical, ignoring.zCreating ipset '%s'z-Runtime To Permanent failed on ipset '%s': %szEZone '%s': interface binding for '%s' has been added by NM, ignoring.zCopying zone '%s' settingszCreating zone '%s'z,Runtime To Permanent failed on zone '%s': %szCreating policy '%s'z.Runtime To Permanent failed on policy '%s': %szCopying helper '%s' settingsz#Helper '%s' is identical, ignoring.zCreating helper '%s'z.Runtime To Permanent failed on helper '%s': %szCopying direct configurationz,Direct configuration is identical, ignoring.z7Runtime To Permanent failed on direct configuration: %szCopying policies configurationz.Policies configuration is identical, ignoring.z9Runtime To Permanent failed on policies configuration: %s)Arr1rZgetServiceNamesr#�service�get_services�getServiceSettingsZgetServiceByNameZgetSettings�update�
addService�	Exception�warningZgetIcmpTypeNames�icmptype�
get_icmptypes�getIcmpTypeSettingsZgetIcmpTypeByNameZaddIcmpTypeZ
getIPSetNames�ipset�
get_ipsets�getIPSetSettingsZgetIPSetByNameZaddIPSetZgetZoneNamesrr<�	get_zones�getZoneSettings2r	�
getInterfacesZinterface_get_sender�removeInterfacerrZgetSettingsDictrZ
getZoneByNameZupdate2ZaddZone2ZgetPolicyNames�policy�"get_policies_not_derived_from_zone�getPolicySettingsZgetPolicyByNameZ	addPolicyZgetHelperNames�helper�get_helpers�getHelperSettingsZgetHelperByNameZ	addHelper�direct�get_all_chains�
get_all_rules�get_all_passthroughsr7�lockdown_whitelist�
export_configZsetLockdownWhitelistrrZRT_TO_PERM_FAILED)
r)r:r9Zconfig_names�nameZconfZconf_obj�eZnm_bus_name�settingsZchanged�	interfaceZ
connectionr-r-r.�runtimeToPermanentds$


























zFirewallD.runtimeToPermanentcCs,tjd�|j|�|jjj�|j�dS)z!Enable lockdown policies
        zpolicies.enableLockdown()N)rr1r;r#r7Zenable_lockdown�LockdownEnabled)r)r:r-r-r.�enableLockdown2s

zFirewallD.enableLockdowncCs,tjd�|j|�|jjj�|j�dS)z"Disable lockdown policies
        zpolicies.disableLockdown()N)rr1r;r#r7Zdisable_lockdown�LockdownDisabled)r)r:r-r-r.�disableLockdown>s

zFirewallD.disableLockdown�bcCstjd�|jjj�S)z+Retuns True if lockdown is enabled
        zpolicies.queryLockdown())rr1r#r7r8)r)r:r-r-r.�
queryLockdownJs
zFirewallD.queryLockdowncCstjd�dS)NzLockdownEnabled())rr1)r)r-r-r.r�UszFirewallD.LockdownEnabledcCstjd�dS)NzLockdownDisabled())rr1)r)r-r-r.r�ZszFirewallD.LockdownDisabledcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zAdd lockdown command
        z*policies.addLockdownWhitelistCommand('%s')N)
rr^rr1r;r#r7r�Zadd_command�LockdownWhitelistCommandAdded)r)r6r:r-r-r.�addLockdownWhitelistCommandcs


z%FirewallD.addLockdownWhitelistCommandcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)z Remove lockdown command
        z-policies.removeLockdownWhitelistCommand('%s')N)
rr^rr1r;r#r7r�Zremove_command�LockdownWhitelistCommandRemoved)r)r6r:r-r-r.�removeLockdownWhitelistCommandps


z(FirewallD.removeLockdownWhitelistCommandcCs(t|t�}tjd|�|jjjj|�S)zQuery lockdown command
        z,policies.queryLockdownWhitelistCommand('%s'))rr^rr1r#r7r�Zhas_command)r)r6r:r-r-r.�queryLockdownWhitelistCommand}s
z'FirewallD.queryLockdownWhitelistCommand�ascCstjd�|jjjj�S)zAdd lockdown command
        z'policies.getLockdownWhitelistCommands())rr1r#r7r�Zget_commands)r)r:r-r-r.�getLockdownWhitelistCommands�s
z&FirewallD.getLockdownWhitelistCommandscCstjd|�dS)Nz#LockdownWhitelistCommandAdded('%s'))rr1)r)r6r-r-r.r��sz'FirewallD.LockdownWhitelistCommandAddedcCstjd|�dS)Nz%LockdownWhitelistCommandRemoved('%s'))rr1)r)r6r-r-r.r��sz)FirewallD.LockdownWhitelistCommandRemoved�icCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zAdd lockdown uid
        z&policies.addLockdownWhitelistUid('%s')N)
r�intrr1r;r#r7r�Zadd_uid�LockdownWhitelistUidAdded)r)r4r:r-r-r.�addLockdownWhitelistUid�s


z!FirewallD.addLockdownWhitelistUidcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zRemove lockdown uid
        z)policies.removeLockdownWhitelistUid('%s')N)
rr�rr1r;r#r7r�Z
remove_uid�LockdownWhitelistUidRemoved)r)r4r:r-r-r.�removeLockdownWhitelistUid�s


z$FirewallD.removeLockdownWhitelistUidcCs(t|t�}tjd|�|jjjj|�S)zQuery lockdown uid
        z(policies.queryLockdownWhitelistUid('%s'))rr�rr1r#r7r�Zhas_uid)r)r4r:r-r-r.�queryLockdownWhitelistUid�s
z#FirewallD.queryLockdownWhitelistUidZaicCstjd�|jjjj�S)zAdd lockdown uid
        z#policies.getLockdownWhitelistUids())rr1r#r7r�Zget_uids)r)r:r-r-r.�getLockdownWhitelistUids�s
z"FirewallD.getLockdownWhitelistUidscCstjd|�dS)NzLockdownWhitelistUidAdded(%d))rr1)r)r4r-r-r.r��sz#FirewallD.LockdownWhitelistUidAddedcCstjd|�dS)NzLockdownWhitelistUidRemoved(%d))rr1)r)r4r-r-r.r��sz%FirewallD.LockdownWhitelistUidRemovedcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zAdd lockdown user
        z'policies.addLockdownWhitelistUser('%s')N)
rr^rr1r;r#r7r�Zadd_user�LockdownWhitelistUserAdded)r)r5r:r-r-r.�addLockdownWhitelistUser�s


z"FirewallD.addLockdownWhitelistUsercCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zRemove lockdown user
        z*policies.removeLockdownWhitelistUser('%s')N)
rr^rr1r;r#r7r�Zremove_user�LockdownWhitelistUserRemoved)r)r5r:r-r-r.�removeLockdownWhitelistUser�s


z%FirewallD.removeLockdownWhitelistUsercCs(t|t�}tjd|�|jjjj|�S)zQuery lockdown user
        z)policies.queryLockdownWhitelistUser('%s'))rr^rr1r#r7r�Zhas_user)r)r5r:r-r-r.�queryLockdownWhitelistUser�s
z$FirewallD.queryLockdownWhitelistUsercCstjd�|jjjj�S)zAdd lockdown user
        z$policies.getLockdownWhitelistUsers())rr1r#r7r�Z	get_users)r)r:r-r-r.�getLockdownWhitelistUserss
z#FirewallD.getLockdownWhitelistUserscCstjd|�dS)Nz LockdownWhitelistUserAdded('%s'))rr1)r)r5r-r-r.r�sz$FirewallD.LockdownWhitelistUserAddedcCstjd|�dS)Nz"LockdownWhitelistUserRemoved('%s'))rr1)r)r5r-r-r.r�sz&FirewallD.LockdownWhitelistUserRemovedcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zAdd lockdown context
        z*policies.addLockdownWhitelistContext('%s')N)
rr^rr1r;r#r7r�Zadd_context�LockdownWhitelistContextAdded)r)r3r:r-r-r.�addLockdownWhitelistContexts


z%FirewallD.addLockdownWhitelistContextcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)z Remove lockdown context
        z-policies.removeLockdownWhitelistContext('%s')N)
rr^rr1r;r#r7r�Zremove_context�LockdownWhitelistContextRemoved)r)r3r:r-r-r.�removeLockdownWhitelistContext's


z(FirewallD.removeLockdownWhitelistContextcCs(t|t�}tjd|�|jjjj|�S)zQuery lockdown context
        z,policies.queryLockdownWhitelistContext('%s'))rr^rr1r#r7r�Zhas_context)r)r3r:r-r-r.�queryLockdownWhitelistContext4s
z'FirewallD.queryLockdownWhitelistContextcCstjd�|jjjj�S)zAdd lockdown context
        z'policies.getLockdownWhitelistContexts())rr1r#r7r�Zget_contexts)r)r:r-r-r.�getLockdownWhitelistContexts@s
z&FirewallD.getLockdownWhitelistContextscCstjd|�dS)Nz#LockdownWhitelistContextAdded('%s'))rr1)r)r3r-r-r.r�Ksz'FirewallD.LockdownWhitelistContextAddedcCstjd|�dS)Nz%LockdownWhitelistContextRemoved('%s'))rr1)r)r3r-r-r.r�Psz)FirewallD.LockdownWhitelistContextRemovedcCs*tjd�|j|�|jj�|j�dS)znEnable panic mode.
        
        All ingoing and outgoing connections and packets will be blocked.
        zenablePanicMode()N)rr1r;r#Zenable_panic_mode�PanicModeEnabled)r)r:r-r-r.�enablePanicModeYs	


zFirewallD.enablePanicModecCs*tjd�|j|�|jj�|j�dS)z�Disable panic mode.

        Enables normal mode: Allowed ingoing and outgoing connections 
        will not be blocked anymore
        zdisablePanicMode()N)rr1r;r#Zdisable_panic_mode�PanicModeDisabled)r)r:r-r-r.�disablePanicModegs



zFirewallD.disablePanicModecCstjd�|jj�S)NzqueryPanicMode())rr1r#Zquery_panic_mode)r)r:r-r-r.�queryPanicModevs
zFirewallD.queryPanicModecCstjd�dS)NzPanicModeEnabled())rr1)r)r-r-r.r�szFirewallD.PanicModeEnabledcCstjd�dS)NzPanicModeDisabled())rr1)r)r-r-r.r��szFirewallD.PanicModeDisabledz&(sssbsasa(ss)asba(ssss)asasasasa(ss)b)cCs$t|t�}tjd|�|jjj|�S)NzgetZoneSettings(%s))rr^rr1r#r<Zget_config_with_settings)r)r<r:r-r-r.�getZoneSettings�s
zFirewallD.getZoneSettingscCs$t|t�}tjd|�|jjj|�S)NzgetZoneSettings2(%s))rr^rr1r#r<�get_config_with_settings_dict)r)r<r:r-r-r.r��s
zFirewallD.getZoneSettings2zsa{sv}cCsBt|t�}tjd|�|j|�|jjj|||�|j||�dS)NzsetZoneSettings2(%s))	rr^rr1r;r#r<�set_config_with_settings_dict�ZoneUpdated)r)r<r�r:r-r-r.�setZoneSettings2�s


zFirewallD.setZoneSettings2cCstjd||f�dS)Nzzone.ZoneUpdated('%s', '%s'))rr1)r)r<r�r-r-r.r��szFirewallD.ZoneUpdatedcCs$t|t�}tjd|�|jjj|�S)Nzpolicy.getPolicySettings(%s))rr^rr1r#r�r�)r)r�r:r-r-r.r��s
zFirewallD.getPolicySettingscCsBt|t�}tjd|�|j|�|jjj|||�|j||�dS)Nzpolicy.setPolicySettings(%s))	rr^rr1r;r#r�r��
PolicyUpdated)r)r�r�r:r-r-r.�setPolicySettings�s


zFirewallD.setPolicySettingscCstjd||f�dS)Nz policy.PolicyUpdated('%s', '%s'))rr1)r)r�r�r-r-r.r��szFirewallD.PolicyUpdatedcCstjd�|jjj�S)NzlistServices())rr1r#rrrs)r)r:r-r-r.�listServices�s
zFirewallD.listServicesz(sssa(ss)asa{ss}asa(ss))cCs�t|t�}tjd|�|jjj|�}|j�}g}x\td�D]P}|j	|d|krr|j
tjt
||j	|d���q:|j
||j	|d�q:Wt|�S)NzgetServiceSettings(%s)�r)rr^rr1r#rr�get_service�export_config_dict�rangeZIMPORT_EXPORT_STRUCTURE�append�copy�deepcopy�getattr�tuple)r)rrr:�objZ	conf_dictZ	conf_listr�r-r-r.rt�s
"zFirewallD.getServiceSettingscCs,t|t�}tjd|�|jjj|�}|j�S)NzgetServiceSettings2(%s))rr^rr1r#rrr�r�)r)rrr:r�r-r-r.�getServiceSettings2�s
zFirewallD.getServiceSettings2cCstjd�|jjj�S)NzlistIcmpTypes())rr1r#ryrz)r)r:r-r-r.�
listIcmpTypes�s
zFirewallD.listIcmpTypescCs(t|t�}tjd|�|jjj|�j�S)NzgetIcmpTypeSettings(%s))rr^rr1r#ryZget_icmptyper�)r)ryr:r-r-r.r{�s
zFirewallD.getIcmpTypeSettingscCstjd�|jj�S)NzgetLogDenied())rr1r#Zget_log_denied)r)r:r-r-r.�getLogDenied	s
zFirewallD.getLogDeniedcCsXt|t�}tjd|�|j|�|jj|�|j|�|jj�|j	j�|j
�dS)NzsetLogDenied('%s'))rr^rr1r;r#Zset_log_denied�LogDeniedChangedrnrro)r)�valuer:r-r-r.�setLogDenieds




zFirewallD.setLogDeniedcCstjd|�dS)NzLogDeniedChanged('%s'))rr1)r)r�r-r-r.r�"szFirewallD.LogDeniedChangedcCstjd�dS)NzgetAutomaticHelpers()�no)rr1)r)r:r-r-r.�getAutomaticHelpers+s
zFirewallD.getAutomaticHelperscCs&t|t�}tjd|�|j|�dS)NzsetAutomaticHelpers('%s'))rr^rr1r;)r)r�r:r-r-r.�setAutomaticHelpers6s
zFirewallD.setAutomaticHelperscCstjd|�dS)NzAutomaticHelpersChanged('%s'))rr1)r)r�r-r-r.�AutomaticHelpersChangedBsz!FirewallD.AutomaticHelpersChangedcCstjd�|jj�S)NzgetDefaultZone())rr1r#Zget_default_zone)r)r:r-r-r.�getDefaultZoneKs
zFirewallD.getDefaultZonecCs<t|t�}tjd|�|j|�|jj|�|j|�dS)NzsetDefaultZone('%s'))rr^rr1r;r#Zset_default_zone�DefaultZoneChanged)r)r<r:r-r-r.�setDefaultZoneTs


zFirewallD.setDefaultZonecCstjd|�dS)NzDefaultZoneChanged('%s'))rr1)r)r<r-r-r.r�`szFirewallD.DefaultZoneChangedcCstjd�|jjj�S)Nzpolicy.getPolicies())rr1r#r�r�)r)r:r-r-r.�getPoliciesks
zFirewallD.getPoliciesz
a{sa{sas}}cCs\tjd�i}xH|jjj�D]8}i||<|jjj|�||d<|jjj|�||d<qW|S)Nzpolicy.getActivePolicies()Z
ingress_zonesZegress_zones)rr1r#r�Z)get_active_policies_not_derived_from_zoneZlist_ingress_zonesZlist_egress_zones)r)r:r7r�r-r-r.�getActivePoliciesss
zFirewallD.getActivePoliciescCstjd�|jjj�S)Nzzone.getZones())rr1r#r<r)r)r:r-r-r.�getZones�s
zFirewallD.getZonescCs�tjd�i}x||jjj�D]l}|jjj|�}|jjj|�}t|�t|�dkri||<t|�dkrp|||d<t|�dkr|||d<qW|S)Nzzone.getActiveZones()r�
interfaces�sources)rr1r#r<r�list_interfaces�list_sources�len)r)r:Zzonesr<r�r�r-r-r.�getActiveZones�s
zFirewallD.getActiveZonescCs2t|t�}tjd|�|jjj|�}|r.|SdS)z�Return the zone an interface belongs to.

        :Parameters:
            `interface` : str
                Name of the interface
        :Returns: str. The name of the zone.
        zzone.getZoneOfInterface('%s')rm)rr^rr1r#r<Zget_zone_of_interface)r)r�r:r<r-r-r.�getZoneOfInterface�s
zFirewallD.getZoneOfInterfacecCs2t|t�}tjd|�|jjj|�}|r.|SdS)Nzzone.getZoneOfSource('%s')rm)rr^rr1r#r<Zget_zone_of_source)r)�sourcer:r<r-r-r.�getZoneOfSource�s
zFirewallD.getZoneOfSourcecCsdS)NFr-)r)r<r:r-r-r.�isImmutable�szFirewallD.isImmutablecCsRt|t�}t|t�}tjd||f�|j|�|jjj|||�}|j||�|S)zPAdd an interface to a zone.
        If zone is empty, use default zone.
        zzone.addInterface('%s', '%s'))	rr^rr1r;r#r<Z
add_interface�InterfaceAdded)r)r<r�r:�_zoner-r-r.�addInterface�s


zFirewallD.addInterfacecCs"t|t�}t|t�}|j|||�S)z�Change a zone an interface is part of.
        If zone is empty, use default zone.

        This function is deprecated, use changeZoneOfInterface instead
        )rr^�changeZoneOfInterface)r)r<r�r:r-r-r.�
changeZone�s


zFirewallD.changeZonecCsRt|t�}t|t�}tjd||f�|j|�|jjj|||�}|j||�|S)z[Change a zone an interface is part of.
        If zone is empty, use default zone.
        z&zone.changeZoneOfInterface('%s', '%s'))	rr^rr1r;r#r<Zchange_zone_of_interface�ZoneOfInterfaceChanged)r)r<r�r:r�r-r-r.r��s


zFirewallD.changeZoneOfInterfacecCsPt|t�}t|t�}tjd||f�|j|�|jjj||�}|j||�|S)zkRemove interface from a zone.
        If zone is empty, remove from zone the interface belongs to.
        z zone.removeInterface('%s', '%s'))	rr^rr1r;r#r<Zremove_interface�InterfaceRemoved)r)r<r�r:r�r-r-r.r��s


zFirewallD.removeInterfacecCs6t|t�}t|t�}tjd||f�|jjj||�S)z^Return true if an interface is in a zone.
        If zone is empty, use default zone.
        zzone.queryInterface('%s', '%s'))rr^rr1r#r<Zquery_interface)r)r<r�r:r-r-r.�queryInterfaces

zFirewallD.queryInterfacecCs&t|t�}tjd|�|jjj|�S)z]Return the list of interfaces of a zone.
        If zone is empty, use default zone.
        zzone.getInterfaces('%s'))rr^rr1r#r<r�)r)r<r:r-r-r.r�s

zFirewallD.getInterfacescCstjd||f�dS)Nzzone.InterfaceAdded('%s', '%s'))rr1)r)r<r�r-r-r.r�+szFirewallD.InterfaceAddedcCstjd||f�dS)z,
        This signal is deprecated.
        zzone.ZoneChanged('%s', '%s')N)rr1)r)r<r�r-r-r.�ZoneChanged0szFirewallD.ZoneChangedcCs"tjd||f�|j||�dS)Nz'zone.ZoneOfInterfaceChanged('%s', '%s'))rr1r�)r)r<r�r-r-r.r�8s
z FirewallD.ZoneOfInterfaceChangedcCstjd||f�dS)Nz!zone.InterfaceRemoved('%s', '%s'))rr1)r)r<r�r-r-r.r�?szFirewallD.InterfaceRemovedcCsRt|t�}t|t�}tjd||f�|j|�|jjj|||�}|j||�|S)zLAdd a source to a zone.
        If zone is empty, use default zone.
        zzone.addSource('%s', '%s'))	rr^rr1r;r#r<Z
add_source�SourceAdded)r)r<r�r:r�r-r-r.�	addSourceHs


zFirewallD.addSourcecCsRt|t�}t|t�}tjd||f�|j|�|jjj|||�}|j||�|S)zXChange a zone an source is part of.
        If zone is empty, use default zone.
        z#zone.changeZoneOfSource('%s', '%s'))	rr^rr1r;r#r<Zchange_zone_of_source�ZoneOfSourceChanged)r)r<r�r:r�r-r-r.�changeZoneOfSourceYs


zFirewallD.changeZoneOfSourcecCsPt|t�}t|t�}tjd||f�|j|�|jjj||�}|j||�|S)zeRemove source from a zone.
        If zone is empty, remove from zone the source belongs to.
        zzone.removeSource('%s', '%s'))	rr^rr1r;r#r<Z
remove_source�
SourceRemoved)r)r<r�r:r�r-r-r.�removeSourcejs


zFirewallD.removeSourcecCs6t|t�}t|t�}tjd||f�|jjj||�S)z[Return true if an source is in a zone.
        If zone is empty, use default zone.
        zzone.querySource('%s', '%s'))rr^rr1r#r<Zquery_source)r)r<r�r:r-r-r.�querySource{s

zFirewallD.querySourcecCs&t|t�}tjd|�|jjj|�S)zZReturn the list of sources of a zone.
        If zone is empty, use default zone.
        zzone.getSources('%s'))rr^rr1r#r<r�)r)r<r:r-r-r.�
getSources�s

zFirewallD.getSourcescCstjd||f�dS)Nzzone.SourceAdded('%s', '%s'))rr1)r)r<r�r-r-r.r��szFirewallD.SourceAddedcCstjd||f�dS)Nz$zone.ZoneOfSourceChanged('%s', '%s'))rr1)r)r<r�r-r-r.r��szFirewallD.ZoneOfSourceChangedcCstjd||f�dS)Nzzone.SourceRemoved('%s', '%s'))rr1)r)r<r�r-r-r.r��szFirewallD.SourceRemovedcCsHtjd||f�|j||=t|d�}|jjj||�|j||�dS)Nz%zone.disableTimedRichRule('%s', '%s'))�rule_str)rr1r2rr#r<�remove_rule�RichRuleRemoved)r)r<�ruler�r-r-r.�disableTimedRichRule�s

zFirewallD.disableTimedRichRuleZssicCs�t|t�}t|t�}t|t�}tjd||f�t|d�}|jjj|||�}|dkrtt	j
||j||�}|j|||�|j
|||�|S)Nzzone.addRichRule('%s', '%s'))r�r)rr^r�rr1rr#r<�add_ruler�timeout_add_secondsr�r?�
RichRuleAdded)r)r<r��timeoutr:r�r�r>r-r-r.�addRichRule�s




zFirewallD.addRichRulecCs\t|t�}t|t�}tjd||f�t|d�}|jjj||�}|j||�|j	||�|S)Nzzone.removeRichRule('%s', '%s'))r�)
rr^rr1rr#r<r�rAr�)r)r<r�r:r�r�r-r-r.�removeRichRule�s


zFirewallD.removeRichRulecCs@t|t�}t|t�}tjd||f�t|d�}|jjj||�S)Nzzone.queryRichRule('%s', '%s'))r�)rr^rr1rr#r<�
query_rule)r)r<r�r:r�r-r-r.�
queryRichRule�s



zFirewallD.queryRichRulecCs&t|t�}tjd|�|jjj|�S)Nzzone.getRichRules('%s'))rr^rr1r#r<Z
list_rules)r)r<r:r-r-r.�getRichRules�s
zFirewallD.getRichRulescCstjd|||f�dS)Nz"zone.RichRuleAdded('%s', '%s', %d))rr1)r)r<r�r�r-r-r.r��szFirewallD.RichRuleAddedcCstjd||f�dS)Nz zone.RichRuleRemoved('%s', '%s'))rr1)r)r<r�r-r-r.r��szFirewallD.RichRuleRemovedcCs>tjd||f�|j||=|jjj||�|j||�dS)Nz$zone.disableTimedService('%s', '%s'))rr1r2r#r<�remove_service�ServiceRemoved)r)r<rrr-r-r.�disableTimedService�szFirewallD.disableTimedServicecCs�t|t�}t|t�}t|t�}tjd|||f�|j|�|jjj||||�}|dkrxt	j
||j||�}|j|||�|j
|||�|S)Nzzone.addService('%s', '%s', %d)r)rr^r�rr1r;r#r<Zadd_servicerr�rr?�ServiceAdded)r)r<rrr�r:r�r>r-r-r.rv�s




zFirewallD.addServicecCs\t|t�}t|t�}tjd||f�|j|�|jjj||�}|j||�|j	||�|S)Nzzone.removeService('%s', '%s'))
rr^rr1r;r#r<rrAr)r)r<rrr:r�r-r-r.�
removeServices


zFirewallD.removeServicecCs6t|t�}t|t�}tjd||f�|jjj||�S)Nzzone.queryService('%s', '%s'))rr^rr1r#r<Z
query_service)r)r<rrr:r-r-r.�queryService&s

zFirewallD.queryServicecCs&t|t�}tjd|�|jjj|�S)Nzzone.getServices('%s'))rr^rr1r#r<Z
list_services)r)r<r:r-r-r.�getServices1s
zFirewallD.getServicescCstjd|||f�dS)Nz!zone.ServiceAdded('%s', '%s', %d))rr1)r)r<rrr�r-r-r.r=szFirewallD.ServiceAddedcCstjd||f�dS)Nzzone.ServiceRemoved('%s', '%s'))rr1)r)r<rrr-r-r.rCszFirewallD.ServiceRemovedcCsHtjd|||f�|j|||f=|jjj|||�|j|||�dS)Nz'zone.disableTimedPort('%s', '%s', '%s'))rr1r2r#r<�remove_port�PortRemoved)r)r<�port�protocolr-r-r.�disableTimedPortLs
zFirewallD.disableTimedPortZsssicCs�t|t�}t|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||||�}|dkr�t	j
||j|||�}|j|||f|�|j
||||�|S)Nzzone.addPort('%s', '%s', '%s')r)rr^r�rr1r;r#r<Zadd_portrr�rr?�	PortAdded)r)r<rrr�r:r�r>r-r-r.�addPortTs






zFirewallD.addPortZssscCspt|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||�}|j|||f�|j	|||�|S)Nz!zone.removePort('%s', '%s', '%s'))
rr^rr1r;r#r<rrAr
)r)r<rrr:r�r-r-r.�
removePortks



zFirewallD.removePortcCsDt|t�}t|t�}t|t�}tjd|||f�|jjj|||�S)Nz zone.queryPort('%s', '%s', '%s'))rr^rr1r#r<Z
query_port)r)r<rrr:r-r-r.�	queryPort}s



zFirewallD.queryPortZaascCs&t|t�}tjd|�|jjj|�S)Nzzone.getPorts('%s'))rr^rr1r#r<Z
list_ports)r)r<r:r-r-r.�getPorts�s
zFirewallD.getPortsrcCstjd||||f�dS)Nz$zone.PortAdded('%s', '%s', '%s', %d))rr1)r)r<rrr�r-r-r.r�szFirewallD.PortAddedcCstjd|||f�dS)Nz"zone.PortRemoved('%s', '%s', '%s'))rr1)r)r<rrr-r-r.r
�szFirewallD.PortRemovedcCs>tjd||f�|j||=|jjj||�|j||�dS)Nz%zone.disableTimedProtocol('%s', '%s'))rr1r2r#r<�remove_protocol�ProtocolRemoved)r)r<rr-r-r.�disableTimedProtocol�szFirewallD.disableTimedProtocolcCs�t|t�}t|t�}t|t�}tjd||f�|j|�|jjj||||�}|dkrvt	j
||j||�}|j|||�|j
|||�|S)Nzzone.enableProtocol('%s', '%s')r)rr^r�rr1r;r#r<Zadd_protocolrr�rr?�
ProtocolAdded)r)r<rr�r:r�r>r-r-r.�addProtocol�s




zFirewallD.addProtocolcCs\t|t�}t|t�}tjd||f�|j|�|jjj||�}|j||�|j	||�|S)Nzzone.removeProtocol('%s', '%s'))
rr^rr1r;r#r<rrAr)r)r<rr:r�r-r-r.�removeProtocol�s


zFirewallD.removeProtocolcCs6t|t�}t|t�}tjd||f�|jjj||�S)Nzzone.queryProtocol('%s', '%s'))rr^rr1r#r<Zquery_protocol)r)r<rr:r-r-r.�
queryProtocol�s

zFirewallD.queryProtocolcCs&t|t�}tjd|�|jjj|�S)Nzzone.getProtocols('%s'))rr^rr1r#r<Zlist_protocols)r)r<r:r-r-r.�getProtocols�s
zFirewallD.getProtocolscCstjd|||f�dS)Nz"zone.ProtocolAdded('%s', '%s', %d))rr1)r)r<rr�r-r-r.r�szFirewallD.ProtocolAddedcCstjd||f�dS)Nz zone.ProtocolRemoved('%s', '%s'))rr1)r)r<rr-r-r.r�szFirewallD.ProtocolRemovedcCsJtjd|||f�|j|d||f=|jjj|||�|j|||�dS)Nz-zone.disableTimedSourcePort('%s', '%s', '%s')�sport)rr1r2r#r<�remove_source_port�SourcePortRemoved)r)r<rrr-r-r.�disableTimedSourcePort�s
z FirewallD.disableTimedSourcePortcCs�t|t�}t|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||||�}|dkr�t	j
||j|||�}|j|d||f|�|j
||||�|S)Nz$zone.addSourcePort('%s', '%s', '%s')rr)rr^r�rr1r;r#r<Zadd_source_portrr�r!r?�SourcePortAdded)r)r<rrr�r:r�r>r-r-r.�
addSourcePort�s








zFirewallD.addSourcePortcCsrt|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||�}|j|d||f�|j	|||�|S)Nz'zone.removeSourcePort('%s', '%s', '%s')r)
rr^rr1r;r#r<rrAr )r)r<rrr:r�r-r-r.�removeSourcePorts





zFirewallD.removeSourcePortcCsDt|t�}t|t�}t|t�}tjd|||f�|jjj|||�S)Nz&zone.querySourcePort('%s', '%s', '%s'))rr^rr1r#r<Zquery_source_port)r)r<rrr:r-r-r.�querySourcePort)s




zFirewallD.querySourcePortcCs&t|t�}tjd|�|jjj|�S)Nzzone.getSourcePorts('%s'))rr^rr1r#r<Zlist_source_ports)r)r<r:r-r-r.�getSourcePorts6s
zFirewallD.getSourcePortscCstjd||||f�dS)Nz*zone.SourcePortAdded('%s', '%s', '%s', %d))rr1)r)r<rrr�r-r-r.r"BszFirewallD.SourcePortAddedcCstjd|||f�dS)Nz(zone.SourcePortRemoved('%s', '%s', '%s'))rr1)r)r<rrr-r-r.r Hs
zFirewallD.SourcePortRemovedcCs(|j|d=|jjj|�|j|�dS)N�
masquerade)r2r#r<�remove_masquerade�MasqueradeRemoved)r)r<r-r-r.�disableTimedMasqueradeRsz FirewallD.disableTimedMasqueradeZsicCstt|t�}t|t�}tjd|�|j|�|jjj|||�}|dkrdt	j
||j|�}|j|d|�|j
||�|S)Nzzone.addMasquerade('%s')rr')rr^r�rr1r;r#r<Zadd_masqueraderr�r*r?�MasqueradeAdded)r)r<r�r:r�r>r-r-r.�
addMasqueradeXs



zFirewallD.addMasqueradecCsJt|t�}tjd|�|j|�|jjj|�}|j|d�|j	|�|S)Nzzone.removeMasquerade('%s')r')
rr^rr1r;r#r<r(rAr))r)r<r:r�r-r-r.�removeMasqueradels


zFirewallD.removeMasqueradecCs&t|t�}tjd|�|jjj|�S)Nzzone.queryMasquerade('%s'))rr^rr1r#r<Zquery_masquerade)r)r<r:r-r-r.�queryMasquerade{s
zFirewallD.queryMasqueradecCstjd||f�dS)Nzzone.MasqueradeAdded('%s', %d))rr1)r)r<r�r-r-r.r+�szFirewallD.MasqueradeAddedcCstjd|�dS)Nzzone.MasqueradeRemoved('%s'))rr1)r)r<r-r-r.r)�szFirewallD.MasqueradeRemovedcCs@|j|||||f=|jjj|||||�|j|||||�dS)N)r2r#r<�remove_forward_port�ForwardPortRemoved)r)r<rr�toport�toaddrr-r-r.�disable_forward_port�szFirewallD.disable_forward_portZsssssic
Cs�t|t�}t|t�}t|t�}t|t�}t|t�}t|t�}tjd|||||f�|j|�|jjj|||||||�}|dkr�t	j
||j|||||�}	|j|||||f|	�|j
||||||�|S)Nz1zone.addForwardPort('%s', '%s', '%s', '%s', '%s')r)rr^r�rr1r;r#r<Zadd_forward_portrr�r3r?�ForwardPortAdded)
r)r<rrr1r2r�r:r�r>r-r-r.�addForwardPort�s&







zFirewallD.addForwardPortZssssscCs�t|t�}t|t�}t|t�}t|t�}t|t�}tjd|||||f�|j|�|jjj|||||�}|j|||||f�|j	|||||�|S)Nz4zone.removeForwardPort('%s', '%s', '%s', '%s', '%s'))
rr^rr1r;r#r<r/rAr0)r)r<rrr1r2r:r�r-r-r.�removeForwardPort�s





zFirewallD.removeForwardPortcCs`t|t�}t|t�}t|t�}t|t�}t|t�}tjd|||||f�|jjj|||||�S)Nz3zone.queryForwardPort('%s', '%s', '%s', '%s', '%s'))rr^rr1r#r<Zquery_forward_port)r)r<rrr1r2r:r-r-r.�queryForwardPort�s




zFirewallD.queryForwardPortcCs&t|t�}tjd|�|jjj|�S)Nzzone.getForwardPorts('%s'))rr^rr1r#r<Zlist_forward_ports)r)r<r:r-r-r.�getForwardPorts�s
zFirewallD.getForwardPortscCstjd||||||f�dS)Nz7zone.ForwardPortAdded('%s', '%s', '%s', '%s', '%s', %d))rr1)r)r<rrr1r2r�r-r-r.r4�szFirewallD.ForwardPortAddedcCstjd|||||f�dS)Nz5zone.ForwardPortRemoved('%s', '%s', '%s', '%s', '%s'))rr1)r)r<rrr1r2r-r-r.r0�szFirewallD.ForwardPortRemovedcCs>tjd||f�|j||=|jjj||�|j||�dS)Nz&zone.disableTimedIcmpBlock('%s', '%s'))rr1r2r#r<�remove_icmp_block�IcmpBlockRemoved)r)r<�icmpr:r-r-r.�disableTimedIcmpBlock�szFirewallD.disableTimedIcmpBlockcCs�t|t�}t|t�}t|t�}tjd||f�|j|�|jjj||||�}|dkrxt	j
||j|||�}|j|||�|j
|||�|S)Nz zone.enableIcmpBlock('%s', '%s')r)rr^r�rr1r;r#r<Zadd_icmp_blockrr�r<r?�IcmpBlockAdded)r)r<r;r�r:r�r>r-r-r.�addIcmpBlocks





zFirewallD.addIcmpBlockcCs\t|t�}t|t�}tjd||f�|j|�|jjj||�}|j||�|j	||�|S)Nz zone.removeIcmpBlock('%s', '%s'))
rr^rr1r;r#r<r9rAr:)r)r<r;r:r�r-r-r.�removeIcmpBlocks


zFirewallD.removeIcmpBlockcCs6t|t�}t|t�}tjd||f�|jjj||�S)Nzzone.queryIcmpBlock('%s', '%s'))rr^rr1r#r<Zquery_icmp_block)r)r<r;r:r-r-r.�queryIcmpBlock&s

zFirewallD.queryIcmpBlockcCs&t|t�}tjd|�|jjj|�S)Nzzone.getIcmpBlocks('%s'))rr^rr1r#r<Zlist_icmp_blocks)r)r<r:r-r-r.�
getIcmpBlocks1s
zFirewallD.getIcmpBlockscCstjd|||f�dS)Nz#zone.IcmpBlockAdded('%s', '%s', %d))rr1)r)r<r;r�r-r-r.r==szFirewallD.IcmpBlockAddedcCstjd||f�dS)Nz!zone.IcmpBlockRemoved('%s', '%s'))rr1)r)r<r;r-r-r.r:CszFirewallD.IcmpBlockRemovedcCs@t|t�}tjd|�|j|�|jjj||�}|j|�|S)Nz zone.addIcmpBlockInversion('%s'))	rr^rr1r;r#r<Zadd_icmp_block_inversion�IcmpBlockInversionAdded)r)r<r:r�r-r-r.�addIcmpBlockInversionLs


zFirewallD.addIcmpBlockInversioncCs>t|t�}tjd|�|j|�|jjj|�}|j|�|S)Nz#zone.removeIcmpBlockInversion('%s'))	rr^rr1r;r#r<Zremove_icmp_block_inversion�IcmpBlockInversionRemoved)r)r<r:r�r-r-r.�removeIcmpBlockInversionZs


z"FirewallD.removeIcmpBlockInversioncCs&t|t�}tjd|�|jjj|�S)Nz"zone.queryIcmpBlockInversion('%s'))rr^rr1r#r<Zquery_icmp_block_inversion)r)r<r:r-r-r.�queryIcmpBlockInversionhs
z!FirewallD.queryIcmpBlockInversioncCstjd|�dS)Nz"zone.IcmpBlockInversionAdded('%s'))rr1)r)r<r-r-r.rBrsz!FirewallD.IcmpBlockInversionAddedcCstjd|�dS)Nz$zone.IcmpBlockInversionRemoved('%s'))rr1)r)r<r-r-r.rDwsz#FirewallD.IcmpBlockInversionRemovedcCs`t|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||�|j|||�dS)Nz!direct.addChain('%s', '%s', '%s'))	rr^rr1r;r#r�Z	add_chain�
ChainAdded)r)�ipv�table�chainr:r-r-r.�addChain�s



zFirewallD.addChaincCs`t|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||�|j|||�dS)Nz$direct.removeChain('%s', '%s', '%s'))	rr^rr1r;r#r�Zremove_chain�ChainRemoved)r)rHrIrJr:r-r-r.�removeChain�s



zFirewallD.removeChaincCsDt|t�}t|t�}t|t�}tjd|||f�|jjj|||�S)Nz#direct.queryChain('%s', '%s', '%s'))rr^rr1r#r�Zquery_chain)r)rHrIrJr:r-r-r.�
queryChain�s



zFirewallD.queryChaincCs6t|t�}t|t�}tjd||f�|jjj||�S)Nzdirect.getChains('%s', '%s'))rr^rr1r#r�Z
get_chains)r)rHrIr:r-r-r.�	getChains�s

zFirewallD.getChainsza(sss)cCstjd�|jjj�S)Nzdirect.getAllChains())rr1r#r�r�)r)r:r-r-r.�getAllChains�s
zFirewallD.getAllChainscCstjd|||f�dS)Nz#direct.ChainAdded('%s', '%s', '%s'))rr1)r)rHrIrJr-r-r.rG�szFirewallD.ChainAddedcCstjd|||f�dS)Nz%direct.ChainRemoved('%s', '%s', '%s'))rr1)r)rHrIrJr-r-r.rL�s
zFirewallD.ChainRemovedZsssiascCs�t|t�}t|t�}t|t�}t|t�}tdd�|D��}tjd||||dj|�f�|j|�|jj	j
|||||�|j|||||�dS)Ncss|]}t|t�VqdS)N)rr^)�.0r�r-r-r.�	<genexpr>�sz$FirewallD.addRule.<locals>.<genexpr>z*direct.addRule('%s', '%s', '%s', %d, '%s')z',')rr^r�r�rr1�joinr;r#r�r��	RuleAdded)r)rHrIrJ�priorityr*r:r-r-r.�addRule�s




zFirewallD.addRulecCs�t|t�}t|t�}t|t�}t|t�}tdd�|D��}tjd||||dj|�f�|j|�|jj	j
|||||�|j|||||�dS)Ncss|]}t|t�VqdS)N)rr^)rQr�r-r-r.rR�sz'FirewallD.removeRule.<locals>.<genexpr>z-direct.removeRule('%s', '%s', '%s', %d, '%s')z',')rr^r�r�rr1rSr;r#r�r��RuleRemoved)r)rHrIrJrUr*r:r-r-r.�
removeRule�s




zFirewallD.removeRulecCs�t|t�}t|t�}t|t�}tjd|||f�|j|�xF|jjj|||�D]0\}}|jjj|||||�|j	|||||�qPWdS)Nz$direct.removeRules('%s', '%s', '%s'))
rr^rr1r;r#r��	get_rulesr�rW)r)rHrIrJr:rUr*r-r-r.�removeRules�s



zFirewallD.removeRulescCsnt|t�}t|t�}t|t�}t|t�}tdd�|D��}tjd||||dj|�f�|jjj	|||||�S)Ncss|]}t|t�VqdS)N)rr^)rQr�r-r-r.rR	sz&FirewallD.queryRule.<locals>.<genexpr>z,direct.queryRule('%s', '%s', '%s', %d, '%s')z',')
rr^r�r�rr1rSr#r�r)r)rHrIrJrUr*r:r-r-r.�	queryRule�s



zFirewallD.queryRuleza(ias)cCsDt|t�}t|t�}t|t�}tjd|||f�|jjj|||�S)Nz!direct.getRules('%s', '%s', '%s'))rr^rr1r#r�rY)r)rHrIrJr:r-r-r.�getRules
	s



zFirewallD.getRulesz	a(sssias)cCstjd�|jjj�S)Nzdirect.getAllRules())rr1r#r�r�)r)r:r-r-r.�getAllRules	s
zFirewallD.getAllRulescCs"tjd||||dj|�f�dS)Nz,direct.RuleAdded('%s', '%s', '%s', %d, '%s')z',')rr1rS)r)rHrIrJrUr*r-r-r.rT"	szFirewallD.RuleAddedcCs"tjd||||dj|�f�dS)Nz.direct.RuleRemoved('%s', '%s', '%s', %d, '%s')z',')rr1rS)r)rHrIrJrUr*r-r-r.rW(	szFirewallD.RuleRemovedrScCs�t|t�}tdd�|D��}tjd|dj|�f�|j|�y|jjj	||�St
k
r�}zh|dkrztddd	d
g�}ntd	d
g�}t|�}|jt
jkr�tt|�|@�dkr�tj|�t|���WYdd}~XnXdS)
Ncss|]}t|t�VqdS)N)rr^)rQr�r-r-r.rR9	sz(FirewallD.passthrough.<locals>.<genexpr>zdirect.passthrough('%s', '%s')z','rHrLz-Cz--checkz-Lz--listr)rHrL)rr^r�rr1rSr;r#r��passthroughr�set�coderZCOMMAND_FAILEDr�rxr
)r)rHr*r:r9Z
query_args�msgr-r-r.r^2	s"


zFirewallD.passthroughcCs\t|�}tdd�|D��}tjd|dj|�f�|j|�|jjj||�|j	||�dS)Ncss|]}t|�VqdS)N)r)rQr�r-r-r.rRT	sz+FirewallD.addPassthrough.<locals>.<genexpr>z!direct.addPassthrough('%s', '%s')z',')
rr�rr1rSr;r#r�Zadd_passthrough�PassthroughAdded)r)rHr*r:r-r-r.�addPassthroughM	s
zFirewallD.addPassthroughcCs\t|�}tdd�|D��}tjd|dj|�f�|j|�|jjj||�|j	||�dS)Ncss|]}t|�VqdS)N)r)rQr�r-r-r.rRb	sz.FirewallD.removePassthrough.<locals>.<genexpr>z$direct.removePassthrough('%s', '%s')z',')
rr�rr1rSr;r#r�Zremove_passthrough�PassthroughRemoved)r)rHr*r:r-r-r.�removePassthrough[	s
zFirewallD.removePassthroughcCsBt|�}tdd�|D��}tjd|dj|�f�|jjj||�S)Ncss|]}t|�VqdS)N)r)rQr�r-r-r.rRp	sz-FirewallD.queryPassthrough.<locals>.<genexpr>z#direct.queryPassthrough('%s', '%s')z',')rr�rr1rSr#r�Zquery_passthrough)r)rHr*r:r-r-r.�queryPassthroughi	s
zFirewallD.queryPassthroughza(sas)cCstjd�|jjj�S)Nzdirect.getAllPassthroughs())rr1r#r�r�)r)r:r-r-r.�getAllPassthroughsu	s
zFirewallD.getAllPassthroughscCs.tjd�xt|j��D]}|j|�qWdS)Nzdirect.removeAllPassthroughs())rr1�reversedrgre)r)r:r^r-r-r.�removeAllPassthroughs~	s
zFirewallD.removeAllPassthroughscCs"t|�}tjd|�|jjj|�S)Nzdirect.getPassthroughs('%s'))rrr1r#r�Zget_passthroughs)r)rHr:r-r-r.�getPassthroughs�	szFirewallD.getPassthroughscCstjd|dj|�f�dS)Nz#direct.PassthroughAdded('%s', '%s')z',')rr1rS)r)rHr*r-r-r.rb�	szFirewallD.PassthroughAddedcCstjd|dj|�f�dS)Nz%direct.PassthroughRemoved('%s', '%s')z',')rr1rS)r)rHr*r-r-r.rd�	szFirewallD.PassthroughRemovedcCsdS)z� PK_ACTION_ALL implies all other actions, i.e. once a subject is
            authorized for PK_ACTION_ALL it's also authorized for any other action.
            Use-case is GUI (RHBZ#994729).
        Nr-)r)r:r-r-r.�authorizeAll�	s	zFirewallD.authorizeAllcCs$t|�}tjd|�|jjj|�S)Nzipset.queryIPSet('%s'))rrr1r#r|Zquery_ipset)r)r|r:r-r-r.�
queryIPSet�	szFirewallD.queryIPSetcCstjd�|jjj�S)Nzipsets.getIPSets())rr1r#r|r})r)r:r-r-r.�	getIPSets�	s
zFirewallD.getIPSetscCs(t|t�}tjd|�|jjj|�j�S)NzgetIPSetSettings(%s))rr^rr1r#r|Z	get_ipsetr�)r)r|r:r-r-r.r~�	s
zFirewallD.getIPSetSettingscCsLt|�}t|�}tjd||f�|j|�|jjj||�|j||�dS)Nzipset.addEntry('%s', '%s'))rrr1r;r#r|Z	add_entry�
EntryAdded)r)r|�entryr:r-r-r.�addEntry�	s
zFirewallD.addEntrycCsLt|�}t|�}tjd||f�|j|�|jjj||�|j||�dS)Nzipset.removeEntry('%s', '%s'))rrr1r;r#r|Zremove_entry�EntryRemoved)r)r|ror:r-r-r.�removeEntry�	s
zFirewallD.removeEntrycCs2t|�}t|�}tjd||f�|jjj||�S)Nzipset.queryEntry('%s', '%s'))rrr1r#r|Zquery_entry)r)r|ror:r-r-r.�
queryEntry�	szFirewallD.queryEntrycCs$t|�}tjd|�|jjj|�S)Nzipset.getEntries('%s'))rrr1r#r|�get_entries)r)r|r:r-r-r.�
getEntries�	szFirewallD.getEntriescCs�t|�}t|t�}tjd|dj|��|jjj|�}|jjj||�t	|�}t	|�}x||D]}|j
||�q^Wx||D]}|j||�q|WdS)Nzipset.setEntries('%s', '[%s]')�,)r�listrr1rSr#r|rtZset_entriesr_rnrq)r)r|Zentriesr:Zold_entriesZold_entries_setZentries_setror-r-r.�
setEntries�	s
zFirewallD.setEntriescCs&t|�}t|�}tjd||f�dS)Nzipset.EntryAdded('%s', '%s'))rrr1)r)r|ror-r-r.rn
szFirewallD.EntryAddedcCs&t|�}t|�}tjd||f�dS)Nzipset.EntryRemoved('%s', '%s'))rrr1)r)r|ror-r-r.rq
szFirewallD.EntryRemovedcCstjd�|jjj�S)Nzhelpers.getHelpers())rr1r#r�r�)r)r:r-r-r.�
getHelpers!
s
zFirewallD.getHelperscCs(t|t�}tjd|�|jjj|�j�S)NzgetHelperSettings(%s))rr^rr1r#r�Z
get_helperr�)r)r�r:r-r-r.r�*
s
zFirewallD.getHelperSettings)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)r)N)N)N)N)r)N)N)N)N)r)N)N)N)r)N)N)N)N)r)N)N)N)N)r)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)��__name__�
__module__�__qualname__�__doc__Z
persistentrr'ZPK_ACTION_CONFIGZdefault_polkit_auth_requiredrr"r0r&r/r
r;r?rArCrZrZPROPERTIES_IFACErerh�slipZpolkitZrequire_authrirr�signalrjZPK_ACTION_INFOZINTROSPECTABLE_IFACErkr(rnrprorqr�ZPK_ACTION_POLICIESrar�r�ZPK_ACTION_POLICIES_INFOr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�ZPK_ACTION_CONFIG_INFOr�r_r�r�r�ZDBUS_INTERFACE_POLICYr�r�r�r�rtr�r�rZDBUS_SIGNATUREr{r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrrr�r�rrvr	r
rrrrrrrrrr
rrrrrrrr!r#r$r%r&r"r r*r,r-r.r+r)r3r5r6r7r8r4r0r<r>r?r@rAr=r:rCrErFrBrDZPK_ACTION_DIRECTr`rKrMZPK_ACTION_DIRECT_INFOrNrOrPrGrLrVrXrZr[r\r]rTrWr^rcrerfrgrirjrbrdZ
PK_ACTION_ALLrkrbrlrmrr~rprrrsrurxrnrqryrr��
__classcell__r-r-)r,r.rAs�	0"	



K



	
	


	
	


	
	


	
	



























	









	








	















	






	
	


	
















	







	









	
	




)9�__all__Z
gi.repositoryrr�sys�modulesr�r'Zdbus.serviceZ	slip.dbusr~Zslip.dbus.serviceZfirewallrZfirewall.core.fwrZfirewall.core.richrZfirewall.core.loggerrZfirewall.clientr	Zfirewall.server.decoratorsr
rrr
Zfirewall.server.configrZfirewall.dbus_utilsrrrrrrrZfirewall.core.io.functionsrZfirewall.core.io.ipsetrZfirewall.core.io.icmptyperZfirewall.core.io.helperrZfirewall.core.fw_nmrrrZfirewall.core.fw_ifcfgrrZfirewall.errorsrrrZObjectrr-r-r-r.�<module>s2
$server/__pycache__/config_service.cpython-36.pyc000064400000051355150351351720015710 0ustar003

��g�u�@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZmZmZddl	mZdd	lmZGd
d�dejjj�ZdS)�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�errors)�
FirewallErrorcs�eZdZdZdZejjZe	�fdd��Z
edd��Zedd��Z
ed	d
��Zeejddd
�ed�dd���Zeejddd
�ed�dd���Zejjjejj�eejdd�ed�dd����Zejjejdd�dd��Zejjjejj�eejdd�ed��fdd�	���Zeejjd d�ed�d!d"���Zeejjdd�ed�d#d$���Zeejjd d�ed�d%d&���Z eejjdd�ed�d'd(���Z!eejj�ed�d)d*���Z"ejjejjdd�ed+d,���Z#eejj�ed�d-d.���Z$ejjejjdd�ed/d0���Z%eejjdd�ed�d1d2���Z&ejjejjdd�ed3d4���Z'eejjdd�ed�d5d6���Z(eejjdd�ed�d7d8���Z)eejjdd�ed�d9d:���Z*eejjdd�ed�d;d<���Z+eejjdd�ed�d=d>���Z,eejjdd�ed�d?d@���Z-eejjdAd�ed�dBdC���Z.eejjdAd�ed�dDdE���Z/eejjdd�ed�dFdG���Z0eejjdd�ed�dHdI���Z1eejjddJd
�ed�dKdL���Z2eejjdMd�ed�dNdO���Z3eejjdMd�ed�dPdQ���Z4eejjdd�ed�dRdS���Z5eejjdd�ed�dTdU���Z6eejjddJd
�ed�dVdW���Z7eejjdAd�ed�dXdY���Z8eejjdAd�ed�dZd[���Z9eejjdd�ed�d\d]���Z:eejjdd�ed�d^d_���Z;eejjddJd
�ed�d`da���Z<eejjdMd�ed�dbdc���Z=eejjdMd�ed�ddde���Z>eejjdd�ed�dfdg���Z?eejjdd�ed�dhdi���Z@eejjddJd
�ed�djdk���ZAeejjdld�ed�dmdn���ZBeejjdld�ed�dodp���ZCeejjddd
�ed�dqdr���ZDeejjdd�ed�dsdt���ZEeejjdd�ed�dudv���ZFeejjddJd
�ed�dwdx���ZGeejjdMd�ed�dydz���ZHeejjdMd�ed�d{d|���ZIeejjdd�ed�d}d~���ZJeejjdd�ed�dd����ZKeejjddJd
�ed�d�d����ZL�ZMS)��FirewallDConfigServicezFirewallD main classTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.service.%d)
�superr
�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_SERVICE)�selfrZconf�servicer�args�kwargs)�	__class__��$/usr/lib/python3.6/config_service.pyr7s

zFirewallDConfigService.__init__cCsdS)Nr)rrrr�__del__DszFirewallDConfigService.__del__cCs|j�dS)N)Zremove_from_connection)rrrr�
unregisterHsz!FirewallDConfigService.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrr"r#rZBooleanr$r%�
exceptions�
DBusException)r�
property_namerrr�
_get_propertyPsz$FirewallDConfigService._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrrr'r(r*)r�interface_namer)�senderrrr�Getas


zFirewallDConfigService.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existr"r#rr$r%Zsv)�	signature)r"r#rr$r%)rr.rr/rrrrr'r(r*Z
Dictionary)rr0r1�ret�xrrr�GetAllrs

zFirewallDConfigService.GetAllZssv)r,cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr.rr/rr�accessCheckrrrr'r()rr0r)Z	new_valuer1rrr�Set�s



zFirewallDConfigService.Setzsa{sv}as)r4cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr.rr/r)rr0Zchanged_propertiesZinvalidated_propertiesrrr�PropertiesChanged�s


z(FirewallDConfigService.PropertiesChanged)r-cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rrr
�
IntrospectrrZget_busrrrr)rr1�data)rrrr;�s

z!FirewallDConfigService.Introspectz(sssa(ss)asa{ss}asa(ss))cCstjd|j�|jj|j�S)z!get settings for service
        z%s.getSettings())rr/rrZget_service_configr)rr1rrr�getSettings�sz"FirewallDConfigService.getSettingscCstjd|j�|jj|j�S)z!get settings for service
        z%s.getSettings2())rr/rr�get_service_config_dictr)rr1rrr�getSettings2�sz#FirewallDConfigService.getSettings2cCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)z$update settings for service
        z%s.update('...')N)rrr/rrr8rZset_service_configr�Updatedr")r�settingsr1rrr�update�s
zFirewallDConfigService.updatecCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)Nz%s.update2('...'))rrr/rrr8r�set_service_config_dictrr@r")rrAr1rrr�update2�s
zFirewallDConfigService.update2cCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z2load default settings for builtin service
        z%s.loadDefaults()N)
rr/rrr8rZload_service_defaultsrr@r")rr1rrr�loadDefaults�sz#FirewallDConfigService.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr/r)rr"rrrr@�szFirewallDConfigService.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove service
        z%s.removeService()N)	rr/rrr8rZremove_servicerZ
removeService)rr1rrr�remove�szFirewallDConfigService.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr/r)rr"rrr�Removed�szFirewallDConfigService.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename service
        z%s.rename('%s')N)rr.rr/rrr8rZrename_servicer�Renamed)rr"r1rrr�rename�s

zFirewallDConfigService.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr/r)rr"rrrrHszFirewallDConfigService.RenamedcCstjd|j�|j�dS)Nz%s.getVersion()r)rr/rr=)rr1rrr�
getVersionsz!FirewallDConfigService.getVersioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setVersion('%s')r)
rr.rr/rrr8�listr=rB)r�versionr1rArrr�
setVersions
z!FirewallDConfigService.setVersioncCstjd|j�|j�dS)Nz
%s.getShort()r)rr/rr=)rr1rrr�getShort"szFirewallDConfigService.getShortcCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setShort('%s')r)
rr.rr/rrr8rKr=rB)rZshortr1rArrr�setShort)s
zFirewallDConfigService.setShortcCstjd|j�|j�dS)Nz%s.getDescription()�)rr/rr=)rr1rrr�getDescription6sz%FirewallDConfigService.getDescriptioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setDescription('%s')rP)
rr.rr/rrr8rKr=rB)r�descriptionr1rArrr�setDescription=s

z%FirewallDConfigService.setDescriptionza(ss)cCstjd|j�|j�dS)Nz
%s.getPorts()�)rr/rr=)rr1rrr�getPortsKszFirewallDConfigService.getPortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setPorts('[%s]')�,css"|]}d|d|dfVqdS)z('%s, '%s')rrNr)�.0�portrrr�	<genexpr>_sz2FirewallDConfigService.setPorts.<locals>.<genexpr>rT)
rrK�
isinstance�append�tuplerr/r�joinrr8r=rB)r�portsr1�_portsrXrArrr�setPortsRs

zFirewallDConfigService.setPortscCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.addPort('%s', '%s')rTz%s:%s)rr.rr/rrr8rKr=rr�ALREADY_ENABLEDr[rB)rrX�protocolr1rArrr�addPortes

zFirewallDConfigService.addPortcCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.removePort('%s', '%s')rTz%s:%s)rr.rr/rrr8rKr=rr�NOT_ENABLEDrFrB)rrXrbr1rArrr�
removePortus

z!FirewallDConfigService.removePort�bcCs:t|t�}t|t�}tjd|j||�||f|j�dkS)Nz%s.queryPort('%s', '%s')rT)rr.rr/rr=)rrXrbr1rrr�	queryPort�s


z FirewallDConfigService.queryPort�ascCstjd|j�|j�dS)Nz%s.getProtocols()�)rr/rr=)rr1rrr�getProtocols�sz#FirewallDConfigService.getProtocolscCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setProtocols('[%s]')rVri)
rrKrr/rr]rr8r=rB)rZ	protocolsr1rArrr�setProtocols�s

z#FirewallDConfigService.setProtocolscCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addProtocol('%s')ri)rr.rr/rrr8rKr=rrrar[rB)rrbr1rArrr�addProtocol�s
z"FirewallDConfigService.addProtocolcCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.removeProtocol('%s')ri)rr.rr/rrr8rKr=rrrdrFrB)rrbr1rArrr�removeProtocol�s
z%FirewallDConfigService.removeProtocolcCs*t|t�}tjd|j|�||j�dkS)Nz%s.queryProtocol(%s')ri)rr.rr/rr=)rrbr1rrr�
queryProtocol�s
z$FirewallDConfigService.queryProtocolcCstjd|j�|j�dS)Nz%s.getSourcePorts()�)rr/rr=)rr1rrr�getSourcePorts�sz%FirewallDConfigService.getSourcePortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setSourcePorts('[%s]')rVcss"|]}d|d|dfVqdS)z('%s, '%s')rrNr)rWrXrrrrY�sz8FirewallDConfigService.setSourcePorts.<locals>.<genexpr>ro)
rrKrZr[r\rr/rr]rr8r=rB)rr^r1r_rXrArrr�setSourcePorts�s

z%FirewallDConfigService.setSourcePortscCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.addSourcePort('%s', '%s')roz%s:%s)rr.rr/rrr8rKr=rrrar[rB)rrXrbr1rArrr�
addSourcePort�s

z$FirewallDConfigService.addSourcePortcCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.removeSourcePort('%s', '%s')roz%s:%s)rr.rr/rrr8rKr=rrrdrFrB)rrXrbr1rArrr�removeSourcePort�s

z'FirewallDConfigService.removeSourcePortcCs:t|t�}t|t�}tjd|j||�||f|j�dkS)Nz%s.querySourcePort('%s', '%s')ro)rr.rr/rr=)rrXrbr1rrr�querySourcePorts


z&FirewallDConfigService.querySourcePortcCstjd|j�|j�dS)Nz%s.getModules()�)rr/rr=)rr1rrr�
getModulessz!FirewallDConfigService.getModulescCs�t|t�}g}x@|D]8}|jd�rB|jdd�}d|krB|jdd�}|j|�qW|}tjd|jdj|��|j	j
|�t|j��}||d<|j|�dS)N�
nf_conntrack_��_�-z%s.setModules('[%s]')rVru)
rrK�
startswith�replacer[rr/rr]rr8r=rB)r�modulesr1Z_modules�modulerArrr�
setModuless



z!FirewallDConfigService.setModulescCs�t|t�}|jd�r4|jdd�}d|kr4|jdd�}tjd|j|�|jj|�t	|j
��}||dkrtttj
|��|dj|�|j|�dS)Nrwrxryrzz%s.addModule('%s')ru)rr.r{r|rr/rrr8rKr=rrrar[rB)rr~r1rArrr�	addModule's

z FirewallDConfigService.addModulecCs�t|t�}|jd�r4|jdd�}d|kr4|jdd�}tjd|j|�|jj|�t	|j
��}||dkrtttj
|��|dj|�|j|�dS)Nrwrxryrzz%s.removeModule('%s')ru)rr.r{r|rr/rrr8rKr=rrrdrFrB)rr~r1rArrr�removeModule8s

z#FirewallDConfigService.removeModulecCsTt|t�}|jd�r4|jdd�}d|kr4|jdd�}tjd|j|�||j�dkS)Nrwrxryrzz%s.queryModule('%s')ru)rr.r{r|rr/rr=)rr~r1rrr�queryModuleIs

z"FirewallDConfigService.queryModuleza{ss}cCstjd|j�|j�dS)Nz%s.getDestinations()�)rr/rr=)rr1rrr�getDestinationsWsz&FirewallDConfigService.getDestinationscCsVt|t�}tjd|j|jd�|jd��|jj|�t|j	��}||d<|j
|�dS)Nz*%s.setDestinations({ipv4:'%s', ipv6:'%s'})Zipv4Zipv6r�)r�dictrr/r�getrr8rKr=rB)rZdestinationsr1rArrr�setDestinations^s
z&FirewallDConfigService.setDestinationscCsVt|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|d|S)Nz%s.getDestination('%s')r�)rr.rr/rrr8rKr=rrrd)r�familyr1rArrr�getDestinationks

z%FirewallDConfigService.getDestinationcCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||dkrn|d||krnt	t
jd||f��||d|<|j|�dS)Nz%s.setDestination('%s', '%s')r�z
'%s': '%s')
rr.rr/rrr8rKr=rrrarB)rr��addressr1rArrr�setDestinationxs


z%FirewallDConfigService.setDestinationcCsbt|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|d|=|j|�dS)Nz%s.removeDestination('%s')r�)
rr.rr/rrr8rKr=rrrdrB)rr�r1rArrr�removeDestination�s


z(FirewallDConfigService.removeDestinationcCsJt|t�}t|t�}tjd|j||�|j�}||dkoH||d|kS)Nz%s.queryDestination('%s', '%s')r�)rr.rr/rr=)rr�r�r1rArrr�queryDestination�s


z'FirewallDConfigService.queryDestinationcCs<tjd|j�|jj|�|jj|j�}d|kr8|dSgS)Nz%s.getIncludes()�includes)rr/rrr8rr>r)rr1rArrr�getIncludes�sz"FirewallDConfigService.getIncludescCsZt|t�}tjd|j|�|jj|�d|dd�i}|jj|j	|�|_	|j
|j	j�dS)Nz%s.setIncludes('%s')r�)rrKrr/rrr8rrCrr@r")rr�r1rArrr�setIncludes�s
z"FirewallDConfigService.setIncludescCsjt|t�}tjd|j|�|jj|�|jj|j	�}|j
dg�j|�|jj|j	|�|_	|j
|j	j�dS)Nz%s.addInclude('%s')r�)rr.rr/rrr8rr>r�
setdefaultr[rCr@r")r�includer1rArrr�
addInclude�s
z!FirewallDConfigService.addIncludecCsft|t�}tjd|j|�|jj|�|jj|j	�}|dj
|�|jj|j	|�|_	|j|j	j
�dS)Nz%s.removeInclude('%s')r�)rr.rr/rrr8rr>rrFrCr@r")rr�r1rArrr�
removeInclude�s
z$FirewallDConfigService.removeIncludecCs@t|t�}tjd|j|�|jj|j�}d|kr<||dkSdS)Nz%s.queryInclude('%s')r�F)rr.rr/rrr>r)rr�r1rArrr�queryInclude�s
z#FirewallDConfigService.queryInclude)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N�__name__�
__module__�__qualname__�__doc__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredrrr	r r!r*r
ZPROPERTIES_IFACEr2r7�slipZpolkitZrequire_authr9r�signalr:ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr;rr=r?rBrDrEr@rFrGrIrHrJrMrNrOrQrSrUr`rcrergrjrkrlrmrnrprqrrrsrtrvrr�r�r�r�r�r�r�r�r�r�r�r�r�r��
__classcell__rr)rrr
/s�
		

	


		


	


		r
)Z
gi.repositoryr�sysr}rZdbus.serviceZ	slip.dbusr�Zslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.loggerrZfirewall.server.decoratorsrr	r
rZfirewall.errorsrrZObjectr
rrrr�<module>s
server/__pycache__/config_icmptype.cpython-36.pyc000064400000024677150351351720016111 0ustar003

��gS:�@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZddlmZmZmZdd	l	mZdd
lmZGdd�dejjj�ZdS)
�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�IcmpType)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�errors)�
FirewallErrorcsHeZdZdZdZejjZe	�fdd��Z
edd��Zedd��Z
ed	d
��Zeejddd
�edHdd���Zeejddd
�edIdd���Zejjjejj�eejdd�edJdd����Zejjejdd�dd��Zejjjejj�eejdd�edK�fdd�	���Zeejjejd�edLd d!���Z eejjejd�edMd"d#���Z!eejj�edNd$d%���Z"ejjejjdd�ed&d'���Z#eejj�edOd(d)���Z$ejjejjdd�ed*d+���Z%eejjdd�edPd,d-���Z&ejjejjdd�ed.d/���Z'eejjdd�edQd0d1���Z(eejjdd�edRd2d3���Z)eejjdd�edSd4d5���Z*eejjdd�edTd6d7���Z+eejjdd�edUd8d9���Z,eejjdd�edVd:d;���Z-eejjd<d�edWd=d>���Z.eejjd<d�edXd?d@���Z/eejjdd�edYdAdB���Z0eejjdd�edZdCdD���Z1eejjddEd
�ed[dFdG���Z2�Z3S)\�FirewallDConfigIcmpTypezFirewallD main classTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.icmptype.%d)
�superr�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_ICMPTYPE)�selfrZconfZicmptyper�args�kwargs)�	__class__��%/usr/lib/python3.6/config_icmptype.pyr8s

z FirewallDConfigIcmpType.__init__cCsdS)Nr)rrrr�__del__EszFirewallDConfigIcmpType.__del__cCs|j�dS)N)Zremove_from_connection)rrrr�
unregisterIsz"FirewallDConfigIcmpType.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrr"r#rZBooleanr$r%�
exceptions�
DBusException)r�
property_namerrr�
_get_propertyQsz%FirewallDConfigIcmpType._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrrr'r(r*)r�interface_namer)�senderrrr�Getbs


zFirewallDConfigIcmpType.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existr"r#rr$r%Zsv)�	signature)r"r#rr$r%)rr.rr/rrrrr'r(r*Z
Dictionary)rr0r1�ret�xrrr�GetAllss

zFirewallDConfigIcmpType.GetAllZssv)r,cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr.rr/rr�accessCheckrrrr'r()rr0r)Z	new_valuer1rrr�Set�s



zFirewallDConfigIcmpType.Setzsa{sv}as)r4cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr.rr/r)rr0Zchanged_propertiesZinvalidated_propertiesrrr�PropertiesChanged�s


z)FirewallDConfigIcmpType.PropertiesChanged)r-cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rrr�
IntrospectrrZget_busrrrr)rr1�data)rrrr;�s

z"FirewallDConfigIcmpType.IntrospectcCstjd|j�|jj|j�S)z"get settings for icmptype
        z%s.getSettings())rr/rrZget_icmptype_configr)rr1rrr�getSettings�sz#FirewallDConfigIcmpType.getSettingscCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)z%update settings for icmptype
        z%s.update('...')N)rrr/rrr8rZset_icmptype_configr�Updatedr")r�settingsr1rrr�update�s
zFirewallDConfigIcmpType.updatecCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z3load default settings for builtin icmptype
        z%s.loadDefaults()N)
rr/rrr8rZload_icmptype_defaultsrr>r")rr1rrr�loadDefaults�sz$FirewallDConfigIcmpType.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr/r)rr"rrrr>�szFirewallDConfigIcmpType.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove icmptype
        z%s.removeIcmpType()N)	rr/rrr8rZremove_icmptyperZremoveIcmpType)rr1rrr�remove�szFirewallDConfigIcmpType.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr/r)rr"rrr�Removed�szFirewallDConfigIcmpType.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename icmptype
        z%s.rename('%s')N)rr.rr/rrr8rZrename_icmptyper�Renamed)rr"r1rrr�rename�s

zFirewallDConfigIcmpType.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr/r)rr"rrrrD�szFirewallDConfigIcmpType.RenamedcCstjd|j�|j�dS)Nz%s.getVersion()r)rr/rr=)rr1rrr�
getVersion�sz"FirewallDConfigIcmpType.getVersioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setVersion('%s')r)
rr.rr/rrr8�listr=r@)r�versionr1r?rrr�
setVersions
z"FirewallDConfigIcmpType.setVersioncCstjd|j�|j�dS)Nz
%s.getShort()r)rr/rr=)rr1rrr�getShortsz FirewallDConfigIcmpType.getShortcCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setShort('%s')r)
rr.rr/rrr8rGr=r@)rZshortr1r?rrr�setShorts
z FirewallDConfigIcmpType.setShortcCstjd|j�|j�dS)Nz%s.getDescription()�)rr/rr=)rr1rrr�getDescription$sz&FirewallDConfigIcmpType.getDescriptioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setDescription('%s')rL)
rr.rr/rrr8rGr=r@)r�descriptionr1r?rrr�setDescription+s

z&FirewallDConfigIcmpType.setDescription�ascCstjd|j�t|j�d�S)Nz%s.getDestinations()�)rr/r�sortedr=)rr1rrr�getDestinations9sz'FirewallDConfigIcmpType.getDestinationscCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setDestinations('[%s]')�,rQ)
rrGrr/r�joinrr8r=r@)rZdestinationsr1r?rrr�setDestinations@s

z'FirewallDConfigIcmpType.setDestinationscCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addDestination('%s')rQ)rr.rr/rrr8rGr=r
rZALREADY_ENABLED�appendr@)r�destinationr1r?rrr�addDestinationLs

z&FirewallDConfigIcmpType.addDestinationcCs�t|t�}tjd|j|�|jj|�t|j��}|drd||dkrTt	t
j|��q�|dj|�ntt
ddg�t
|g��|d<|j|�dS)Nz%s.removeDestination('%s')rQZipv4Zipv6)rr.rr/rrr8rGr=r
rZNOT_ENABLEDrB�setr@)rrXr1r?rrr�removeDestinationZs

z)FirewallDConfigIcmpType.removeDestination�bcCs8t|t�}tjd|j|�|j�}|dp6||dkS)Nz%s.queryDestination('%s')rQ)rr.rr/rr=)rrXr1r?rrr�queryDestinationms


z(FirewallDConfigIcmpType.queryDestination)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)4�__name__�
__module__�__qualname__�__doc__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredr	rr
r r!r*rZPROPERTIES_IFACEr2r7�slipZpolkitZrequire_authr9�service�signalr:ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr;rrZDBUS_SIGNATUREr=r@rAr>rBrCrErDrFrIrJrKrMrOrSrVrYr[r]�
__classcell__rr)rrr0s�
		

	

	r)Z
gi.repositoryr�sys�modulesrZdbus.serviceZ	slip.dbusrbZslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.io.icmptyperZfirewall.core.loggerrZfirewall.server.decoratorsr	r
rrZfirewall.errorsr
rcZObjectrrrrr�<module>s
server/__pycache__/firewalld.cpython-36.pyc000064400000217455150351351720014701 0ustar003

��gb��@sVdgZddlmZmZddlZeejd<ddlZddlZddlZddl	Z
ddlZ
ddlm
Z
ddlmZddlmZddlmZdd	lmZdd
lmZmZmZmZddlmZddlmZmZm Z m!Z!m"Z"m#Z#m$Z$dd
l%m&Z&ddl'm(Z(ddl)m*Z*ddl+m,Z,ddl-m.Z.m/Z/m0Z0ddl1m2Z2ddlm3Z3ddl4m5Z5Gdd�de
jj6j7�Z8dS)�	FirewallD�)�GLib�GObjectNZgobject)�config)�Firewall)�	Rich_Rule)�log)�FirewallClientZoneSettings)�dbus_handle_exceptions�dbus_service_method�handle_exceptions�FirewallDBusException)�FirewallDConfig)�dbus_to_python�command_of_sender�context_of_sender�
uid_of_sender�user_of_uid�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�check_config)�IPSet)�IcmpType)�Helper)�nm_get_bus_name�nm_get_connection_of_interface�nm_set_zone_of_connection)�ifcfg_set_zone_of_interface)�errors)�
FirewallErrorcs�"eZdZdZdZejjZe	�fdd��Z
dd�Ze	dd��Ze	d	d
��Z
edd��Zed
d��Zedd��Zedd��Zedd��Zeejddd�e�d�dd���Zeejddd�e�d�dd���Zejjjejj�eejdd �e�d�d!d"����Zejjejd#d$�d%d&��Zejjjejj�eej dd'�e�d��fd(d)�	���Z!ejjjejj�eejj"d*d*d�e�d�d+d,����Z#ejjjejj�eejj"d*d*d�e�d�d-d.����Z$ejjejj"�ed/d0���Z%ejjjejj�eejj"d*d*d�e�d�d1d2����Z&ejjjejj�eejj"d*d*d�e�d�d3d4����Z'ejjjejj(�eejj)d*d*d�e�d�d5d6����Z*ejjjejj(�eejj)d*d*d�e�d�d7d8����Z+ejjjejj,�eejj)d*d9d�e�d�d:d;����Z-ejjejj)d*d$�ed<d=���Z.ejjejj)d*d$�ed>d?���Z/ejjjejj(�eejj)dd*d�e�d�d@dA����Z0ejjjejj(�eejj)dd*d�e�d�dBdC����Z1ejjjejj,�eejj)dd9d�e�d�dDdE����Z2ejjjejj,�eejj)d*dFd�e�d�dGdH����Z3ejjejj)dd$�edIdJ���Z4ejjejj)dd$�edKdL���Z5ejjjejj(�eejj)dMd*d�e�d�dNdO����Z6ejjjejj(�eejj)dMd*d�e�d�dPdQ����Z7ejjjejj,�eejj)dMd9d�e�d�dRdS����Z8ejjjejj,�eejj)d*dTd�e�d�dUdV����Z9ejjejj)dMd$�edWdX���Z:ejjejj)dMd$�edYdZ���Z;ejjjejj(�eejj)dd*d�e�d�d[d\����Z<ejjjejj(�eejj)dd*d�e�d�d]d^����Z=ejjjejj,�eejj)dd9d�e�d�d_d`����Z>ejjjejj,�eejj)d*dFd�e�d�dadb����Z?ejjejj)dd$�edcdd���Z@ejjejj)dd$�ededf���ZAejjjejj(�eejj)dd*d�e�d�dgdh����ZBejjjejj(�eejj)dd*d�e�d�didj����ZCejjjejj,�eejj)dd9d�e�d�dkdl����ZDejjjejj,�eejj)d*dFd�e�d�dmdn����ZEejjejj)dd$�edodp���ZFejjejj)dd$�edqdr���ZGejjjejj�eejj"d*d*d�e�d�dsdt����ZHejjjejj�eejj"d*d*d�e�d�dudv����ZIejjjejj�eejj"d*d9d�e�d�dwdx����ZJejjejj"d*d$�edydz���ZKejjejj"d*d$�ed{d|���ZLejjjejjM�eejj"dd}d�e�d�d~d����ZNejjjejjM�eejjOddd�e�d�d�d�����ZPejjjejjM�eejjOd�d �e�d�d�d�����ZQejjejjOd�d$�ed�d����ZRejjjejjM�eejjSddd�e�d�d�d�����ZTejjjejjM�eejjSd�d �e�d�d�d�����ZUejjejjSd�d$�ed�d����ZVejjjejj�eejj"d*dFd�e�d�d�d�����ZWejjjejjM�eejj"dd�d�e�d�d�d�����ZXejjjejjM�eejj"ddd�e�d�d�d�����ZYejjjejj�eejj"d*dFd�e�d�d�d�����ZZejjjejjM�eejj"de[j\d�e�d�d�d�����Z]ejjjejjM�eejj"d*dd�e�d�d�d�����Z^ejjjejj�eejj"dd*d�e�d�d�d�����Z_ejjejj"dd$�ed�d����Z`ejjjejjM�eejj"d*dd�e�d�d�d�����Zaejjjejj�eejj"dd*d�e�d�d�d�����Zbejjejj"dd$�ed�d����Zcejjjejj�eejj"d*dd�e�d�d�d�����Zdejjjejj�eejj"dd*d�e�d�d�d�����Zeejjejj"dd$�ed�d����Zfejjjejj�eejjSd*dFd�e�d�d�d�����Zgejjjejj�eejjSd*d�d�e�d�d�d�����Zhejjjejj�eejjOd*dFd�e�d�d�d�����Ziejjjejj�eejjOd*d�d�e�d�d�d�����Zjejjjejj�eejjOddd�e�d�d�d�����Zkejjjejj�eejjOddd�e�d�d�d�����ZlejjjejjM�eejjOdd9d�e�d�d�d�����Zmejjjejj�eejjOddd�e�d�d�d�����Znejjjejj�eejjOddd�e�d�d�d�����Zoejjjejj�eejjOddd�e�d�d�d�����Zpejjjejj�eejjOddd�e�d�d�d�����ZqejjjejjM�eejjOdd9d�e�d�d�d„���ZrejjjejjM�eejjOddFd�e�d�d�dĄ���ZsejjejjOdd$�ed�dƄ��ZtejjejjOdd$�ed�dȄ��ZuejjejjOdd$�ed�dʄ��ZvejjejjOdd$�ed�d̄��Zwejjjejj�eejjOddd�e�d�d�d΄���Zxejjjejj�eejjOddd�e�d�d�dЄ���Zyejjjejj�eejjOddd�e�d�d�d҄���ZzejjjejjM�eejjOdd9d�e�d�d�dԄ���Z{ejjjejjM�eejjOddFd�e�d�d�dք���Z|ejjejjOdd$�ed�d؄��Z}ejjejjOdd$�ed�dڄ��Z~ejjejjOdd$�ed�d܄��Zed�dބ�Z�ejjjejj�eejjOd�dd�e�d�d�d����Z�ejjjejj�eejjOddd�e�d�d�d����Z�ejjjejjM�eejjOdd9d�e�d�d�d����Z�ejjjejjM�eejjOddFd�e�d�d�d����Z�ejjejjOd�d$�ed�d���Z�ejjejjOdd$�ed�d���Z�ed�d��Z�ejjjejj�eejjOd�dd�e�d�d�d����Z�ejjjejj�eejjOddd�e�d�d�d����Z�ejjjejjM�eejjOdd9d�e�d�d�d����Z�ejjjejjM�eejjOddFd�e�d�d�d�����Z�ejjejjOd�d$�ed�d����Z�ejjejjOdd$�ed�d����Z�ed�d���Z�ejjjejj�eejjOd�dd�e�d�d�d�����Z�ejjjejj�eejjOd�dd�e�d��d�d����Z�ejjjejjM�eejjOd�d9d�e�d��d�d����Z�ejjjejjM�eejjOd�dd�e�d��d�d����Z�ejjejjOd�d$�e�d��d�d	���Z�ejjejjOd�d$�e�d
�d���Z�e�d�d
��Z�ejjjejj�eejjOd�dd�e�d��d�d����Z�ejjjejj�eejjOddd�e�d��d�d����Z�ejjjejjM�eejjOdd9d�e�d��d�d����Z�ejjjejjM�eejjOddFd�e�d��d�d����Z�ejjejjOd�d$�e�d��d�d���Z�ejjejjOdd$�e�d�d���Z�e�d�d��Z�ejjjejj�eejjOd�dd�e�d��d�d����Z�ejjjejj�eejjOd�dd�e�d�d�d����Z�ejjjejjM�eejjOd�d9d�e�d�d �d!����Z�ejjjejjM�eejjOd�dd�e�d�d"�d#����Z�ejjejjOd�d$�e�d�d$�d%���Z�ejjejjOd�d$�e�d&�d'���Z�e�d(�d)��Z�ejjjejj�eejjO�d*dd�e�d�d+�d,����Z�ejjjejj�eejjOddd�e�d�d-�d.����Z�ejjjejjM�eejjOdd9d�e�d�d/�d0����Z�ejjejjO�d*d$�e�d�d1�d2���Z�ejjejjOdd$�e�d3�d4���Z�e�d5�d6��Z�ejjjejj�eejjO�d7dd�e�d�d8�d9����Z�ejjjejj�eejjO�d:dd�e�d	�d;�d<����Z�ejjjejjM�eejjO�d:d9d�e�d
�d=�d>����Z�ejjjejjM�eejjOd�dd�e�d�d?�d@����Z�ejjejjO�d7d$�e�d�dA�dB���Z�ejjejjO�d:d$�e�dC�dD���Z�e�dE�dF��Z�ejjjejj�eejjOd�dd�e�d
�dG�dH����Z�ejjjejj�eejjOddd�e�d�dI�dJ����Z�ejjjejjM�eejjOdd9d�e�d�dK�dL����Z�ejjjejjM�eejjOddFd�e�d�dM�dN����Z�ejjejjOd�d$�e�d�dO�dP���Z�ejjejjOdd$�e�dQ�dR���Z�ejjjejj�eejjOddd�e�d�dS�dT����Z�ejjjejj�eejjOddd�e�d�dU�dV����Z�ejjjejjM�eejjOdd9d�e�d�dW�dX����Z�ejjejjOdd$�e�dY�dZ���Z�ejjejjOdd$�e�d[�d\���Z�ejjjejj��eejj�d�d*d�e�d�d]�d^����Z�ejjjejj��eejj�d�d*d�e�d�d_�d`����Z�ejjjejj��eejj�d�d9d�e�d�da�db����Z�ejjjejj��eejj�ddFd�e�d�dc�dd����Z�ejjjejj��eejj�d*�ded�e�d�df�dg����Z�ejjejj�d�d$�e�dh�di���Z�ejjejj�d�d$�e�dj�dk���Z�ejjjejj��eejj��dld*d�e�d�dm�dn����Z�ejjjejj��eejj��dld*d�e�d�do�dp����Z�ejjjejj��eejj�d�d*d�e�d�dq�dr����Z�ejjjejj��eejj��dld9d�e�d�ds�dt����Z�ejjjejj��eejj�d��dud�e�d�dv�dw����Z�ejjjejj��eejj�d*�dxd�e�d�dy�dz����Z�ejjejj��dld$�e�d{�d|���Z�ejjejj��dld$�e�d}�d~���Z�ejjjejj��eejj��ddd�e�d �d��d�����Z�ejjjejj��eejj��dd*d�e�d!�d��d�����Z�ejjjejj��eejj��dd*d�e�d"�d��d�����Z�ejjjejj��eejj��dd9d�e�d#�d��d�����Z�ejjjejj��eejj�d*�d�d�e�d$�d��d�����Z�ejjjejj��eejj�d*d*d�e�d%�d��d�����Z�ejjjejj��eejj�d�dd�e�d&�d��d�����Z�ejjejj��dd$�e�d��d����Z�ejjejj��dd$�e�d��d����Z�ejjjejj׃eejj"d*d*d�e�d'�d��d�����Z�ejjjejj�eejj�dd9d�e�d(�d��d�����Z�ejjjejj�eejj�d*dFd�e�d)�d��d�����Z�ejjjejjM�eejj�de�j\d�e�d*�d��d�����Z�ejjjejj�eejj�dd*d�e�d+�d��d�����Z�ejjjejj�eejj�dd*d�e�d,�d��d�����Z�ejjjejj�eejj�dd9d�e�d-�d��d�����Z�ejjjejj�eejj�ddFd�e�d.�d��d�����Z�ejjjejj�eejjِdd �e�d/�d��d�����Z�ejjejj�dd$�e�d��d����Z�ejjejj�dd$�e�d��d����Z�ejjjejj�eejj"d*dFd�e�d0�d��d�����Z�ejjjejjM�eejj"de�j\d�e�d1�d��d�����Z�Z�S(2rzFirewallD main classTcs`tt|�j||�t�|_|d|_|d|_|j�t|t	j
j�t|jj	|jt	j
j
�|_	dS)Nr�)�superr�__init__r�fw�busname�path�startrr�dbus�DBUS_INTERFACErZDBUS_PATH_CONFIG)�self�args�kwargs)�	__class__��/usr/lib/python3.6/firewalld.pyr"Is

zFirewallD.__init__cCs|j�dS)N)�stop)r)r-r-r.�__del__TszFirewallD.__del__cCstjd�i|_|jj�S)Nzstart())r�debug1�	_timeoutsr#r&)r)r-r-r.r&Ws
zFirewallD.startcCstjd�|jj�S)Nzstop())rr1r#r/)r)r-r-r.r/_s
zFirewallD.stopcCs�|jjj�r�|dkr"tjd�dStj�}t||�}|jjjd|�rHdSt	||�}|jjjd|�rfdSt
|�}|jjjd|�r�dSt||�}|jjjd|�r�dStt
jd��dS)Nz&Lockdown not possible, sender not set.�context�uid�user�commandzlockdown is enabled)r#�policies�query_lockdownr�errorr'Z	SystemBusrZaccess_checkrrrrrZ
ACCESS_DENIED)r)�senderZbusr3r4r5r6r-r-r.�accessCheckhs$



zFirewallD.accessCheckcCs&||jkri|j|<||j||<dS)N)r2)r)�zone�x�tagr-r-r.�
addTimeouts

zFirewallD.addTimeoutcCs<||jkr8||j|kr8tj|j||�|j||=dS)N)r2r�
source_remove)r)r<r=r-r-r.�
removeTimeout�szFirewallD.removeTimeoutcCsTxD|jD]:}x&|j|D]}tj|j||�qW|j|j�qW|jj�dS)N)r2rr@�clear)r)r<r=r-r-r.�cleanup_timeouts�s
zFirewallD.cleanup_timeoutscCsd|dkrtjtj�S|dkr6tjdtjjtjjf�S|dkrNtj|jj��S|dkrhtj|jj	d��S|dkr�tj
|jjd�S|d	kr�tj|jj	d
��S|dkr�tj|jj�S|dkr�tj
|jj
d�S|d
kr�tj|jj�S|dk�r�tj|jj�S|dk�rtj
|jjd�S|dk�r$tjd�S|dk�r:tjid�S|dk�rPtjid�Stjjd|��dS)N�version�interface_versionz%d.%d�state�IPv4�ipv4�
IPv4ICMPTypes�s�IPv6�ipv6�
IPv6_rpfilter�
IPv6ICMPTypes�BRIDGEr�
IPSetTypes�nf_conntrack_helper_settingF�nf_conntrack_helpers�sas�nf_nat_helperszDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r'�Stringr�VERSIONZDBUS_INTERFACE_VERSIONZDBUS_INTERFACE_REVISIONr#Z	get_stateZBooleanZis_ipv_enabledZArrayZipv4_supported_icmp_typesZipv6_rpfilter_enabledZipv6_supported_icmp_typesZebtables_enabledZ
ipset_enabledZipset_supported_types�
Dictionary�
exceptions�
DBusException)r)Zpropr-r-r.�
_get_property�s@





zFirewallD._get_propertyZss�v)�in_signature�
out_signatureNcCs~t|t�}t|t�}tjd||�|tjjkr8|j|�S|tjjtjj	tjj
tjjgkrjtjj
d|��ntjj
d|��dS)NzGet('%s', '%s')zDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not existzJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strrr1rr'r(rZ�DBUS_INTERFACE_ZONE�DBUS_INTERFACE_DIRECT�DBUS_INTERFACE_POLICIES�DBUS_INTERFACE_IPSETrXrY)r)�interface_name�
property_namer:r-r-r.�Get�s



z
FirewallD.GetrJza{sv}cCs�t|t�}tjd|�i}|tjjkrDxNdD]}|j|�||<q,Wn2|tjjtjj	tjj
tjjgkrfntjj
d|��tj|dd�S)NzGetAll('%s')rDrErFrGrKrMrOrrPrQrRrTrIrNzJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existZsv)�	signature)rDrErFrGrKrMrOrrPrQrRrTrIrN)rr^rr1rr'r(rZr_r`rarbrXrYrW)r)rcr:�retr=r-r-r.�GetAll�s&
zFirewallD.GetAllZssv)r\cCs�t|t�}t|t�}t|�}tjd|||�|j|�|tjjkrn|dkr\tjj	d|��q�tjj	d|��nB|tjj
tjjtjjtjj
gkr�tjj	d|��ntjj	d|��dS)NzSet('%s', '%s', '%s')rDrErFrGrKrMrOrrPrQrRrTrIrNzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-onlyzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not existzJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)rDrErFrGrKrMrOrrPrQrRrTrIrN)rr^rr1r;rr'r(rXrYr_r`rarb)r)rcrdZ	new_valuer:r-r-r.�Set�s:






z
FirewallD.Setzsa{sv}as)rfcCs.t|t�}t|�}t|�}tjd|||�dS)Nz#PropertiesChanged('%s', '%s', '%s'))rr^rr1)r)rcZchanged_propertiesZinvalidated_propertiesr-r-r.�PropertiesChangeds

zFirewallD.PropertiesChanged)r]cs4tjd�tt|�j|j|jj��}t||t	j
j�S)NzIntrospect())rZdebug2r!r�
Introspectr%r$Zget_busrrr'r()r)r:�data)r,r-r.rk&s

zFirewallD.Introspect�cCs*tjd�|jj�|jj�|j�dS)z#Reload the firewall rules.
        zreload()N)rr1r#�reloadr�Reloaded)r)r:r-r-r.rn4s


zFirewallD.reloadcCs,tjd�|jjd�|jj�|j�dS)z�Completely reload the firewall.

        Completely reload the firewall: Stops firewall, unloads modules and 
        starts the firewall again.
        zcompleteReload()TN)rr1r#rnrro)r)r:r-r-r.�completeReloadCs


zFirewallD.completeReloadcCstjd�dS)Nz
Reloaded())rr1)r)r-r-r.roSszFirewallD.ReloadedcCstjd�t|j�dS)z&Check permanent configuration
        zcheckPermanentConfig()N)rr1rr#)r)r:r-r-r.�checkPermanentConfigXs
zFirewallD.checkPermanentConfigc
Cs�tjd�d}|jj�}x�|jjj�D]�}|j|�}yj||kr�|jj|�}|j	�|krptjd|�|j
|�q�tjd|�ntjd|�|jj||�Wq&tk
r�}ztj
d||f�d}WYdd}~Xq&Xq&W|jj�}x�|jjj�D]�}|j|�}yn||k�rR|jj|�}|j	�|k�rBtjd	|�|j
|�ntjd
|�ntjd|�|jj||�Wq�tk
�r�}ztj
d||f�d}WYdd}~Xq�Xq�W|jj�}x�|jjj�D]�}yx|j|�}||k�r&|jj|�}|j	�|k�rtjd
|�|j
|�ntjd|�ntjd|�|jj||�Wn:tk
�r~}ztj
d||f�d}WYdd}~XnX�q�W|jj�}t�}�x�|jjj�D�]�}|j|�}t|�}	|dk	�r~d}
xH|	j �D]<}|jjj!||�|k�r�tjd||f�|	j"|�d}
�q�WxV|	j �D]J}y,t#|�}|�rNt$||��rN|	j"|�d}
Wntk
�rfYnX�q W|
�r~~|	j%�}x|	j �D]}t&||��q�WyP||k�r�|jj'|�}tjd|�|j(|�ntjd|�|jj)||�Wn:tk
�r&}ztj
d||f�d}WYdd}~XnX�q�W|jj*�}x�|jj+j,�D]�}|j-|�}yB||k�rx|jj.|�}|j
|�ntjd|�|jj/||�Wn:tk
�r�}ztj
d||f�d}WYdd}~XnX�qFW|jj0�}x�|jj1j2�D]�}|j3|�}yn||k�rN|jj4|�}|j	�|k�r>tjd|�|j
|�ntjd|�ntjd|�|jj5||�Wn:tk
�r�}ztj
d||f�d}WYdd}~XnX�q�W|jj6j7�|jj6j8�|jj6j9�f}y6|jj	�|k�r�tjd�|jj
|�n
tjd�Wn6tk
�r<}ztj
d|�d}WYdd}~XnX|jj:j;j<�}y6|jj	�|k�rvtjd�|jj=|�n
tjd�Wn6tk
�r�}ztj
d |�d}WYdd}~XnX|�r�t>t?j@��dS)!z-Make runtime configuration permanent
        zcopyRuntimeToPermanent()FzCopying service '%s' settingsz$Service '%s' is identical, ignoring.zCreating service '%s'z/Runtime To Permanent failed on service '%s': %sTNzCopying icmptype '%s' settingsz%IcmpType '%s' is identical, ignoring.zCreating icmptype '%s'z0Runtime To Permanent failed on icmptype '%s': %szCopying ipset '%s' settingsz"IPSet '%s' is identical, ignoring.zCreating ipset '%s'z-Runtime To Permanent failed on ipset '%s': %szEZone '%s': interface binding for '%s' has been added by NM, ignoring.zCopying zone '%s' settingszCreating zone '%s'z,Runtime To Permanent failed on zone '%s': %szCreating policy '%s'z.Runtime To Permanent failed on policy '%s': %szCopying helper '%s' settingsz#Helper '%s' is identical, ignoring.zCreating helper '%s'z.Runtime To Permanent failed on helper '%s': %szCopying direct configurationz,Direct configuration is identical, ignoring.z7Runtime To Permanent failed on direct configuration: %szCopying policies configurationz.Policies configuration is identical, ignoring.z9Runtime To Permanent failed on policies configuration: %s)Arr1rZgetServiceNamesr#�service�get_services�getServiceSettingsZgetServiceByNameZgetSettings�update�
addService�	Exception�warningZgetIcmpTypeNames�icmptype�
get_icmptypes�getIcmpTypeSettingsZgetIcmpTypeByNameZaddIcmpTypeZ
getIPSetNames�ipset�
get_ipsets�getIPSetSettingsZgetIPSetByNameZaddIPSetZgetZoneNamesrr<�	get_zones�getZoneSettings2r	�
getInterfacesZinterface_get_sender�removeInterfacerrZgetSettingsDictrZ
getZoneByNameZupdate2ZaddZone2ZgetPolicyNames�policy�"get_policies_not_derived_from_zone�getPolicySettingsZgetPolicyByNameZ	addPolicyZgetHelperNames�helper�get_helpers�getHelperSettingsZgetHelperByNameZ	addHelper�direct�get_all_chains�
get_all_rules�get_all_passthroughsr7�lockdown_whitelist�
export_configZsetLockdownWhitelistrrZRT_TO_PERM_FAILED)
r)r:r9Zconfig_names�nameZconfZconf_obj�eZnm_bus_name�settingsZchanged�	interfaceZ
connectionr-r-r.�runtimeToPermanentds$


























zFirewallD.runtimeToPermanentcCs,tjd�|j|�|jjj�|j�dS)z!Enable lockdown policies
        zpolicies.enableLockdown()N)rr1r;r#r7Zenable_lockdown�LockdownEnabled)r)r:r-r-r.�enableLockdown2s

zFirewallD.enableLockdowncCs,tjd�|j|�|jjj�|j�dS)z"Disable lockdown policies
        zpolicies.disableLockdown()N)rr1r;r#r7Zdisable_lockdown�LockdownDisabled)r)r:r-r-r.�disableLockdown>s

zFirewallD.disableLockdown�bcCstjd�|jjj�S)z+Retuns True if lockdown is enabled
        zpolicies.queryLockdown())rr1r#r7r8)r)r:r-r-r.�
queryLockdownJs
zFirewallD.queryLockdowncCstjd�dS)NzLockdownEnabled())rr1)r)r-r-r.r�UszFirewallD.LockdownEnabledcCstjd�dS)NzLockdownDisabled())rr1)r)r-r-r.r�ZszFirewallD.LockdownDisabledcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zAdd lockdown command
        z*policies.addLockdownWhitelistCommand('%s')N)
rr^rr1r;r#r7r�Zadd_command�LockdownWhitelistCommandAdded)r)r6r:r-r-r.�addLockdownWhitelistCommandcs


z%FirewallD.addLockdownWhitelistCommandcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)z Remove lockdown command
        z-policies.removeLockdownWhitelistCommand('%s')N)
rr^rr1r;r#r7r�Zremove_command�LockdownWhitelistCommandRemoved)r)r6r:r-r-r.�removeLockdownWhitelistCommandps


z(FirewallD.removeLockdownWhitelistCommandcCs(t|t�}tjd|�|jjjj|�S)zQuery lockdown command
        z,policies.queryLockdownWhitelistCommand('%s'))rr^rr1r#r7r�Zhas_command)r)r6r:r-r-r.�queryLockdownWhitelistCommand}s
z'FirewallD.queryLockdownWhitelistCommand�ascCstjd�|jjjj�S)zAdd lockdown command
        z'policies.getLockdownWhitelistCommands())rr1r#r7r�Zget_commands)r)r:r-r-r.�getLockdownWhitelistCommands�s
z&FirewallD.getLockdownWhitelistCommandscCstjd|�dS)Nz#LockdownWhitelistCommandAdded('%s'))rr1)r)r6r-r-r.r��sz'FirewallD.LockdownWhitelistCommandAddedcCstjd|�dS)Nz%LockdownWhitelistCommandRemoved('%s'))rr1)r)r6r-r-r.r��sz)FirewallD.LockdownWhitelistCommandRemoved�icCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zAdd lockdown uid
        z&policies.addLockdownWhitelistUid('%s')N)
r�intrr1r;r#r7r�Zadd_uid�LockdownWhitelistUidAdded)r)r4r:r-r-r.�addLockdownWhitelistUid�s


z!FirewallD.addLockdownWhitelistUidcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zRemove lockdown uid
        z)policies.removeLockdownWhitelistUid('%s')N)
rr�rr1r;r#r7r�Z
remove_uid�LockdownWhitelistUidRemoved)r)r4r:r-r-r.�removeLockdownWhitelistUid�s


z$FirewallD.removeLockdownWhitelistUidcCs(t|t�}tjd|�|jjjj|�S)zQuery lockdown uid
        z(policies.queryLockdownWhitelistUid('%s'))rr�rr1r#r7r�Zhas_uid)r)r4r:r-r-r.�queryLockdownWhitelistUid�s
z#FirewallD.queryLockdownWhitelistUidZaicCstjd�|jjjj�S)zAdd lockdown uid
        z#policies.getLockdownWhitelistUids())rr1r#r7r�Zget_uids)r)r:r-r-r.�getLockdownWhitelistUids�s
z"FirewallD.getLockdownWhitelistUidscCstjd|�dS)NzLockdownWhitelistUidAdded(%d))rr1)r)r4r-r-r.r��sz#FirewallD.LockdownWhitelistUidAddedcCstjd|�dS)NzLockdownWhitelistUidRemoved(%d))rr1)r)r4r-r-r.r��sz%FirewallD.LockdownWhitelistUidRemovedcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zAdd lockdown user
        z'policies.addLockdownWhitelistUser('%s')N)
rr^rr1r;r#r7r�Zadd_user�LockdownWhitelistUserAdded)r)r5r:r-r-r.�addLockdownWhitelistUser�s


z"FirewallD.addLockdownWhitelistUsercCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zRemove lockdown user
        z*policies.removeLockdownWhitelistUser('%s')N)
rr^rr1r;r#r7r�Zremove_user�LockdownWhitelistUserRemoved)r)r5r:r-r-r.�removeLockdownWhitelistUser�s


z%FirewallD.removeLockdownWhitelistUsercCs(t|t�}tjd|�|jjjj|�S)zQuery lockdown user
        z)policies.queryLockdownWhitelistUser('%s'))rr^rr1r#r7r�Zhas_user)r)r5r:r-r-r.�queryLockdownWhitelistUser�s
z$FirewallD.queryLockdownWhitelistUsercCstjd�|jjjj�S)zAdd lockdown user
        z$policies.getLockdownWhitelistUsers())rr1r#r7r�Z	get_users)r)r:r-r-r.�getLockdownWhitelistUserss
z#FirewallD.getLockdownWhitelistUserscCstjd|�dS)Nz LockdownWhitelistUserAdded('%s'))rr1)r)r5r-r-r.r�sz$FirewallD.LockdownWhitelistUserAddedcCstjd|�dS)Nz"LockdownWhitelistUserRemoved('%s'))rr1)r)r5r-r-r.r�sz&FirewallD.LockdownWhitelistUserRemovedcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)zAdd lockdown context
        z*policies.addLockdownWhitelistContext('%s')N)
rr^rr1r;r#r7r�Zadd_context�LockdownWhitelistContextAdded)r)r3r:r-r-r.�addLockdownWhitelistContexts


z%FirewallD.addLockdownWhitelistContextcCs@t|t�}tjd|�|j|�|jjjj|�|j	|�dS)z Remove lockdown context
        z-policies.removeLockdownWhitelistContext('%s')N)
rr^rr1r;r#r7r�Zremove_context�LockdownWhitelistContextRemoved)r)r3r:r-r-r.�removeLockdownWhitelistContext's


z(FirewallD.removeLockdownWhitelistContextcCs(t|t�}tjd|�|jjjj|�S)zQuery lockdown context
        z,policies.queryLockdownWhitelistContext('%s'))rr^rr1r#r7r�Zhas_context)r)r3r:r-r-r.�queryLockdownWhitelistContext4s
z'FirewallD.queryLockdownWhitelistContextcCstjd�|jjjj�S)zAdd lockdown context
        z'policies.getLockdownWhitelistContexts())rr1r#r7r�Zget_contexts)r)r:r-r-r.�getLockdownWhitelistContexts@s
z&FirewallD.getLockdownWhitelistContextscCstjd|�dS)Nz#LockdownWhitelistContextAdded('%s'))rr1)r)r3r-r-r.r�Ksz'FirewallD.LockdownWhitelistContextAddedcCstjd|�dS)Nz%LockdownWhitelistContextRemoved('%s'))rr1)r)r3r-r-r.r�Psz)FirewallD.LockdownWhitelistContextRemovedcCs*tjd�|j|�|jj�|j�dS)znEnable panic mode.
        
        All ingoing and outgoing connections and packets will be blocked.
        zenablePanicMode()N)rr1r;r#Zenable_panic_mode�PanicModeEnabled)r)r:r-r-r.�enablePanicModeYs	


zFirewallD.enablePanicModecCs*tjd�|j|�|jj�|j�dS)z�Disable panic mode.

        Enables normal mode: Allowed ingoing and outgoing connections 
        will not be blocked anymore
        zdisablePanicMode()N)rr1r;r#Zdisable_panic_mode�PanicModeDisabled)r)r:r-r-r.�disablePanicModegs



zFirewallD.disablePanicModecCstjd�|jj�S)NzqueryPanicMode())rr1r#Zquery_panic_mode)r)r:r-r-r.�queryPanicModevs
zFirewallD.queryPanicModecCstjd�dS)NzPanicModeEnabled())rr1)r)r-r-r.r�szFirewallD.PanicModeEnabledcCstjd�dS)NzPanicModeDisabled())rr1)r)r-r-r.r��szFirewallD.PanicModeDisabledz&(sssbsasa(ss)asba(ssss)asasasasa(ss)b)cCs$t|t�}tjd|�|jjj|�S)NzgetZoneSettings(%s))rr^rr1r#r<Zget_config_with_settings)r)r<r:r-r-r.�getZoneSettings�s
zFirewallD.getZoneSettingscCs$t|t�}tjd|�|jjj|�S)NzgetZoneSettings2(%s))rr^rr1r#r<�get_config_with_settings_dict)r)r<r:r-r-r.r��s
zFirewallD.getZoneSettings2zsa{sv}cCsBt|t�}tjd|�|j|�|jjj|||�|j||�dS)NzsetZoneSettings2(%s))	rr^rr1r;r#r<�set_config_with_settings_dict�ZoneUpdated)r)r<r�r:r-r-r.�setZoneSettings2�s


zFirewallD.setZoneSettings2cCstjd||f�dS)Nzzone.ZoneUpdated('%s', '%s'))rr1)r)r<r�r-r-r.r��szFirewallD.ZoneUpdatedcCs$t|t�}tjd|�|jjj|�S)Nzpolicy.getPolicySettings(%s))rr^rr1r#r�r�)r)r�r:r-r-r.r��s
zFirewallD.getPolicySettingscCsBt|t�}tjd|�|j|�|jjj|||�|j||�dS)Nzpolicy.setPolicySettings(%s))	rr^rr1r;r#r�r��
PolicyUpdated)r)r�r�r:r-r-r.�setPolicySettings�s


zFirewallD.setPolicySettingscCstjd||f�dS)Nz policy.PolicyUpdated('%s', '%s'))rr1)r)r�r�r-r-r.r��szFirewallD.PolicyUpdatedcCstjd�|jjj�S)NzlistServices())rr1r#rrrs)r)r:r-r-r.�listServices�s
zFirewallD.listServicesz(sssa(ss)asa{ss}asa(ss))cCs�t|t�}tjd|�|jjj|�}|j�}g}x\td�D]P}|j	|d|krr|j
tjt
||j	|d���q:|j
||j	|d�q:Wt|�S)NzgetServiceSettings(%s)�r)rr^rr1r#rr�get_service�export_config_dict�rangeZIMPORT_EXPORT_STRUCTURE�append�copy�deepcopy�getattr�tuple)r)rrr:�objZ	conf_dictZ	conf_listr�r-r-r.rt�s
"zFirewallD.getServiceSettingscCs,t|t�}tjd|�|jjj|�}|j�S)NzgetServiceSettings2(%s))rr^rr1r#rrr�r�)r)rrr:r�r-r-r.�getServiceSettings2�s
zFirewallD.getServiceSettings2cCstjd�|jjj�S)NzlistIcmpTypes())rr1r#ryrz)r)r:r-r-r.�
listIcmpTypes�s
zFirewallD.listIcmpTypescCs(t|t�}tjd|�|jjj|�j�S)NzgetIcmpTypeSettings(%s))rr^rr1r#ryZget_icmptyper�)r)ryr:r-r-r.r{�s
zFirewallD.getIcmpTypeSettingscCstjd�|jj�S)NzgetLogDenied())rr1r#Zget_log_denied)r)r:r-r-r.�getLogDenied	s
zFirewallD.getLogDeniedcCsXt|t�}tjd|�|j|�|jj|�|j|�|jj�|j	j�|j
�dS)NzsetLogDenied('%s'))rr^rr1r;r#Zset_log_denied�LogDeniedChangedrnrro)r)�valuer:r-r-r.�setLogDenieds




zFirewallD.setLogDeniedcCstjd|�dS)NzLogDeniedChanged('%s'))rr1)r)r�r-r-r.r�"szFirewallD.LogDeniedChangedcCstjd�dS)NzgetAutomaticHelpers()�no)rr1)r)r:r-r-r.�getAutomaticHelpers+s
zFirewallD.getAutomaticHelperscCs&t|t�}tjd|�|j|�dS)NzsetAutomaticHelpers('%s'))rr^rr1r;)r)r�r:r-r-r.�setAutomaticHelpers6s
zFirewallD.setAutomaticHelperscCstjd|�dS)NzAutomaticHelpersChanged('%s'))rr1)r)r�r-r-r.�AutomaticHelpersChangedBsz!FirewallD.AutomaticHelpersChangedcCstjd�|jj�S)NzgetDefaultZone())rr1r#Zget_default_zone)r)r:r-r-r.�getDefaultZoneKs
zFirewallD.getDefaultZonecCs<t|t�}tjd|�|j|�|jj|�|j|�dS)NzsetDefaultZone('%s'))rr^rr1r;r#Zset_default_zone�DefaultZoneChanged)r)r<r:r-r-r.�setDefaultZoneTs


zFirewallD.setDefaultZonecCstjd|�dS)NzDefaultZoneChanged('%s'))rr1)r)r<r-r-r.r�`szFirewallD.DefaultZoneChangedcCstjd�|jjj�S)Nzpolicy.getPolicies())rr1r#r�r�)r)r:r-r-r.�getPoliciesks
zFirewallD.getPoliciesz
a{sa{sas}}cCs\tjd�i}xH|jjj�D]8}i||<|jjj|�||d<|jjj|�||d<qW|S)Nzpolicy.getActivePolicies()Z
ingress_zonesZegress_zones)rr1r#r�Z)get_active_policies_not_derived_from_zoneZlist_ingress_zonesZlist_egress_zones)r)r:r7r�r-r-r.�getActivePoliciesss
zFirewallD.getActivePoliciescCstjd�|jjj�S)Nzzone.getZones())rr1r#r<r)r)r:r-r-r.�getZones�s
zFirewallD.getZonescCs�tjd�i}x||jjj�D]l}|jjj|�}|jjj|�}t|�t|�dkri||<t|�dkrp|||d<t|�dkr|||d<qW|S)Nzzone.getActiveZones()r�
interfaces�sources)rr1r#r<r�list_interfaces�list_sources�len)r)r:Zzonesr<r�r�r-r-r.�getActiveZones�s
zFirewallD.getActiveZonescCs2t|t�}tjd|�|jjj|�}|r.|SdS)z�Return the zone an interface belongs to.

        :Parameters:
            `interface` : str
                Name of the interface
        :Returns: str. The name of the zone.
        zzone.getZoneOfInterface('%s')rm)rr^rr1r#r<Zget_zone_of_interface)r)r�r:r<r-r-r.�getZoneOfInterface�s
zFirewallD.getZoneOfInterfacecCs2t|t�}tjd|�|jjj|�}|r.|SdS)Nzzone.getZoneOfSource('%s')rm)rr^rr1r#r<Zget_zone_of_source)r)�sourcer:r<r-r-r.�getZoneOfSource�s
zFirewallD.getZoneOfSourcecCsdS)NFr-)r)r<r:r-r-r.�isImmutable�szFirewallD.isImmutablecCsRt|t�}t|t�}tjd||f�|j|�|jjj|||�}|j||�|S)zPAdd an interface to a zone.
        If zone is empty, use default zone.
        zzone.addInterface('%s', '%s'))	rr^rr1r;r#r<Z
add_interface�InterfaceAdded)r)r<r�r:�_zoner-r-r.�addInterface�s


zFirewallD.addInterfacecCs"t|t�}t|t�}|j|||�S)z�Change a zone an interface is part of.
        If zone is empty, use default zone.

        This function is deprecated, use changeZoneOfInterface instead
        )rr^�changeZoneOfInterface)r)r<r�r:r-r-r.�
changeZone�s


zFirewallD.changeZonecCsRt|t�}t|t�}tjd||f�|j|�|jjj|||�}|j||�|S)z[Change a zone an interface is part of.
        If zone is empty, use default zone.
        z&zone.changeZoneOfInterface('%s', '%s'))	rr^rr1r;r#r<Zchange_zone_of_interface�ZoneOfInterfaceChanged)r)r<r�r:r�r-r-r.r��s


zFirewallD.changeZoneOfInterfacecCsPt|t�}t|t�}tjd||f�|j|�|jjj||�}|j||�|S)zkRemove interface from a zone.
        If zone is empty, remove from zone the interface belongs to.
        z zone.removeInterface('%s', '%s'))	rr^rr1r;r#r<Zremove_interface�InterfaceRemoved)r)r<r�r:r�r-r-r.r��s


zFirewallD.removeInterfacecCs6t|t�}t|t�}tjd||f�|jjj||�S)z^Return true if an interface is in a zone.
        If zone is empty, use default zone.
        zzone.queryInterface('%s', '%s'))rr^rr1r#r<Zquery_interface)r)r<r�r:r-r-r.�queryInterfaces

zFirewallD.queryInterfacecCs&t|t�}tjd|�|jjj|�S)z]Return the list of interfaces of a zone.
        If zone is empty, use default zone.
        zzone.getInterfaces('%s'))rr^rr1r#r<r�)r)r<r:r-r-r.r�s

zFirewallD.getInterfacescCstjd||f�dS)Nzzone.InterfaceAdded('%s', '%s'))rr1)r)r<r�r-r-r.r�+szFirewallD.InterfaceAddedcCstjd||f�dS)z,
        This signal is deprecated.
        zzone.ZoneChanged('%s', '%s')N)rr1)r)r<r�r-r-r.�ZoneChanged0szFirewallD.ZoneChangedcCs"tjd||f�|j||�dS)Nz'zone.ZoneOfInterfaceChanged('%s', '%s'))rr1r�)r)r<r�r-r-r.r�8s
z FirewallD.ZoneOfInterfaceChangedcCstjd||f�dS)Nz!zone.InterfaceRemoved('%s', '%s'))rr1)r)r<r�r-r-r.r�?szFirewallD.InterfaceRemovedcCsRt|t�}t|t�}tjd||f�|j|�|jjj|||�}|j||�|S)zLAdd a source to a zone.
        If zone is empty, use default zone.
        zzone.addSource('%s', '%s'))	rr^rr1r;r#r<Z
add_source�SourceAdded)r)r<r�r:r�r-r-r.�	addSourceHs


zFirewallD.addSourcecCsRt|t�}t|t�}tjd||f�|j|�|jjj|||�}|j||�|S)zXChange a zone an source is part of.
        If zone is empty, use default zone.
        z#zone.changeZoneOfSource('%s', '%s'))	rr^rr1r;r#r<Zchange_zone_of_source�ZoneOfSourceChanged)r)r<r�r:r�r-r-r.�changeZoneOfSourceYs


zFirewallD.changeZoneOfSourcecCsPt|t�}t|t�}tjd||f�|j|�|jjj||�}|j||�|S)zeRemove source from a zone.
        If zone is empty, remove from zone the source belongs to.
        zzone.removeSource('%s', '%s'))	rr^rr1r;r#r<Z
remove_source�
SourceRemoved)r)r<r�r:r�r-r-r.�removeSourcejs


zFirewallD.removeSourcecCs6t|t�}t|t�}tjd||f�|jjj||�S)z[Return true if an source is in a zone.
        If zone is empty, use default zone.
        zzone.querySource('%s', '%s'))rr^rr1r#r<Zquery_source)r)r<r�r:r-r-r.�querySource{s

zFirewallD.querySourcecCs&t|t�}tjd|�|jjj|�S)zZReturn the list of sources of a zone.
        If zone is empty, use default zone.
        zzone.getSources('%s'))rr^rr1r#r<r�)r)r<r:r-r-r.�
getSources�s

zFirewallD.getSourcescCstjd||f�dS)Nzzone.SourceAdded('%s', '%s'))rr1)r)r<r�r-r-r.r��szFirewallD.SourceAddedcCstjd||f�dS)Nz$zone.ZoneOfSourceChanged('%s', '%s'))rr1)r)r<r�r-r-r.r��szFirewallD.ZoneOfSourceChangedcCstjd||f�dS)Nzzone.SourceRemoved('%s', '%s'))rr1)r)r<r�r-r-r.r��szFirewallD.SourceRemovedcCsHtjd||f�|j||=t|d�}|jjj||�|j||�dS)Nz%zone.disableTimedRichRule('%s', '%s'))�rule_str)rr1r2rr#r<�remove_rule�RichRuleRemoved)r)r<�ruler�r-r-r.�disableTimedRichRule�s

zFirewallD.disableTimedRichRuleZssicCs�t|t�}t|t�}t|t�}tjd||f�t|d�}|jjj|||�}|dkrtt	j
||j||�}|j|||�|j
|||�|S)Nzzone.addRichRule('%s', '%s'))r�r)rr^r�rr1rr#r<�add_ruler�timeout_add_secondsr�r?�
RichRuleAdded)r)r<r��timeoutr:r�r�r>r-r-r.�addRichRule�s




zFirewallD.addRichRulecCs\t|t�}t|t�}tjd||f�t|d�}|jjj||�}|j||�|j	||�|S)Nzzone.removeRichRule('%s', '%s'))r�)
rr^rr1rr#r<r�rAr�)r)r<r�r:r�r�r-r-r.�removeRichRule�s


zFirewallD.removeRichRulecCs@t|t�}t|t�}tjd||f�t|d�}|jjj||�S)Nzzone.queryRichRule('%s', '%s'))r�)rr^rr1rr#r<�
query_rule)r)r<r�r:r�r-r-r.�
queryRichRule�s



zFirewallD.queryRichRulecCs&t|t�}tjd|�|jjj|�S)Nzzone.getRichRules('%s'))rr^rr1r#r<Z
list_rules)r)r<r:r-r-r.�getRichRules�s
zFirewallD.getRichRulescCstjd|||f�dS)Nz"zone.RichRuleAdded('%s', '%s', %d))rr1)r)r<r�r�r-r-r.r��szFirewallD.RichRuleAddedcCstjd||f�dS)Nz zone.RichRuleRemoved('%s', '%s'))rr1)r)r<r�r-r-r.r��szFirewallD.RichRuleRemovedcCs>tjd||f�|j||=|jjj||�|j||�dS)Nz$zone.disableTimedService('%s', '%s'))rr1r2r#r<�remove_service�ServiceRemoved)r)r<rrr-r-r.�disableTimedService�szFirewallD.disableTimedServicecCs�t|t�}t|t�}t|t�}tjd|||f�|j|�|jjj||||�}|dkrxt	j
||j||�}|j|||�|j
|||�|S)Nzzone.addService('%s', '%s', %d)r)rr^r�rr1r;r#r<Zadd_servicerr�rr?�ServiceAdded)r)r<rrr�r:r�r>r-r-r.rv�s




zFirewallD.addServicecCs\t|t�}t|t�}tjd||f�|j|�|jjj||�}|j||�|j	||�|S)Nzzone.removeService('%s', '%s'))
rr^rr1r;r#r<rrAr)r)r<rrr:r�r-r-r.�
removeServices


zFirewallD.removeServicecCs6t|t�}t|t�}tjd||f�|jjj||�S)Nzzone.queryService('%s', '%s'))rr^rr1r#r<Z
query_service)r)r<rrr:r-r-r.�queryService&s

zFirewallD.queryServicecCs&t|t�}tjd|�|jjj|�S)Nzzone.getServices('%s'))rr^rr1r#r<Z
list_services)r)r<r:r-r-r.�getServices1s
zFirewallD.getServicescCstjd|||f�dS)Nz!zone.ServiceAdded('%s', '%s', %d))rr1)r)r<rrr�r-r-r.r=szFirewallD.ServiceAddedcCstjd||f�dS)Nzzone.ServiceRemoved('%s', '%s'))rr1)r)r<rrr-r-r.rCszFirewallD.ServiceRemovedcCsHtjd|||f�|j|||f=|jjj|||�|j|||�dS)Nz'zone.disableTimedPort('%s', '%s', '%s'))rr1r2r#r<�remove_port�PortRemoved)r)r<�port�protocolr-r-r.�disableTimedPortLs
zFirewallD.disableTimedPortZsssicCs�t|t�}t|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||||�}|dkr�t	j
||j|||�}|j|||f|�|j
||||�|S)Nzzone.addPort('%s', '%s', '%s')r)rr^r�rr1r;r#r<Zadd_portrr�rr?�	PortAdded)r)r<rrr�r:r�r>r-r-r.�addPortTs






zFirewallD.addPortZssscCspt|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||�}|j|||f�|j	|||�|S)Nz!zone.removePort('%s', '%s', '%s'))
rr^rr1r;r#r<rrAr
)r)r<rrr:r�r-r-r.�
removePortks



zFirewallD.removePortcCsDt|t�}t|t�}t|t�}tjd|||f�|jjj|||�S)Nz zone.queryPort('%s', '%s', '%s'))rr^rr1r#r<Z
query_port)r)r<rrr:r-r-r.�	queryPort}s



zFirewallD.queryPortZaascCs&t|t�}tjd|�|jjj|�S)Nzzone.getPorts('%s'))rr^rr1r#r<Z
list_ports)r)r<r:r-r-r.�getPorts�s
zFirewallD.getPortsrcCstjd||||f�dS)Nz$zone.PortAdded('%s', '%s', '%s', %d))rr1)r)r<rrr�r-r-r.r�szFirewallD.PortAddedcCstjd|||f�dS)Nz"zone.PortRemoved('%s', '%s', '%s'))rr1)r)r<rrr-r-r.r
�szFirewallD.PortRemovedcCs>tjd||f�|j||=|jjj||�|j||�dS)Nz%zone.disableTimedProtocol('%s', '%s'))rr1r2r#r<�remove_protocol�ProtocolRemoved)r)r<rr-r-r.�disableTimedProtocol�szFirewallD.disableTimedProtocolcCs�t|t�}t|t�}t|t�}tjd||f�|j|�|jjj||||�}|dkrvt	j
||j||�}|j|||�|j
|||�|S)Nzzone.enableProtocol('%s', '%s')r)rr^r�rr1r;r#r<Zadd_protocolrr�rr?�
ProtocolAdded)r)r<rr�r:r�r>r-r-r.�addProtocol�s




zFirewallD.addProtocolcCs\t|t�}t|t�}tjd||f�|j|�|jjj||�}|j||�|j	||�|S)Nzzone.removeProtocol('%s', '%s'))
rr^rr1r;r#r<rrAr)r)r<rr:r�r-r-r.�removeProtocol�s


zFirewallD.removeProtocolcCs6t|t�}t|t�}tjd||f�|jjj||�S)Nzzone.queryProtocol('%s', '%s'))rr^rr1r#r<Zquery_protocol)r)r<rr:r-r-r.�
queryProtocol�s

zFirewallD.queryProtocolcCs&t|t�}tjd|�|jjj|�S)Nzzone.getProtocols('%s'))rr^rr1r#r<Zlist_protocols)r)r<r:r-r-r.�getProtocols�s
zFirewallD.getProtocolscCstjd|||f�dS)Nz"zone.ProtocolAdded('%s', '%s', %d))rr1)r)r<rr�r-r-r.r�szFirewallD.ProtocolAddedcCstjd||f�dS)Nz zone.ProtocolRemoved('%s', '%s'))rr1)r)r<rr-r-r.r�szFirewallD.ProtocolRemovedcCsJtjd|||f�|j|d||f=|jjj|||�|j|||�dS)Nz-zone.disableTimedSourcePort('%s', '%s', '%s')�sport)rr1r2r#r<�remove_source_port�SourcePortRemoved)r)r<rrr-r-r.�disableTimedSourcePort�s
z FirewallD.disableTimedSourcePortcCs�t|t�}t|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||||�}|dkr�t	j
||j|||�}|j|d||f|�|j
||||�|S)Nz$zone.addSourcePort('%s', '%s', '%s')rr)rr^r�rr1r;r#r<Zadd_source_portrr�r!r?�SourcePortAdded)r)r<rrr�r:r�r>r-r-r.�
addSourcePort�s








zFirewallD.addSourcePortcCsrt|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||�}|j|d||f�|j	|||�|S)Nz'zone.removeSourcePort('%s', '%s', '%s')r)
rr^rr1r;r#r<rrAr )r)r<rrr:r�r-r-r.�removeSourcePorts





zFirewallD.removeSourcePortcCsDt|t�}t|t�}t|t�}tjd|||f�|jjj|||�S)Nz&zone.querySourcePort('%s', '%s', '%s'))rr^rr1r#r<Zquery_source_port)r)r<rrr:r-r-r.�querySourcePort)s




zFirewallD.querySourcePortcCs&t|t�}tjd|�|jjj|�S)Nzzone.getSourcePorts('%s'))rr^rr1r#r<Zlist_source_ports)r)r<r:r-r-r.�getSourcePorts6s
zFirewallD.getSourcePortscCstjd||||f�dS)Nz*zone.SourcePortAdded('%s', '%s', '%s', %d))rr1)r)r<rrr�r-r-r.r"BszFirewallD.SourcePortAddedcCstjd|||f�dS)Nz(zone.SourcePortRemoved('%s', '%s', '%s'))rr1)r)r<rrr-r-r.r Hs
zFirewallD.SourcePortRemovedcCs(|j|d=|jjj|�|j|�dS)N�
masquerade)r2r#r<�remove_masquerade�MasqueradeRemoved)r)r<r-r-r.�disableTimedMasqueradeRsz FirewallD.disableTimedMasqueradeZsicCstt|t�}t|t�}tjd|�|j|�|jjj|||�}|dkrdt	j
||j|�}|j|d|�|j
||�|S)Nzzone.addMasquerade('%s')rr')rr^r�rr1r;r#r<Zadd_masqueraderr�r*r?�MasqueradeAdded)r)r<r�r:r�r>r-r-r.�
addMasqueradeXs



zFirewallD.addMasqueradecCsJt|t�}tjd|�|j|�|jjj|�}|j|d�|j	|�|S)Nzzone.removeMasquerade('%s')r')
rr^rr1r;r#r<r(rAr))r)r<r:r�r-r-r.�removeMasqueradels


zFirewallD.removeMasqueradecCs&t|t�}tjd|�|jjj|�S)Nzzone.queryMasquerade('%s'))rr^rr1r#r<Zquery_masquerade)r)r<r:r-r-r.�queryMasquerade{s
zFirewallD.queryMasqueradecCstjd||f�dS)Nzzone.MasqueradeAdded('%s', %d))rr1)r)r<r�r-r-r.r+�szFirewallD.MasqueradeAddedcCstjd|�dS)Nzzone.MasqueradeRemoved('%s'))rr1)r)r<r-r-r.r)�szFirewallD.MasqueradeRemovedcCs@|j|||||f=|jjj|||||�|j|||||�dS)N)r2r#r<�remove_forward_port�ForwardPortRemoved)r)r<rr�toport�toaddrr-r-r.�disable_forward_port�szFirewallD.disable_forward_portZsssssic
Cs�t|t�}t|t�}t|t�}t|t�}t|t�}t|t�}tjd|||||f�|j|�|jjj|||||||�}|dkr�t	j
||j|||||�}	|j|||||f|	�|j
||||||�|S)Nz1zone.addForwardPort('%s', '%s', '%s', '%s', '%s')r)rr^r�rr1r;r#r<Zadd_forward_portrr�r3r?�ForwardPortAdded)
r)r<rrr1r2r�r:r�r>r-r-r.�addForwardPort�s&







zFirewallD.addForwardPortZssssscCs�t|t�}t|t�}t|t�}t|t�}t|t�}tjd|||||f�|j|�|jjj|||||�}|j|||||f�|j	|||||�|S)Nz4zone.removeForwardPort('%s', '%s', '%s', '%s', '%s'))
rr^rr1r;r#r<r/rAr0)r)r<rrr1r2r:r�r-r-r.�removeForwardPort�s





zFirewallD.removeForwardPortcCs`t|t�}t|t�}t|t�}t|t�}t|t�}tjd|||||f�|jjj|||||�S)Nz3zone.queryForwardPort('%s', '%s', '%s', '%s', '%s'))rr^rr1r#r<Zquery_forward_port)r)r<rrr1r2r:r-r-r.�queryForwardPort�s




zFirewallD.queryForwardPortcCs&t|t�}tjd|�|jjj|�S)Nzzone.getForwardPorts('%s'))rr^rr1r#r<Zlist_forward_ports)r)r<r:r-r-r.�getForwardPorts�s
zFirewallD.getForwardPortscCstjd||||||f�dS)Nz7zone.ForwardPortAdded('%s', '%s', '%s', '%s', '%s', %d))rr1)r)r<rrr1r2r�r-r-r.r4�szFirewallD.ForwardPortAddedcCstjd|||||f�dS)Nz5zone.ForwardPortRemoved('%s', '%s', '%s', '%s', '%s'))rr1)r)r<rrr1r2r-r-r.r0�szFirewallD.ForwardPortRemovedcCs>tjd||f�|j||=|jjj||�|j||�dS)Nz&zone.disableTimedIcmpBlock('%s', '%s'))rr1r2r#r<�remove_icmp_block�IcmpBlockRemoved)r)r<�icmpr:r-r-r.�disableTimedIcmpBlock�szFirewallD.disableTimedIcmpBlockcCs�t|t�}t|t�}t|t�}tjd||f�|j|�|jjj||||�}|dkrxt	j
||j|||�}|j|||�|j
|||�|S)Nz zone.enableIcmpBlock('%s', '%s')r)rr^r�rr1r;r#r<Zadd_icmp_blockrr�r<r?�IcmpBlockAdded)r)r<r;r�r:r�r>r-r-r.�addIcmpBlocks





zFirewallD.addIcmpBlockcCs\t|t�}t|t�}tjd||f�|j|�|jjj||�}|j||�|j	||�|S)Nz zone.removeIcmpBlock('%s', '%s'))
rr^rr1r;r#r<r9rAr:)r)r<r;r:r�r-r-r.�removeIcmpBlocks


zFirewallD.removeIcmpBlockcCs6t|t�}t|t�}tjd||f�|jjj||�S)Nzzone.queryIcmpBlock('%s', '%s'))rr^rr1r#r<Zquery_icmp_block)r)r<r;r:r-r-r.�queryIcmpBlock&s

zFirewallD.queryIcmpBlockcCs&t|t�}tjd|�|jjj|�S)Nzzone.getIcmpBlocks('%s'))rr^rr1r#r<Zlist_icmp_blocks)r)r<r:r-r-r.�
getIcmpBlocks1s
zFirewallD.getIcmpBlockscCstjd|||f�dS)Nz#zone.IcmpBlockAdded('%s', '%s', %d))rr1)r)r<r;r�r-r-r.r==szFirewallD.IcmpBlockAddedcCstjd||f�dS)Nz!zone.IcmpBlockRemoved('%s', '%s'))rr1)r)r<r;r-r-r.r:CszFirewallD.IcmpBlockRemovedcCs@t|t�}tjd|�|j|�|jjj||�}|j|�|S)Nz zone.addIcmpBlockInversion('%s'))	rr^rr1r;r#r<Zadd_icmp_block_inversion�IcmpBlockInversionAdded)r)r<r:r�r-r-r.�addIcmpBlockInversionLs


zFirewallD.addIcmpBlockInversioncCs>t|t�}tjd|�|j|�|jjj|�}|j|�|S)Nz#zone.removeIcmpBlockInversion('%s'))	rr^rr1r;r#r<Zremove_icmp_block_inversion�IcmpBlockInversionRemoved)r)r<r:r�r-r-r.�removeIcmpBlockInversionZs


z"FirewallD.removeIcmpBlockInversioncCs&t|t�}tjd|�|jjj|�S)Nz"zone.queryIcmpBlockInversion('%s'))rr^rr1r#r<Zquery_icmp_block_inversion)r)r<r:r-r-r.�queryIcmpBlockInversionhs
z!FirewallD.queryIcmpBlockInversioncCstjd|�dS)Nz"zone.IcmpBlockInversionAdded('%s'))rr1)r)r<r-r-r.rBrsz!FirewallD.IcmpBlockInversionAddedcCstjd|�dS)Nz$zone.IcmpBlockInversionRemoved('%s'))rr1)r)r<r-r-r.rDwsz#FirewallD.IcmpBlockInversionRemovedcCs`t|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||�|j|||�dS)Nz!direct.addChain('%s', '%s', '%s'))	rr^rr1r;r#r�Z	add_chain�
ChainAdded)r)�ipv�table�chainr:r-r-r.�addChain�s



zFirewallD.addChaincCs`t|t�}t|t�}t|t�}tjd|||f�|j|�|jjj|||�|j|||�dS)Nz$direct.removeChain('%s', '%s', '%s'))	rr^rr1r;r#r�Zremove_chain�ChainRemoved)r)rHrIrJr:r-r-r.�removeChain�s



zFirewallD.removeChaincCsDt|t�}t|t�}t|t�}tjd|||f�|jjj|||�S)Nz#direct.queryChain('%s', '%s', '%s'))rr^rr1r#r�Zquery_chain)r)rHrIrJr:r-r-r.�
queryChain�s



zFirewallD.queryChaincCs6t|t�}t|t�}tjd||f�|jjj||�S)Nzdirect.getChains('%s', '%s'))rr^rr1r#r�Z
get_chains)r)rHrIr:r-r-r.�	getChains�s

zFirewallD.getChainsza(sss)cCstjd�|jjj�S)Nzdirect.getAllChains())rr1r#r�r�)r)r:r-r-r.�getAllChains�s
zFirewallD.getAllChainscCstjd|||f�dS)Nz#direct.ChainAdded('%s', '%s', '%s'))rr1)r)rHrIrJr-r-r.rG�szFirewallD.ChainAddedcCstjd|||f�dS)Nz%direct.ChainRemoved('%s', '%s', '%s'))rr1)r)rHrIrJr-r-r.rL�s
zFirewallD.ChainRemovedZsssiascCs�t|t�}t|t�}t|t�}t|t�}tdd�|D��}tjd||||dj|�f�|j|�|jj	j
|||||�|j|||||�dS)Ncss|]}t|t�VqdS)N)rr^)�.0r�r-r-r.�	<genexpr>�sz$FirewallD.addRule.<locals>.<genexpr>z*direct.addRule('%s', '%s', '%s', %d, '%s')z',')rr^r�r�rr1�joinr;r#r�r��	RuleAdded)r)rHrIrJ�priorityr*r:r-r-r.�addRule�s




zFirewallD.addRulecCs�t|t�}t|t�}t|t�}t|t�}tdd�|D��}tjd||||dj|�f�|j|�|jj	j
|||||�|j|||||�dS)Ncss|]}t|t�VqdS)N)rr^)rQr�r-r-r.rR�sz'FirewallD.removeRule.<locals>.<genexpr>z-direct.removeRule('%s', '%s', '%s', %d, '%s')z',')rr^r�r�rr1rSr;r#r�r��RuleRemoved)r)rHrIrJrUr*r:r-r-r.�
removeRule�s




zFirewallD.removeRulecCs�t|t�}t|t�}t|t�}tjd|||f�|j|�xF|jjj|||�D]0\}}|jjj|||||�|j	|||||�qPWdS)Nz$direct.removeRules('%s', '%s', '%s'))
rr^rr1r;r#r��	get_rulesr�rW)r)rHrIrJr:rUr*r-r-r.�removeRules�s



zFirewallD.removeRulescCsnt|t�}t|t�}t|t�}t|t�}tdd�|D��}tjd||||dj|�f�|jjj	|||||�S)Ncss|]}t|t�VqdS)N)rr^)rQr�r-r-r.rR	sz&FirewallD.queryRule.<locals>.<genexpr>z,direct.queryRule('%s', '%s', '%s', %d, '%s')z',')
rr^r�r�rr1rSr#r�r)r)rHrIrJrUr*r:r-r-r.�	queryRule�s



zFirewallD.queryRuleza(ias)cCsDt|t�}t|t�}t|t�}tjd|||f�|jjj|||�S)Nz!direct.getRules('%s', '%s', '%s'))rr^rr1r#r�rY)r)rHrIrJr:r-r-r.�getRules
	s



zFirewallD.getRulesz	a(sssias)cCstjd�|jjj�S)Nzdirect.getAllRules())rr1r#r�r�)r)r:r-r-r.�getAllRules	s
zFirewallD.getAllRulescCs"tjd||||dj|�f�dS)Nz,direct.RuleAdded('%s', '%s', '%s', %d, '%s')z',')rr1rS)r)rHrIrJrUr*r-r-r.rT"	szFirewallD.RuleAddedcCs"tjd||||dj|�f�dS)Nz.direct.RuleRemoved('%s', '%s', '%s', %d, '%s')z',')rr1rS)r)rHrIrJrUr*r-r-r.rW(	szFirewallD.RuleRemovedrScCs�t|t�}tdd�|D��}tjd|dj|�f�|j|�y|jjj	||�St
k
r�}zh|dkrztddd	d
g�}ntd	d
g�}t|�}|jt
jkr�tt|�|@�dkr�tj|�t|���WYdd}~XnXdS)
Ncss|]}t|t�VqdS)N)rr^)rQr�r-r-r.rR9	sz(FirewallD.passthrough.<locals>.<genexpr>zdirect.passthrough('%s', '%s')z','rHrLz-Cz--checkz-Lz--listr)rHrL)rr^r�rr1rSr;r#r��passthroughr�set�coderZCOMMAND_FAILEDr�rxr
)r)rHr*r:r9Z
query_args�msgr-r-r.r^2	s"


zFirewallD.passthroughcCs\t|�}tdd�|D��}tjd|dj|�f�|j|�|jjj||�|j	||�dS)Ncss|]}t|�VqdS)N)r)rQr�r-r-r.rRT	sz+FirewallD.addPassthrough.<locals>.<genexpr>z!direct.addPassthrough('%s', '%s')z',')
rr�rr1rSr;r#r�Zadd_passthrough�PassthroughAdded)r)rHr*r:r-r-r.�addPassthroughM	s
zFirewallD.addPassthroughcCs\t|�}tdd�|D��}tjd|dj|�f�|j|�|jjj||�|j	||�dS)Ncss|]}t|�VqdS)N)r)rQr�r-r-r.rRb	sz.FirewallD.removePassthrough.<locals>.<genexpr>z$direct.removePassthrough('%s', '%s')z',')
rr�rr1rSr;r#r�Zremove_passthrough�PassthroughRemoved)r)rHr*r:r-r-r.�removePassthrough[	s
zFirewallD.removePassthroughcCsBt|�}tdd�|D��}tjd|dj|�f�|jjj||�S)Ncss|]}t|�VqdS)N)r)rQr�r-r-r.rRp	sz-FirewallD.queryPassthrough.<locals>.<genexpr>z#direct.queryPassthrough('%s', '%s')z',')rr�rr1rSr#r�Zquery_passthrough)r)rHr*r:r-r-r.�queryPassthroughi	s
zFirewallD.queryPassthroughza(sas)cCstjd�|jjj�S)Nzdirect.getAllPassthroughs())rr1r#r�r�)r)r:r-r-r.�getAllPassthroughsu	s
zFirewallD.getAllPassthroughscCs.tjd�xt|j��D]}|j|�qWdS)Nzdirect.removeAllPassthroughs())rr1�reversedrgre)r)r:r^r-r-r.�removeAllPassthroughs~	s
zFirewallD.removeAllPassthroughscCs"t|�}tjd|�|jjj|�S)Nzdirect.getPassthroughs('%s'))rrr1r#r�Zget_passthroughs)r)rHr:r-r-r.�getPassthroughs�	szFirewallD.getPassthroughscCstjd|dj|�f�dS)Nz#direct.PassthroughAdded('%s', '%s')z',')rr1rS)r)rHr*r-r-r.rb�	szFirewallD.PassthroughAddedcCstjd|dj|�f�dS)Nz%direct.PassthroughRemoved('%s', '%s')z',')rr1rS)r)rHr*r-r-r.rd�	szFirewallD.PassthroughRemovedcCsdS)z� PK_ACTION_ALL implies all other actions, i.e. once a subject is
            authorized for PK_ACTION_ALL it's also authorized for any other action.
            Use-case is GUI (RHBZ#994729).
        Nr-)r)r:r-r-r.�authorizeAll�	s	zFirewallD.authorizeAllcCs$t|�}tjd|�|jjj|�S)Nzipset.queryIPSet('%s'))rrr1r#r|Zquery_ipset)r)r|r:r-r-r.�
queryIPSet�	szFirewallD.queryIPSetcCstjd�|jjj�S)Nzipsets.getIPSets())rr1r#r|r})r)r:r-r-r.�	getIPSets�	s
zFirewallD.getIPSetscCs(t|t�}tjd|�|jjj|�j�S)NzgetIPSetSettings(%s))rr^rr1r#r|Z	get_ipsetr�)r)r|r:r-r-r.r~�	s
zFirewallD.getIPSetSettingscCsLt|�}t|�}tjd||f�|j|�|jjj||�|j||�dS)Nzipset.addEntry('%s', '%s'))rrr1r;r#r|Z	add_entry�
EntryAdded)r)r|�entryr:r-r-r.�addEntry�	s
zFirewallD.addEntrycCsLt|�}t|�}tjd||f�|j|�|jjj||�|j||�dS)Nzipset.removeEntry('%s', '%s'))rrr1r;r#r|Zremove_entry�EntryRemoved)r)r|ror:r-r-r.�removeEntry�	s
zFirewallD.removeEntrycCs2t|�}t|�}tjd||f�|jjj||�S)Nzipset.queryEntry('%s', '%s'))rrr1r#r|Zquery_entry)r)r|ror:r-r-r.�
queryEntry�	szFirewallD.queryEntrycCs$t|�}tjd|�|jjj|�S)Nzipset.getEntries('%s'))rrr1r#r|�get_entries)r)r|r:r-r-r.�
getEntries�	szFirewallD.getEntriescCs�t|�}t|t�}tjd|dj|��|jjj|�}|jjj||�t	|�}t	|�}x||D]}|j
||�q^Wx||D]}|j||�q|WdS)Nzipset.setEntries('%s', '[%s]')�,)r�listrr1rSr#r|rtZset_entriesr_rnrq)r)r|Zentriesr:Zold_entriesZold_entries_setZentries_setror-r-r.�
setEntries�	s
zFirewallD.setEntriescCs&t|�}t|�}tjd||f�dS)Nzipset.EntryAdded('%s', '%s'))rrr1)r)r|ror-r-r.rn
szFirewallD.EntryAddedcCs&t|�}t|�}tjd||f�dS)Nzipset.EntryRemoved('%s', '%s'))rrr1)r)r|ror-r-r.rq
szFirewallD.EntryRemovedcCstjd�|jjj�S)Nzhelpers.getHelpers())rr1r#r�r�)r)r:r-r-r.�
getHelpers!
s
zFirewallD.getHelperscCs(t|t�}tjd|�|jjj|�j�S)NzgetHelperSettings(%s))rr^rr1r#r�Z
get_helperr�)r)r�r:r-r-r.r�*
s
zFirewallD.getHelperSettings)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)r)N)N)N)N)r)N)N)N)N)r)N)N)N)r)N)N)N)N)r)N)N)N)N)r)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)��__name__�
__module__�__qualname__�__doc__Z
persistentrr'ZPK_ACTION_CONFIGZdefault_polkit_auth_requiredrr"r0r&r/r
r;r?rArCrZrZPROPERTIES_IFACErerh�slipZpolkitZrequire_authrirr�signalrjZPK_ACTION_INFOZINTROSPECTABLE_IFACErkr(rnrprorqr�ZPK_ACTION_POLICIESrar�r�ZPK_ACTION_POLICIES_INFOr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�ZPK_ACTION_CONFIG_INFOr�r_r�r�r�ZDBUS_INTERFACE_POLICYr�r�r�r�rtr�r�rZDBUS_SIGNATUREr{r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrrr�r�rrvr	r
rrrrrrrrrr
rrrrrrrr!r#r$r%r&r"r r*r,r-r.r+r)r3r5r6r7r8r4r0r<r>r?r@rAr=r:rCrErFrBrDZPK_ACTION_DIRECTr`rKrMZPK_ACTION_DIRECT_INFOrNrOrPrGrLrVrXrZr[r\r]rTrWr^rcrerfrgrirjrbrdZ
PK_ACTION_ALLrkrbrlrmrr~rprrrsrurxrnrqryrr��
__classcell__r-r-)r,r.rAs�	0"	



K



	
	


	
	


	
	


	
	



























	









	








	















	






	
	


	
















	







	









	
	




)9�__all__Z
gi.repositoryrr�sys�modulesr�r'Zdbus.serviceZ	slip.dbusr~Zslip.dbus.serviceZfirewallrZfirewall.core.fwrZfirewall.core.richrZfirewall.core.loggerrZfirewall.clientr	Zfirewall.server.decoratorsr
rrr
Zfirewall.server.configrZfirewall.dbus_utilsrrrrrrrZfirewall.core.io.functionsrZfirewall.core.io.ipsetrZfirewall.core.io.icmptyperZfirewall.core.io.helperrZfirewall.core.fw_nmrrrZfirewall.core.fw_ifcfgrrZfirewall.errorsrrrZObjectrr-r-r-r.�<module>s2
$server/__pycache__/decorators.cpython-36.pyc000064400000004023150351351720015056 0ustar003

��go�@s�dZddddgZddlZddlZddlZddlmZddlmZdd	lm	Z	dd
l
mZddlmZddl
mZGd
d�dej�Zedd��Zedd��Zdd�ZdS)z>This module contains decorators for use with and without D-Bus�FirewallDBusException�handle_exceptions�dbus_handle_exceptions�dbus_service_method�N)�
DBusException)�	decorator)�config)�
FirewallError)�errors)�logc@seZdZdZdejjZdS)rz%s.ExceptionN)�__name__�
__module__�__qualname__�__doc__r�dbusZDBUS_INTERFACEZ_dbus_error_name�rr� /usr/lib/python3.6/decorators.pyr+scOsdy
|||�Stk
rD}ztjtj��tj|�WYdd}~Xntk
r^tj�YnXdS)zTDecorator to handle exceptions and log them. Used if not conneced
    to D-Bus.
    N)r	r�debug1�	traceback�
format_exc�error�	Exception�	exception)�func�args�kwargsrrrrr/s
cOs�y
|||�Stk
r�}zdtjt|��}|tjtjtjtjgkrRtj	t|��ntj
tj��tj
t|��tt|���WYdd}~XnZtk
r�}z
|�WYdd}~Xn6tk
r�}ztj�tt|���WYdd}~XnXdS)z�Decorator to handle exceptions, log and report them into D-Bus

    :Raises DBusException: on a firewall error code problems.
    N)r	�get_code�strr
ZALREADY_ENABLEDZNOT_ENABLEDZZONE_ALREADY_SETZALREADY_SETrZwarningrrrrrrrr)rrrr�codeZexrrrr<s

cOs|jdd�tjj||�S)zAdd sender argument for D-BusZsender_keywordZsender)�
setdefaultrZservice�method)rrrrrrTs)r�__all__rZdbus.servicerZdbus.exceptionsrrZfirewallrZfirewall.errorsr	r
Zfirewall.core.loggerrrrrrrrrr�<module>s
server/__pycache__/config_service.cpython-36.opt-1.pyc000064400000051355150351351720016647 0ustar003

��g�u�@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZmZmZddl	mZdd	lmZGd
d�dejjj�ZdS)�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�errors)�
FirewallErrorcs�eZdZdZdZejjZe	�fdd��Z
edd��Zedd��Z
ed	d
��Zeejddd
�ed�dd���Zeejddd
�ed�dd���Zejjjejj�eejdd�ed�dd����Zejjejdd�dd��Zejjjejj�eejdd�ed��fdd�	���Zeejjd d�ed�d!d"���Zeejjdd�ed�d#d$���Zeejjd d�ed�d%d&���Z eejjdd�ed�d'd(���Z!eejj�ed�d)d*���Z"ejjejjdd�ed+d,���Z#eejj�ed�d-d.���Z$ejjejjdd�ed/d0���Z%eejjdd�ed�d1d2���Z&ejjejjdd�ed3d4���Z'eejjdd�ed�d5d6���Z(eejjdd�ed�d7d8���Z)eejjdd�ed�d9d:���Z*eejjdd�ed�d;d<���Z+eejjdd�ed�d=d>���Z,eejjdd�ed�d?d@���Z-eejjdAd�ed�dBdC���Z.eejjdAd�ed�dDdE���Z/eejjdd�ed�dFdG���Z0eejjdd�ed�dHdI���Z1eejjddJd
�ed�dKdL���Z2eejjdMd�ed�dNdO���Z3eejjdMd�ed�dPdQ���Z4eejjdd�ed�dRdS���Z5eejjdd�ed�dTdU���Z6eejjddJd
�ed�dVdW���Z7eejjdAd�ed�dXdY���Z8eejjdAd�ed�dZd[���Z9eejjdd�ed�d\d]���Z:eejjdd�ed�d^d_���Z;eejjddJd
�ed�d`da���Z<eejjdMd�ed�dbdc���Z=eejjdMd�ed�ddde���Z>eejjdd�ed�dfdg���Z?eejjdd�ed�dhdi���Z@eejjddJd
�ed�djdk���ZAeejjdld�ed�dmdn���ZBeejjdld�ed�dodp���ZCeejjddd
�ed�dqdr���ZDeejjdd�ed�dsdt���ZEeejjdd�ed�dudv���ZFeejjddJd
�ed�dwdx���ZGeejjdMd�ed�dydz���ZHeejjdMd�ed�d{d|���ZIeejjdd�ed�d}d~���ZJeejjdd�ed�dd����ZKeejjddJd
�ed�d�d����ZL�ZMS)��FirewallDConfigServicezFirewallD main classTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.service.%d)
�superr
�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_SERVICE)�selfrZconf�servicer�args�kwargs)�	__class__��$/usr/lib/python3.6/config_service.pyr7s

zFirewallDConfigService.__init__cCsdS)Nr)rrrr�__del__DszFirewallDConfigService.__del__cCs|j�dS)N)Zremove_from_connection)rrrr�
unregisterHsz!FirewallDConfigService.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrr"r#rZBooleanr$r%�
exceptions�
DBusException)r�
property_namerrr�
_get_propertyPsz$FirewallDConfigService._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrrr'r(r*)r�interface_namer)�senderrrr�Getas


zFirewallDConfigService.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existr"r#rr$r%Zsv)�	signature)r"r#rr$r%)rr.rr/rrrrr'r(r*Z
Dictionary)rr0r1�ret�xrrr�GetAllrs

zFirewallDConfigService.GetAllZssv)r,cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr.rr/rr�accessCheckrrrr'r()rr0r)Z	new_valuer1rrr�Set�s



zFirewallDConfigService.Setzsa{sv}as)r4cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr.rr/r)rr0Zchanged_propertiesZinvalidated_propertiesrrr�PropertiesChanged�s


z(FirewallDConfigService.PropertiesChanged)r-cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rrr
�
IntrospectrrZget_busrrrr)rr1�data)rrrr;�s

z!FirewallDConfigService.Introspectz(sssa(ss)asa{ss}asa(ss))cCstjd|j�|jj|j�S)z!get settings for service
        z%s.getSettings())rr/rrZget_service_configr)rr1rrr�getSettings�sz"FirewallDConfigService.getSettingscCstjd|j�|jj|j�S)z!get settings for service
        z%s.getSettings2())rr/rr�get_service_config_dictr)rr1rrr�getSettings2�sz#FirewallDConfigService.getSettings2cCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)z$update settings for service
        z%s.update('...')N)rrr/rrr8rZset_service_configr�Updatedr")r�settingsr1rrr�update�s
zFirewallDConfigService.updatecCsFt|�}tjd|j�|jj|�|jj|j|�|_|j	|jj
�dS)Nz%s.update2('...'))rrr/rrr8r�set_service_config_dictrr@r")rrAr1rrr�update2�s
zFirewallDConfigService.update2cCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z2load default settings for builtin service
        z%s.loadDefaults()N)
rr/rrr8rZload_service_defaultsrr@r")rr1rrr�loadDefaults�sz#FirewallDConfigService.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr/r)rr"rrrr@�szFirewallDConfigService.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove service
        z%s.removeService()N)	rr/rrr8rZremove_servicerZ
removeService)rr1rrr�remove�szFirewallDConfigService.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr/r)rr"rrr�Removed�szFirewallDConfigService.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename service
        z%s.rename('%s')N)rr.rr/rrr8rZrename_servicer�Renamed)rr"r1rrr�rename�s

zFirewallDConfigService.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr/r)rr"rrrrHszFirewallDConfigService.RenamedcCstjd|j�|j�dS)Nz%s.getVersion()r)rr/rr=)rr1rrr�
getVersionsz!FirewallDConfigService.getVersioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setVersion('%s')r)
rr.rr/rrr8�listr=rB)r�versionr1rArrr�
setVersions
z!FirewallDConfigService.setVersioncCstjd|j�|j�dS)Nz
%s.getShort()r)rr/rr=)rr1rrr�getShort"szFirewallDConfigService.getShortcCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setShort('%s')r)
rr.rr/rrr8rKr=rB)rZshortr1rArrr�setShort)s
zFirewallDConfigService.setShortcCstjd|j�|j�dS)Nz%s.getDescription()�)rr/rr=)rr1rrr�getDescription6sz%FirewallDConfigService.getDescriptioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setDescription('%s')rP)
rr.rr/rrr8rKr=rB)r�descriptionr1rArrr�setDescription=s

z%FirewallDConfigService.setDescriptionza(ss)cCstjd|j�|j�dS)Nz
%s.getPorts()�)rr/rr=)rr1rrr�getPortsKszFirewallDConfigService.getPortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setPorts('[%s]')�,css"|]}d|d|dfVqdS)z('%s, '%s')rrNr)�.0�portrrr�	<genexpr>_sz2FirewallDConfigService.setPorts.<locals>.<genexpr>rT)
rrK�
isinstance�append�tuplerr/r�joinrr8r=rB)r�portsr1�_portsrXrArrr�setPortsRs

zFirewallDConfigService.setPortscCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.addPort('%s', '%s')rTz%s:%s)rr.rr/rrr8rKr=rr�ALREADY_ENABLEDr[rB)rrX�protocolr1rArrr�addPortes

zFirewallDConfigService.addPortcCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.removePort('%s', '%s')rTz%s:%s)rr.rr/rrr8rKr=rr�NOT_ENABLEDrFrB)rrXrbr1rArrr�
removePortus

z!FirewallDConfigService.removePort�bcCs:t|t�}t|t�}tjd|j||�||f|j�dkS)Nz%s.queryPort('%s', '%s')rT)rr.rr/rr=)rrXrbr1rrr�	queryPort�s


z FirewallDConfigService.queryPort�ascCstjd|j�|j�dS)Nz%s.getProtocols()�)rr/rr=)rr1rrr�getProtocols�sz#FirewallDConfigService.getProtocolscCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setProtocols('[%s]')rVri)
rrKrr/rr]rr8r=rB)rZ	protocolsr1rArrr�setProtocols�s

z#FirewallDConfigService.setProtocolscCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addProtocol('%s')ri)rr.rr/rrr8rKr=rrrar[rB)rrbr1rArrr�addProtocol�s
z"FirewallDConfigService.addProtocolcCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.removeProtocol('%s')ri)rr.rr/rrr8rKr=rrrdrFrB)rrbr1rArrr�removeProtocol�s
z%FirewallDConfigService.removeProtocolcCs*t|t�}tjd|j|�||j�dkS)Nz%s.queryProtocol(%s')ri)rr.rr/rr=)rrbr1rrr�
queryProtocol�s
z$FirewallDConfigService.queryProtocolcCstjd|j�|j�dS)Nz%s.getSourcePorts()�)rr/rr=)rr1rrr�getSourcePorts�sz%FirewallDConfigService.getSourcePortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setSourcePorts('[%s]')rVcss"|]}d|d|dfVqdS)z('%s, '%s')rrNr)rWrXrrrrY�sz8FirewallDConfigService.setSourcePorts.<locals>.<genexpr>ro)
rrKrZr[r\rr/rr]rr8r=rB)rr^r1r_rXrArrr�setSourcePorts�s

z%FirewallDConfigService.setSourcePortscCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.addSourcePort('%s', '%s')roz%s:%s)rr.rr/rrr8rKr=rrrar[rB)rrXrbr1rArrr�
addSourcePort�s

z$FirewallDConfigService.addSourcePortcCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||f|dkrbt	t
jd||f��|dj||f�|j
|�dS)Nz%s.removeSourcePort('%s', '%s')roz%s:%s)rr.rr/rrr8rKr=rrrdrFrB)rrXrbr1rArrr�removeSourcePort�s

z'FirewallDConfigService.removeSourcePortcCs:t|t�}t|t�}tjd|j||�||f|j�dkS)Nz%s.querySourcePort('%s', '%s')ro)rr.rr/rr=)rrXrbr1rrr�querySourcePorts


z&FirewallDConfigService.querySourcePortcCstjd|j�|j�dS)Nz%s.getModules()�)rr/rr=)rr1rrr�
getModulessz!FirewallDConfigService.getModulescCs�t|t�}g}x@|D]8}|jd�rB|jdd�}d|krB|jdd�}|j|�qW|}tjd|jdj|��|j	j
|�t|j��}||d<|j|�dS)N�
nf_conntrack_��_�-z%s.setModules('[%s]')rVru)
rrK�
startswith�replacer[rr/rr]rr8r=rB)r�modulesr1Z_modules�modulerArrr�
setModuless



z!FirewallDConfigService.setModulescCs�t|t�}|jd�r4|jdd�}d|kr4|jdd�}tjd|j|�|jj|�t	|j
��}||dkrtttj
|��|dj|�|j|�dS)Nrwrxryrzz%s.addModule('%s')ru)rr.r{r|rr/rrr8rKr=rrrar[rB)rr~r1rArrr�	addModule's

z FirewallDConfigService.addModulecCs�t|t�}|jd�r4|jdd�}d|kr4|jdd�}tjd|j|�|jj|�t	|j
��}||dkrtttj
|��|dj|�|j|�dS)Nrwrxryrzz%s.removeModule('%s')ru)rr.r{r|rr/rrr8rKr=rrrdrFrB)rr~r1rArrr�removeModule8s

z#FirewallDConfigService.removeModulecCsTt|t�}|jd�r4|jdd�}d|kr4|jdd�}tjd|j|�||j�dkS)Nrwrxryrzz%s.queryModule('%s')ru)rr.r{r|rr/rr=)rr~r1rrr�queryModuleIs

z"FirewallDConfigService.queryModuleza{ss}cCstjd|j�|j�dS)Nz%s.getDestinations()�)rr/rr=)rr1rrr�getDestinationsWsz&FirewallDConfigService.getDestinationscCsVt|t�}tjd|j|jd�|jd��|jj|�t|j	��}||d<|j
|�dS)Nz*%s.setDestinations({ipv4:'%s', ipv6:'%s'})Zipv4Zipv6r�)r�dictrr/r�getrr8rKr=rB)rZdestinationsr1rArrr�setDestinations^s
z&FirewallDConfigService.setDestinationscCsVt|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|d|S)Nz%s.getDestination('%s')r�)rr.rr/rrr8rKr=rrrd)r�familyr1rArrr�getDestinationks

z%FirewallDConfigService.getDestinationcCs�t|t�}t|t�}tjd|j||�|jj|�t|j��}||dkrn|d||krnt	t
jd||f��||d|<|j|�dS)Nz%s.setDestination('%s', '%s')r�z
'%s': '%s')
rr.rr/rrr8rKr=rrrarB)rr��addressr1rArrr�setDestinationxs


z%FirewallDConfigService.setDestinationcCsbt|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|d|=|j|�dS)Nz%s.removeDestination('%s')r�)
rr.rr/rrr8rKr=rrrdrB)rr�r1rArrr�removeDestination�s


z(FirewallDConfigService.removeDestinationcCsJt|t�}t|t�}tjd|j||�|j�}||dkoH||d|kS)Nz%s.queryDestination('%s', '%s')r�)rr.rr/rr=)rr�r�r1rArrr�queryDestination�s


z'FirewallDConfigService.queryDestinationcCs<tjd|j�|jj|�|jj|j�}d|kr8|dSgS)Nz%s.getIncludes()�includes)rr/rrr8rr>r)rr1rArrr�getIncludes�sz"FirewallDConfigService.getIncludescCsZt|t�}tjd|j|�|jj|�d|dd�i}|jj|j	|�|_	|j
|j	j�dS)Nz%s.setIncludes('%s')r�)rrKrr/rrr8rrCrr@r")rr�r1rArrr�setIncludes�s
z"FirewallDConfigService.setIncludescCsjt|t�}tjd|j|�|jj|�|jj|j	�}|j
dg�j|�|jj|j	|�|_	|j
|j	j�dS)Nz%s.addInclude('%s')r�)rr.rr/rrr8rr>r�
setdefaultr[rCr@r")r�includer1rArrr�
addInclude�s
z!FirewallDConfigService.addIncludecCsft|t�}tjd|j|�|jj|�|jj|j	�}|dj
|�|jj|j	|�|_	|j|j	j
�dS)Nz%s.removeInclude('%s')r�)rr.rr/rrr8rr>rrFrCr@r")rr�r1rArrr�
removeInclude�s
z$FirewallDConfigService.removeIncludecCs@t|t�}tjd|j|�|jj|j�}d|kr<||dkSdS)Nz%s.queryInclude('%s')r�F)rr.rr/rrr>r)rr�r1rArrr�queryInclude�s
z#FirewallDConfigService.queryInclude)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N�__name__�
__module__�__qualname__�__doc__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredrrr	r r!r*r
ZPROPERTIES_IFACEr2r7�slipZpolkitZrequire_authr9r�signalr:ZPK_ACTION_INFOZINTROSPECTABLE_IFACEr;rr=r?rBrDrEr@rFrGrIrHrJrMrNrOrQrSrUr`rcrergrjrkrlrmrnrprqrrrsrtrvrr�r�r�r�r�r�r�r�r�r�r�r�r�r��
__classcell__rr)rrr
/s�
		

	


		


	


		r
)Z
gi.repositoryr�sysr}rZdbus.serviceZ	slip.dbusr�Zslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.loggerrZfirewall.server.decoratorsrr	r
rZfirewall.errorsrrZObjectr
rrrr�<module>s
server/__pycache__/config_zone.cpython-36.pyc000064400000101501150351351720015210 0ustar003

��gW��@s�ddlmZddlZeejd<ddlZddlZddlZddlZddl	m
Z
ddlmZm
Z
mZddlmZddlmZddlmZdd	lmZdd
lmZddlmZmZmZddl	mZdd
lmZddl m!Z!m"Z"m#Z#m$Z$Gdd�dejj%j&�Z'dS)�)�GObjectNZgobject)�config)�dbus_to_python�%dbus_introspection_prepare_properties�!dbus_introspection_add_properties)�Zone)�ifcfg_set_zone_of_interface)�DEFAULT_ZONE_TARGET)�	Rich_Rule)�log)�handle_exceptions�dbus_handle_exceptions�dbus_service_method)�errors)�
FirewallError)�portStr�portInPortRange�coalescePortRange�breakPortRangecs�	eZdZdZdZejjZe	�fdd��Z
edd��Zedd��Z
ed	d
��Zeejddd
�ed�dd���Zeejddd
�ed�dd���Zejjjejj�eejdd�ed�dd����Zejjejdd�dd��Zejjjejj�eejdd�ed��fdd�	���Zeejjd d�ed�d!d"���Zeejjdd�ed�d#d$���Zd%d&�Z eejjd d�ed�d'd(���Z!eejjdd�ed�d)d*���Z"eejj�ed�d+d,���Z#ejjejjdd�ed-d.���Z$eejj�ed�d/d0���Z%ejjejjdd�ed1d2���Z&eejjdd�ed�d3d4���Z'ejjejjdd�ed5d6���Z(eejjdd�ed�d7d8���Z)eejjdd�ed�d9d:���Z*eejjdd�ed�d;d<���Z+eejjdd�ed�d=d>���Z,eejjdd�ed�d?d@���Z-eejjdd�ed�dAdB���Z.eejjdd�ed�dCdD���Z/eejjdd�ed�dEdF���Z0eejjdGd�ed�dHdI���Z1eejjdGd�ed�dJdK���Z2eejjdd�ed�dLdM���Z3eejjdd�ed�dNdO���Z4eejjddPd
�ed�dQdR���Z5eejjdSd�ed�dTdU���Z6eejjdSd�ed�dVdW���Z7eejjdd�ed�dXdY���Z8eejjdd�ed�dZd[���Z9eejjddPd
�ed�d\d]���Z:eejjdGd�ed�d^d_���Z;eejjdGd�ed�d`da���Z<eejjdd�ed�dbdc���Z=eejjdd�ed�ddde���Z>eejjddPd
�ed�dfdg���Z?eejjdSd�ed�dhdi���Z@eejjdSd�ed�djdk���ZAeejjdd�ed�dldm���ZBeejjdd�ed�dndo���ZCeejjddPd
�ed�dpdq���ZDeejjdGd�ed�drds���ZEeejjdGd�ed�dtdu���ZFeejjdd�ed�dvdw���ZGeejjdd�ed�dxdy���ZHeejjddPd
�ed�dzd{���ZIeejjdPd�ed�d|d}���ZJeejjdPd�ed�d~d���ZKeejj�ed�d�d����ZLeejj�ed�d�d����ZMeejjdPd�ed�d�d����ZNeejjdPd�ed�d�d����ZOeejjdPd�ed�d�d����ZPeejj�ed�d�d����ZQeejj�ed�d�d����ZReejjdPd�ed�d�d����ZSeejjd�d�ed�d�d����ZTeejjd�d�ed�d�d����ZUeejjd�d�ed�d�d����ZVeejjd�d�ed�d�d����ZWeejjd�dPd
�ed�d�d����ZXeejjdGd�ed�d�d����ZYeejjdGd�ed�d�d����ZZeejjdd�ed�d�d����Z[eejjdd�ed�d�d����Z\eejjddPd
�ed�d�d����Z]eejjdGd�ed�d�d����Z^eejjdGd�ed�d�d����Z_eejjdd�ed�d�d����Z`eejjdd�ed�d�d����ZaeejjddPd
�ed�d�d����ZbeejjdGd�ed�d�d����ZceejjdGd�e�dd�d����Zdeejjdd�e�dd�d����Zeeejjdd�e�dd�d����ZfeejjddPd
�e�dd�d����Zg�ZhS(�FirewallDConfigZonezFirewallD main classTcs\tt|�j||�||_||_||_||_|d|_|d|_d|j|_	t
|tjj�dS)Nr�zconfig.zone.%d)
�superr�__init__�parentr�obj�item_id�busname�path�_log_prefixr�dbus�DBUS_INTERFACE_CONFIG_ZONE)�selfrZconfZzoner�args�kwargs)�	__class__��!/usr/lib/python3.6/config_zone.pyr=s

zFirewallDConfigZone.__init__cCsdS)Nr%)r!r%r%r&�__del__JszFirewallDConfigZone.__del__cCs|j�dS)N)Zremove_from_connection)r!r%r%r&�
unregisterNszFirewallDConfigZone.unregistercCs�|dkrtj|jj�S|dkr,tj|jj�S|dkrBtj|jj�S|dkrXtj|jj�S|dkrntj|jj�Stj	j
d|��dS)N�name�filenamer�default�builtinzDorg.freedesktop.DBus.Error.InvalidArgs: Property '%s' does not exist)r�Stringrr)r*rZBooleanr+r,�
exceptions�
DBusException)r!�
property_namer%r%r&�
_get_propertyVsz!FirewallDConfigZone._get_propertyZss�v)�in_signature�
out_signatureNcCsLt|t�}t|t�}tjd|j||�|tjjkrBtjj	d|��|j
|�S)Nz%s.Get('%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not exist)r�strr�debug1rrrr r.r/r1)r!�interface_namer0�senderr%r%r&�Getgs


zFirewallDConfigZone.Get�sza{sv}cCsdt|t�}tjd|j|�|tjjkr6tjj	d|��i}xd
D]}|j
|�||<q@Wtj|dd	�S)Nz%s.GetAll('%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existr)r*rr+r,Zsv)�	signature)r)r*rr+r,)rr5rr6rrrr r.r/r1Z
Dictionary)r!r7r8�ret�xr%r%r&�GetAllxs

zFirewallDConfigZone.GetAllZssv)r3cCslt|t�}t|t�}t|�}tjd|j|||�|jj|�|tjj	krXtj
jd|��tj
jd|��dS)Nz%s.Set('%s', '%s', '%s')zJorg.freedesktop.DBus.Error.UnknownInterface: Interface '%s' does not existzGorg.freedesktop.DBus.Error.PropertyReadOnly: Property '%s' is read-only)rr5rr6rr�accessCheckrrr r.r/)r!r7r0Z	new_valuer8r%r%r&�Set�s



zFirewallDConfigZone.Setzsa{sv}as)r;cCs2t|t�}t|�}t|�}tjd|j|||�dS)Nz&%s.PropertiesChanged('%s', '%s', '%s'))rr5rr6r)r!r7Zchanged_propertiesZinvalidated_propertiesr%r%r&�PropertiesChanged�s


z%FirewallDConfigZone.PropertiesChanged)r4cs8tjd|j�tt|�j|j|jj��}t	||t
jj�S)Nz%s.Introspect())
rZdebug2rrr�
IntrospectrrZget_busrrrr )r!r8�data)r$r%r&rB�s

zFirewallDConfigZone.Introspectz&(sssbsasa(ss)asba(ssss)asasasasa(ss)b)cCsDtjd|j�|jj|j�}|dtkr@t|�}d|d<t|�}|S)zget settings for zone
        z%s.getSettings()�r+)	rr6rrZget_zone_configrr	�list�tuple)r!r8�settings�	_settingsr%r%r&�getSettings�szFirewallDConfigZone.getSettingscCs4tjd|j�|jj|j�}|dtkr0d|d<|S)zget settings for zone
        z%s.getSettings2()�targetr+)rr6rr�get_zone_config_dictrr	)r!r8rGr%r%r&�getSettings2�s
z FirewallDConfigZone.getSettings2cCs|jj|j�}d|kr"t|d�nt�}d|kr<t|d�nt�}t|t�rzt|tjd��|}t|tjd��|}nDd|kr�t|d�nt�}d|kr�t|d�nt�}||}||}x$|D]}	|jj	|	�r�t
tj|	��q�Wx$|D]}
|jj
|
�r�t
tj|
��q�WdS)a
Assignment of interfaces/sources to zones is different from other
           zone settings in the sense that particular interface/zone can be
           part of only one zone. So make sure added interfaces/sources have
           not already been bound to another zone.�
interfaces�sourcesN)rrKr�set�
isinstancerFrZindex_ofrZgetZoneOfInterfacerrZ
ZONE_CONFLICTZgetZoneOfSource)r!rGZold_settingsZ
old_ifacesZold_sourcesZadded_ifacesZ
added_sourcesZ
new_ifacesZnew_sourcesZiface�sourcer%r%r&� _checkDuplicateInterfacesSources�s 


z4FirewallDConfigZone._checkDuplicateInterfacesSourcescCstt|�}tjd|j�|jj|�|ddkrFt|�}t|d<t|�}|j	|�|j
j|j|�|_|j
|jj�dS)z!update settings for zone
        z%s.update('...')rDr+N)rrr6rrr?rEr	rFrRrZset_zone_configr�Updatedr))r!rGr8rHr%r%r&�update�s
zFirewallDConfigZone.updatecCslt|�}tjd|j�|jj|�d|kr>|ddkr>t|d<|j|�|jj	|j
|�|_
|j|j
j�dS)z!update settings for zone
        z%s.update2('...')rJr+N)
rrr6rrr?r	rRrZset_zone_config_dictrrSr))r!rGr8r%r%r&�update2�s
zFirewallDConfigZone.update2cCs<tjd|j�|jj|�|jj|j�|_|j|jj	�dS)z/load default settings for builtin zone
        z%s.loadDefaults()N)
rr6rrr?rZload_zone_defaultsrrSr))r!r8r%r%r&�loadDefaultssz FirewallDConfigZone.loadDefaultscCstjd|j|f�dS)Nz%s.Updated('%s'))rr6r)r!r)r%r%r&rSszFirewallDConfigZone.UpdatedcCs:tjd|j�|jj|�|jj|j�|jj|j�dS)zremove zone
        z%s.removeZone()N)	rr6rrr?rZremove_zonerZ
removeZone)r!r8r%r%r&�removeszFirewallDConfigZone.removecCstjd|j|f�dS)Nz%s.Removed('%s'))rr6r)r!r)r%r%r&�Removed#szFirewallDConfigZone.RemovedcCsFt|t�}tjd|j|�|jj|�|jj|j	|�|_	|j
|�dS)zrename zone
        z%s.rename('%s')N)rr5rr6rrr?rZrename_zoner�Renamed)r!r)r8r%r%r&�rename*s

zFirewallDConfigZone.renamecCstjd|j|f�dS)Nz%s.Renamed('%s'))rr6r)r!r)r%r%r&rY6szFirewallDConfigZone.RenamedcCstjd|j�|j�dS)Nz%s.getVersion()r)rr6rrI)r!r8r%r%r&�
getVersion=szFirewallDConfigZone.getVersioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setVersion('%s')r)
rr5rr6rrr?rErIrT)r!�versionr8rGr%r%r&�
setVersionDs
zFirewallDConfigZone.setVersioncCstjd|j�|j�dS)Nz
%s.getShort()r)rr6rrI)r!r8r%r%r&�getShortQszFirewallDConfigZone.getShortcCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setShort('%s')r)
rr5rr6rrr?rErIrT)r!Zshortr8rGr%r%r&�setShortXs
zFirewallDConfigZone.setShortcCstjd|j�|j�dS)Nz%s.getDescription()�)rr6rrI)r!r8r%r%r&�getDescriptionesz"FirewallDConfigZone.getDescriptioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setDescription('%s')r`)
rr5rr6rrr?rErIrT)r!�descriptionr8rGr%r%r&�setDescriptionls
z"FirewallDConfigZone.setDescriptioncCs.tjd|j�|j�}|dtkr*|dSdS)Nz%s.getTarget()rDr+)rr6rrIr	)r!r8rGr%r%r&�	getTarget|szFirewallDConfigZone.getTargetcCsTt|t�}tjd|j|�|jj|�t|j��}|dkr>|nt	|d<|j
|�dS)Nz%s.setTarget('%s')r+rD)rr5rr6rrr?rErIr	rT)r!rJr8rGr%r%r&�	setTarget�s
zFirewallDConfigZone.setTarget�ascCstjd|j�|j�dS)Nz%s.getServices()�)rr6rrI)r!r8r%r%r&�getServices�szFirewallDConfigZone.getServicescCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setServices('[%s]')�,rg)
rrErr6r�joinrr?rIrT)r!Zservicesr8rGr%r%r&�setServices�s

zFirewallDConfigZone.setServicescCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addService('%s')rg)rr5rr6rrr?rErIrr�ALREADY_ENABLED�appendrT)r!�servicer8rGr%r%r&�
addService�s
zFirewallDConfigZone.addServicecCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.removeService('%s')rg)rr5rr6rrr?rErIrr�NOT_ENABLEDrWrT)r!rnr8rGr%r%r&�
removeService�s
z!FirewallDConfigZone.removeService�bcCs*t|t�}tjd|j|�||j�dkS)Nz%s.queryService('%s')rg)rr5rr6rrI)r!rnr8r%r%r&�queryService�s
z FirewallDConfigZone.queryServiceza(ss)cCstjd|j�|j�dS)Nz
%s.getPorts()�)rr6rrI)r!r8r%r%r&�getPorts�szFirewallDConfigZone.getPortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setPorts('[%s]')ricss"|]}d|d|dfVqdS)z('%s, '%s')rrNr%)�.0�portr%r%r&�	<genexpr>�sz/FirewallDConfigZone.setPorts.<locals>.<genexpr>rt)
rrErPrmrFrr6rrjrr?rIrT)r!�portsr8�_portsrwrGr%r%r&�setPorts�s

zFirewallDConfigZone.setPortsc
s�t|t�}t�t��tjd|j|��|jj|�t|j��}tt	�fdd�|d��}x.|D]&}t
||d�r^ttj
d|�f��q^Wt|dd�|D��\}}x$|D]}	|djt|	d	��f�q�Wx$|D]}	|djt|	d	��f�q�W|j|�dS)
Nz%s.addPort('%s', '%s')cs|d�kS)Nrr%)r=)�protocolr%r&�<lambda>�sz-FirewallDConfigZone.addPort.<locals>.<lambda>rtrz%s:%scSsg|]\}}|�qSr%r%)rv�_port�	_protocolr%r%r&�
<listcomp>�sz/FirewallDConfigZone.addPort.<locals>.<listcomp>�-)rr5rr6rrr?rErI�filterrrrrlrrWrrmrT)
r!rwr|r8rG�existing_port_ids�port_id�added_ranges�removed_ranges�ranger%)r|r&�addPort�s"




zFirewallDConfigZone.addPortc
s�t|t�}t�t��tjd|j|��|jj|�t|j��}tt	�fdd�|d��}x0|D]}t
||d�r^Pq^Wttj
d|�f��t|dd�|D��\}}x$|D]}	|djt|	d	��f�q�Wx$|D]}	|djt|	d	��f�q�W|j|�dS)
Nz%s.removePort('%s', '%s')cs|d�kS)Nrr%)r=)r|r%r&r}sz0FirewallDConfigZone.removePort.<locals>.<lambda>rtrz%s:%scSsg|]\}}|�qSr%r%)rvr~rr%r%r&r�sz2FirewallDConfigZone.removePort.<locals>.<listcomp>r�)rr5rr6rrr?rErIr�rrrrprrWrrmrT)
r!rwr|r8rGr�r�r�r�r�r%)r|r&�
removePort�s"




zFirewallDConfigZone.removePortcCsZt|t�}t|t�}tjd|j||�x.|j�dD]\}}t||�r4||kr4dSq4WdS)Nz%s.queryPort('%s', '%s')rtTF)rr5rr6rrIr)r!rwr|r8r~rr%r%r&�	queryPorts

zFirewallDConfigZone.queryPortcCstjd|j�|j�dS)Nz%s.getProtocols()�
)rr6rrI)r!r8r%r%r&�getProtocolssz FirewallDConfigZone.getProtocolscCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setProtocols('[%s]')rir�)
rrErr6rrjrr?rIrT)r!Z	protocolsr8rGr%r%r&�setProtocols&s

z FirewallDConfigZone.setProtocolscCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addProtocol('%s')r�)rr5rr6rrr?rErIrrrlrmrT)r!r|r8rGr%r%r&�addProtocol2s
zFirewallDConfigZone.addProtocolcCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.removeProtocol('%s')r�)rr5rr6rrr?rErIrrrprWrT)r!r|r8rGr%r%r&�removeProtocol?s
z"FirewallDConfigZone.removeProtocolcCs*t|t�}tjd|j|�||j�dkS)Nz%s.queryProtocol('%s')r�)rr5rr6rrI)r!r|r8r%r%r&�
queryProtocolLs
z!FirewallDConfigZone.queryProtocolcCstjd|j�|j�dS)Nz%s.getSourcePorts()�)rr6rrI)r!r8r%r%r&�getSourcePortsVsz"FirewallDConfigZone.getSourcePortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setSourcePorts('[%s]')ricss"|]}d|d|dfVqdS)z('%s, '%s')rrNr%)rvrwr%r%r&rxjsz5FirewallDConfigZone.setSourcePorts.<locals>.<genexpr>r�)
rrErPrmrFrr6rrjrr?rIrT)r!ryr8rzrwrGr%r%r&�setSourcePorts]s

z"FirewallDConfigZone.setSourcePortsc
s�t|t�}t�t��tjd|j|��|jj|�t|j��}tt	�fdd�|d��}x.|D]&}t
||d�r^ttj
d|�f��q^Wt|dd�|D��\}}x$|D]}	|djt|	d	��f�q�Wx$|D]}	|djt|	d	��f�q�W|j|�dS)
Nz%s.addSourcePort('%s', '%s')cs|d�kS)Nrr%)r=)r|r%r&r}zsz3FirewallDConfigZone.addSourcePort.<locals>.<lambda>r�rz%s:%scSsg|]\}}|�qSr%r%)rvr~rr%r%r&r�sz5FirewallDConfigZone.addSourcePort.<locals>.<listcomp>r�)rr5rr6rrr?rErIr�rrrrlrrWrrmrT)
r!rwr|r8rGr�r�r�r�r�r%)r|r&�
addSourcePortps"




z!FirewallDConfigZone.addSourcePortc
s�t|t�}t�t��tjd|j|��|jj|�t|j��}tt	�fdd�|d��}x0|D]}t
||d�r^Pq^Wttj
d|�f��t|dd�|D��\}}x$|D]}	|djt|	d	��f�q�Wx$|D]}	|djt|	d	��f�q�W|j|�dS)
Nz%s.removeSourcePort('%s', '%s')cs|d�kS)Nrr%)r=)r|r%r&r}�sz6FirewallDConfigZone.removeSourcePort.<locals>.<lambda>r�rz%s:%scSsg|]\}}|�qSr%r%)rvr~rr%r%r&r��sz8FirewallDConfigZone.removeSourcePort.<locals>.<listcomp>r�)rr5rr6rrr?rErIr�rrrrprrWrrmrT)
r!rwr|r8rGr�r�r�r�r�r%)r|r&�removeSourcePort�s"




z$FirewallDConfigZone.removeSourcePortcCsZt|t�}t|t�}tjd|j||�x.|j�dD]\}}t||�r4||kr4dSq4WdS)Nz%s.querySourcePort('%s', '%s')r�TF)rr5rr6rrIr)r!rwr|r8r~rr%r%r&�querySourcePort�s

z#FirewallDConfigZone.querySourcePortcCstjd|j�|j�dS)Nz%s.getIcmpBlocks()�)rr6rrI)r!r8r%r%r&�
getIcmpBlocks�sz!FirewallDConfigZone.getIcmpBlockscCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setIcmpBlocks('[%s]')rir�)
rrErr6rrjrr?rIrT)r!Z	icmptypesr8rGr%r%r&�
setIcmpBlocks�s

z!FirewallDConfigZone.setIcmpBlockscCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addIcmpBlock('%s')r�)rr5rr6rrr?rErIrrrlrmrT)r!�icmptyper8rGr%r%r&�addIcmpBlock�s
z FirewallDConfigZone.addIcmpBlockcCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.removeIcmpBlock('%s')r�)rr5rr6rrr?rErIrrrprWrT)r!r�r8rGr%r%r&�removeIcmpBlock�s
z#FirewallDConfigZone.removeIcmpBlockcCs*t|t�}tjd|j|�||j�dkS)Nz%s.queryIcmpBlock('%s')r�)rr5rr6rrI)r!r�r8r%r%r&�queryIcmpBlock�s
z"FirewallDConfigZone.queryIcmpBlockcCstjd|j�|j�dS)Nz%s.getIcmpBlockInversion()�)rr6rrI)r!r8r%r%r&�getIcmpBlockInversion�sz)FirewallDConfigZone.getIcmpBlockInversioncCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setIcmpBlockInversion('%s')r�)
r�boolrr6rrr?rErIrT)r!�flagr8rGr%r%r&�setIcmpBlockInversion�s
z)FirewallDConfigZone.setIcmpBlockInversioncCsPtjd|j�|jj|�t|j��}|dr:ttj	d��d|d<|j
|�dS)Nz%s.addIcmpBlockInversion()r�zicmp-block-inversionT)rr6rrr?rErIrrrlrT)r!r8rGr%r%r&�addIcmpBlockInversion�sz)FirewallDConfigZone.addIcmpBlockInversioncCsPtjd|j�|jj|�t|j��}|ds:ttj	d��d|d<|j
|�dS)Nz%s.removeIcmpBlockInversion()r�zicmp-block-inversionF)rr6rrr?rErIrrrprT)r!r8rGr%r%r&�removeIcmpBlockInversionsz,FirewallDConfigZone.removeIcmpBlockInversioncCstjd|j�|j�dS)Nz%s.queryIcmpBlockInversion()r�)rr6rrI)r!r8r%r%r&�queryIcmpBlockInversionsz+FirewallDConfigZone.queryIcmpBlockInversioncCstjd|j�|j�dS)Nz%s.getMasquerade()�)rr6rrI)r!r8r%r%r&�
getMasqueradesz!FirewallDConfigZone.getMasqueradecCsHt|t�}tjd|j|�|jj|�t|j��}||d<|j	|�dS)Nz%s.setMasquerade('%s')r�)
rr�rr6rrr?rErIrT)r!�
masquerader8rGr%r%r&�
setMasquerades
z!FirewallDConfigZone.setMasqueradecCsPtjd|j�|jj|�t|j��}|dr:ttj	d��d|d<|j
|�dS)Nz%s.addMasquerade()r�r�T)rr6rrr?rErIrrrlrT)r!r8rGr%r%r&�
addMasquerade'sz!FirewallDConfigZone.addMasqueradecCsPtjd|j�|jj|�t|j��}|ds:ttj	d��d|d<|j
|�dS)Nz%s.removeMasquerade()r�r�F)rr6rrr?rErIrrrprT)r!r8rGr%r%r&�removeMasquerade2sz$FirewallDConfigZone.removeMasqueradecCstjd|j�|j�dS)Nz%s.queryMasquerade()r�)rr6rrI)r!r8r%r%r&�queryMasquerade=sz#FirewallDConfigZone.queryMasqueradeza(ssss)cCstjd|j�|j�dS)Nz%s.getForwardPorts()�	)rr6rrI)r!r8r%r%r&�getForwardPortsFsz#FirewallDConfigZone.getForwardPortscCs�g}x6t|t�D](}t|t�r.|jt|��q|j|�qW|}tjd|jdjdd�|D���|j	j
|�t|j��}||d<|j|�dS)Nz%s.setForwardPorts('[%s]')ricss.|]&}d|d|d|d|dfVqdS)z('%s, '%s', '%s', '%s')rrr`�Nr%)rvrwr%r%r&rxZsz6FirewallDConfigZone.setForwardPorts.<locals>.<genexpr>r�)
rrErPrmrFrr6rrjrr?rIrT)r!ryr8rzrwrGr%r%r&�setForwardPortsMs


z#FirewallDConfigZone.setForwardPortsZsssscCs�t|t�}t|t�}t|t�}t|t�}tjd|j||||�|jj|�||t|�t|�f}t|j��}||dkr�t	t
jd||||f��|dj|�|j
|�dS)Nz)%s.addForwardPort('%s', '%s', '%s', '%s')r�z%s:%s:%s:%s)rr5rr6rrr?rErIrrrlrmrT)r!rwr|�toport�toaddrr8�fwp_idrGr%r%r&�addForwardPortas




z"FirewallDConfigZone.addForwardPortcCs�t|t�}t|t�}t|t�}t|t�}tjd|j||||�|jj|�||t|�t|�f}t|j��}||dkr�t	t
jd||||f��|dj|�|j
|�dS)Nz,%s.removeForwardPort('%s', '%s', '%s', '%s')r�z%s:%s:%s:%s)rr5rr6rrr?rErIrrrprWrT)r!rwr|r�r�r8r�rGr%r%r&�removeForwardPortus




z%FirewallDConfigZone.removeForwardPortcCsbt|t�}t|t�}t|t�}t|t�}tjd|j||||�||t|�t|�f}||j�dkS)Nz+%s.queryForwardPort('%s', '%s', '%s', '%s')r�)rr5rr6rrI)r!rwr|r�r�r8r�r%r%r&�queryForwardPort�s



z$FirewallDConfigZone.queryForwardPortcCstjd|j�|j�dS)Nz%s.getInterfaces()�
)rr6rrI)r!r8r%r%r&�
getInterfaces�sz!FirewallDConfigZone.getInterfacescCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setInterfaces('[%s]')rir�)
rrErr6rrjrr?rIrT)r!rMr8rGr%r%r&�
setInterfaces�s

z!FirewallDConfigZone.setInterfacescCstt|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�t|jj|�dS)Nz%s.addInterface('%s')r�)rr5rr6rrr?rErIrrrlrmrTrrr))r!�	interfacer8rGr%r%r&�addInterface�s

z FirewallDConfigZone.addInterfacecCspt|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�td|�dS)Nz%s.removeInterface('%s')r��)rr5rr6rrr?rErIrrrprWrTr)r!r�r8rGr%r%r&�removeInterface�s

z#FirewallDConfigZone.removeInterfacecCs*t|t�}tjd|j|�||j�dkS)Nz%s.queryInterface('%s')r�)rr5rr6rrI)r!r�r8r%r%r&�queryInterface�s
z"FirewallDConfigZone.queryInterfacecCstjd|j�|j�dS)Nz%s.getSources()�)rr6rrI)r!r8r%r%r&�
getSources�szFirewallDConfigZone.getSourcescCsNt|t�}tjd|jdj|��|jj|�t|j��}||d<|j	|�dS)Nz%s.setSources('[%s]')rir�)
rrErr6rrjrr?rIrT)r!rNr8rGr%r%r&�
setSources�s

zFirewallDConfigZone.setSourcescCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.addSource('%s')r�)rr5rr6rrr?rErIrrrlrmrT)r!rQr8rGr%r%r&�	addSource�s
zFirewallDConfigZone.addSourcecCsft|t�}tjd|j|�|jj|�t|j��}||dkrJt	t
j|��|dj|�|j
|�dS)Nz%s.removeSource('%s')r�)rr5rr6rrr?rErIrrrprWrT)r!rQr8rGr%r%r&�removeSource�s
z FirewallDConfigZone.removeSourcecCs*t|t�}tjd|j|�||j�dkS)Nz%s.querySource('%s')r�)rr5rr6rrI)r!rQr8r%r%r&�querySources
zFirewallDConfigZone.querySourcecCstjd|j�|j�dS)Nz%s.getRichRules()�)rr6rrI)r!r8r%r%r&�getRichRulessz FirewallDConfigZone.getRichRulescCs\t|t�}tjd|jdj|��|jj|�t|j��}dd�|D�}||d<|j	|�dS)Nz%s.setRichRules('[%s]')ricSsg|]}tt|d���qS))�rule_str)r5r
)rv�rr%r%r&r�sz4FirewallDConfigZone.setRichRules.<locals>.<listcomp>r�)
rrErr6rrjrr?rIrT)r!Zrulesr8rGr%r%r&�setRichRuless

z FirewallDConfigZone.setRichRulescCstt|t�}tjd|j|�|jj|�t|j��}tt	|d��}||dkrXt
tj|��|dj
|�|j|�dS)Nz%s.addRichRule('%s'))r�r�)rr5rr6rrr?rErIr
rrrlrmrT)r!�ruler8rGr�r%r%r&�addRichRule s
zFirewallDConfigZone.addRichRulecCstt|t�}tjd|j|�|jj|�t|j��}tt	|d��}||dkrXt
tj|��|dj
|�|j|�dS)Nz%s.removeRichRule('%s'))r�r�)rr5rr6rrr?rErIr
rrrprWrT)r!r�r8rGr�r%r%r&�removeRichRule.s
z"FirewallDConfigZone.removeRichRulecCs8t|t�}tjd|j|�tt|d��}||j�dkS)Nz%s.queryRichRule('%s'))r�r�)rr5rr6rr
rI)r!r�r8r�r%r%r&�
queryRichRule<s
z!FirewallDConfigZone.queryRichRule)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)i�__name__�
__module__�__qualname__�__doc__Z
persistentrrZPK_ACTION_CONFIGZdefault_polkit_auth_requiredrrr
r'r(r1rZPROPERTIES_IFACEr9r>�slipZpolkitZrequire_authr@rn�signalrAZPK_ACTION_INFOZINTROSPECTABLE_IFACErBr rIrLrRrTrUrVrSrWrXrZrYr[r]r^r_rarcrdrerhrkrorqrsrur{r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r��
__classcell__r%r%)r$r&r5sf
		

	



	


	


	


	
	
	
			


r)(Z
gi.repositoryr�sys�modulesrZdbus.serviceZ	slip.dbusr�Zslip.dbus.serviceZfirewallrZfirewall.dbus_utilsrrrZfirewall.core.io.zonerZfirewall.core.fw_ifcfgrZfirewall.core.baser	Zfirewall.core.richr
Zfirewall.core.loggerrZfirewall.server.decoratorsrr
rrZfirewall.errorsrZfirewall.functionsrrrrrnZObjectrr%r%r%r&�<module>s$
	server/__pycache__/__init__.cpython-36.pyc000064400000000161150351351720014447 0ustar003

��g�@sdS)N�rrr�/usr/lib/python3.6/__init__.py�<module>sserver/__pycache__/__init__.cpython-36.opt-1.pyc000064400000000161150351351720015406 0ustar003

��g�@sdS)N�rrr�/usr/lib/python3.6/__init__.py�<module>sserver/config_ipset.py000064400000044572150351351720011113 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2015-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.

# force use of pygobject3 in python-slip
from gi.repository import GObject
import sys
sys.modules['gobject'] = GObject

import dbus
import dbus.service
import slip.dbus
import slip.dbus.service

from firewall import config
from firewall.dbus_utils import dbus_to_python, \
    dbus_introspection_prepare_properties, \
    dbus_introspection_add_properties
from firewall.core.io.ipset import IPSet
from firewall.core.ipset import IPSET_TYPES, normalize_ipset_entry, \
                                check_entry_overlaps_existing, \
                                check_for_overlapping_entries
from firewall.core.logger import log
from firewall.server.decorators import handle_exceptions, \
    dbus_handle_exceptions, dbus_service_method
from firewall import errors
from firewall.errors import FirewallError

############################################################################
#
# class FirewallDConfigIPSet
#
############################################################################

class FirewallDConfigIPSet(slip.dbus.service.Object):
    """FirewallD main class"""

    persistent = True
    """ Make FirewallD persistent. """
    default_polkit_auth_required = config.dbus.PK_ACTION_CONFIG
    """ Use PK_ACTION_INFO as a default """

    @handle_exceptions
    def __init__(self, parent, conf, ipset, item_id, *args, **kwargs):
        super(FirewallDConfigIPSet, self).__init__(*args, **kwargs)
        self.parent = parent
        self.config = conf
        self.obj = ipset
        self.item_id = item_id
        self.busname = args[0]
        self.path = args[1]
        self._log_prefix = "config.ipset.%d" % self.item_id
        dbus_introspection_prepare_properties(
            self, config.dbus.DBUS_INTERFACE_CONFIG_IPSET)

    @dbus_handle_exceptions
    def __del__(self):
        pass

    @dbus_handle_exceptions
    def unregister(self):
        self.remove_from_connection()

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # P R O P E R T I E S

    @dbus_handle_exceptions
    def _get_property(self, property_name):
        if property_name == "name":
            return dbus.String(self.obj.name)
        elif property_name == "filename":
            return dbus.String(self.obj.filename)
        elif property_name == "path":
            return dbus.String(self.obj.path)
        elif property_name == "default":
            return dbus.Boolean(self.obj.default)
        elif property_name == "builtin":
            return dbus.Boolean(self.obj.builtin)
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ss',
                         out_signature='v')
    @dbus_handle_exceptions
    def Get(self, interface_name, property_name, sender=None): # pylint: disable=W0613
        # get a property
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        log.debug1("%s.Get('%s', '%s')", self._log_prefix,
                   interface_name, property_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_IPSET:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        return self._get_property(property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='s',
                         out_signature='a{sv}')
    @dbus_handle_exceptions
    def GetAll(self, interface_name, sender=None): # pylint: disable=W0613
        interface_name = dbus_to_python(interface_name, str)
        log.debug1("%s.GetAll('%s')", self._log_prefix, interface_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_IPSET:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        ret = { }
        for x in [ "name", "filename", "path", "default", "builtin" ]:
            ret[x] = self._get_property(x)
        return dbus.Dictionary(ret, signature="sv")

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ssv')
    @dbus_handle_exceptions
    def Set(self, interface_name, property_name, new_value, sender=None):
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        new_value = dbus_to_python(new_value)
        log.debug1("%s.Set('%s', '%s', '%s')", self._log_prefix,
                   interface_name, property_name, new_value)
        self.parent.accessCheck(sender)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_IPSET:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        raise dbus.exceptions.DBusException(
            "org.freedesktop.DBus.Error.PropertyReadOnly: "
            "Property '%s' is read-only" % property_name)

    @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as')
    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)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(dbus.INTROSPECTABLE_IFACE, out_signature='s')
    @dbus_handle_exceptions
    def Introspect(self, sender=None): # pylint: disable=W0613
        log.debug2("%s.Introspect()", self._log_prefix)

        data = super(FirewallDConfigIPSet, self).Introspect(
            self.path, self.busname.get_bus())

        return dbus_introspection_add_properties(
            self, data, config.dbus.DBUS_INTERFACE_CONFIG_IPSET)

    # S E T T I N G S

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         out_signature=IPSet.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def getSettings(self, sender=None): # pylint: disable=W0613
        """get settings for ipset
        """
        log.debug1("%s.getSettings()", self._log_prefix)
        return self.config.get_ipset_config(self.obj)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature=IPSet.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def update(self, settings, sender=None):
        """update settings for ipset
        """
        settings = dbus_to_python(settings)
        log.debug1("%s.update('...')", self._log_prefix)
        self.parent.accessCheck(sender)
        self.obj = self.config.set_ipset_config(self.obj, settings)
        self.Updated(self.obj.name)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET)
    @dbus_handle_exceptions
    def loadDefaults(self, sender=None):
        """load default settings for builtin ipset
        """
        log.debug1("%s.loadDefaults()", self._log_prefix)
        self.parent.accessCheck(sender)
        self.obj = self.config.load_ipset_defaults(self.obj)
        self.Updated(self.obj.name)
        #self.PropertiesChanged(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
        #                       { "default": True }, [ ])

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_IPSET, signature='s')
    @dbus_handle_exceptions
    def Updated(self, name):
        log.debug1("%s.Updated('%s')" % (self._log_prefix, name))

    # R E M O V E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET)
    @dbus_handle_exceptions
    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)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_IPSET, signature='s')
    @dbus_handle_exceptions
    def Removed(self, name):
        log.debug1("%s.Removed('%s')" % (self._log_prefix, name))

    # R E N A M E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='s')
    @dbus_handle_exceptions
    def rename(self, name, sender=None):
        """rename ipset
        """
        name = dbus_to_python(name, str)
        log.debug1("%s.rename('%s')", self._log_prefix, name)
        self.parent.accessCheck(sender)
        self.obj = self.config.rename_ipset(self.obj, name)
        self.Renamed(name)
        #self.PropertiesChanged(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
        #                       { "name": name }, [ ])

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_IPSET, signature='s')
    @dbus_handle_exceptions
    def Renamed(self, name):
        log.debug1("%s.Renamed('%s')" % (self._log_prefix, name))

    # version

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         out_signature='s')
    @dbus_handle_exceptions
    def getVersion(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getVersion()", self._log_prefix)
        return self.getSettings()[0]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # short

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         out_signature='s')
    @dbus_handle_exceptions
    def getShort(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getShort()", self._log_prefix)
        return self.getSettings()[1]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # description

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         out_signature='s')
    @dbus_handle_exceptions
    def getDescription(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getDescription()", self._log_prefix)
        return self.getSettings()[2]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # type

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         out_signature='s')
    @dbus_handle_exceptions
    def getType(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getType()", self._log_prefix)
        return self.getSettings()[3]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='s')
    @dbus_handle_exceptions
    def setType(self, ipset_type, sender=None):
        ipset_type = dbus_to_python(ipset_type, str)
        log.debug1("%s.setType('%s')", self._log_prefix, ipset_type)
        self.parent.accessCheck(sender)
        if ipset_type not in IPSET_TYPES:
            raise FirewallError(errors.INVALID_TYPE, ipset_type)
        settings = list(self.getSettings())
        settings[3] = ipset_type
        self.update(settings)

    # options

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         out_signature='a{ss}')
    @dbus_handle_exceptions
    def getOptions(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getOptions()", self._log_prefix)
        return self.getSettings()[4]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='a{ss}')
    @dbus_handle_exceptions
    def setOptions(self, options, sender=None):
        options = dbus_to_python(options, dict)
        log.debug1("%s.setOptions('[%s]')", self._log_prefix,
                   repr(options))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[4] = options
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='ss')
    @dbus_handle_exceptions
    def addOption(self, key, value, sender=None):
        key = dbus_to_python(key, str)
        value = dbus_to_python(value, str)
        log.debug1("%s.addOption('%s', '%s')", self._log_prefix, key, value)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if key in settings[4] and settings[4][key] == value:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s': '%s'" % (key, value))
        settings[4][key] = value
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeOption(self, key, sender=None):
        key = dbus_to_python(key, str)
        log.debug1("%s.removeOption('%s')", self._log_prefix, key)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if key not in settings[4]:
            raise FirewallError(errors.NOT_ENABLED, key)
        del settings[4][key]
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='ss',
                         out_signature='b')
    @dbus_handle_exceptions
    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)

    # entries

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         out_signature='as')
    @dbus_handle_exceptions
    def getEntries(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getEntries()", self._log_prefix)
        return self.getSettings()[5]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='as')
    @dbus_handle_exceptions
    def setEntries(self, entries, sender=None):
        entries = dbus_to_python(entries, list)
        check_for_overlapping_entries(entries)
        log.debug1("%s.setEntries('[%s]')", self._log_prefix,
                   ",".join(entries))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if "timeout" in settings[4] and settings[4]["timeout"] != "0":
            raise FirewallError(errors.IPSET_WITH_TIMEOUT)
        settings[5] = entries
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='s')
    @dbus_handle_exceptions
    def addEntry(self, entry, sender=None):
        entry = dbus_to_python(entry, str)
        entry = normalize_ipset_entry(entry)
        log.debug1("%s.addEntry('%s')", self._log_prefix, entry)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if "timeout" in settings[4] and settings[4]["timeout"] != "0":
            raise FirewallError(errors.IPSET_WITH_TIMEOUT)
        if entry in settings[5]:
            raise FirewallError(errors.ALREADY_ENABLED, entry)
        check_entry_overlaps_existing(entry, settings[5])
        settings[5].append(entry)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeEntry(self, entry, sender=None):
        entry = dbus_to_python(entry, str)
        entry = normalize_ipset_entry(entry)
        log.debug1("%s.removeEntry('%s')", self._log_prefix, entry)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if "timeout" in settings[4] and settings[4]["timeout"] != "0":
            raise FirewallError(errors.IPSET_WITH_TIMEOUT)
        if entry not in settings[5]:
            raise FirewallError(errors.NOT_ENABLED, entry)
        settings[5].remove(entry)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_IPSET,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    def queryEntry(self, entry, sender=None): # pylint: disable=W0613
        entry = dbus_to_python(entry, str)
        entry = normalize_ipset_entry(entry)
        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]
server/config.py000064400000211644150351351720007703 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.

# force use of pygobject3 in python-slip
from gi.repository import GObject
import sys
sys.modules['gobject'] = GObject
import os

import dbus
import dbus.service
import slip.dbus
import slip.dbus.service

from firewall import config
from firewall.core.base import DEFAULT_ZONE_TARGET
from firewall.core.watcher import Watcher
from firewall.core.logger import log
from firewall.server.decorators import handle_exceptions, \
    dbus_handle_exceptions, dbus_service_method
from firewall.server.config_icmptype import FirewallDConfigIcmpType
from firewall.server.config_service import FirewallDConfigService
from firewall.server.config_zone import FirewallDConfigZone
from firewall.server.config_policy import FirewallDConfigPolicy
from firewall.server.config_ipset import FirewallDConfigIPSet
from firewall.server.config_helper import FirewallDConfigHelper
from firewall.core.io.icmptype import IcmpType
from firewall.core.io.ipset import IPSet
from firewall.core.io.helper import Helper
from firewall.core.io.lockdown_whitelist import LockdownWhitelist
from firewall.core.io.direct import Direct
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 import errors
from firewall.errors import FirewallError

############################################################################
#
# class FirewallDConfig
#
############################################################################

class FirewallDConfig(slip.dbus.service.Object):
    """FirewallD main class"""

    persistent = True
    """ Make FirewallD persistent. """
    default_polkit_auth_required = config.dbus.PK_ACTION_CONFIG
    """ Use config.dbus.PK_ACTION_INFO as a default """

    @handle_exceptions
    def __init__(self, conf, *args, **kwargs):
        super(FirewallDConfig, self).__init__(*args, **kwargs)
        self.config = conf
        self.busname = args[0]
        self.path = args[1]
        self._init_vars()
        self.watcher = Watcher(self.watch_updater, 5)
        self.watcher.add_watch_dir(config.FIREWALLD_IPSETS)
        self.watcher.add_watch_dir(config.ETC_FIREWALLD_IPSETS)
        self.watcher.add_watch_dir(config.FIREWALLD_ICMPTYPES)
        self.watcher.add_watch_dir(config.ETC_FIREWALLD_ICMPTYPES)
        self.watcher.add_watch_dir(config.FIREWALLD_HELPERS)
        self.watcher.add_watch_dir(config.ETC_FIREWALLD_HELPERS)
        self.watcher.add_watch_dir(config.FIREWALLD_SERVICES)
        self.watcher.add_watch_dir(config.ETC_FIREWALLD_SERVICES)
        self.watcher.add_watch_dir(config.FIREWALLD_ZONES)
        self.watcher.add_watch_dir(config.ETC_FIREWALLD_ZONES)
        self.watcher.add_watch_dir(config.FIREWALLD_POLICIES)
        self.watcher.add_watch_dir(config.ETC_FIREWALLD_POLICIES)
        # Add watches for combined zone directories
        if os.path.exists(config.ETC_FIREWALLD_ZONES):
            for filename in sorted(os.listdir(config.ETC_FIREWALLD_ZONES)):
                path = "%s/%s" % (config.ETC_FIREWALLD_ZONES, filename)
                if os.path.isdir(path):
                    self.watcher.add_watch_dir(path)
        self.watcher.add_watch_file(config.LOCKDOWN_WHITELIST)
        self.watcher.add_watch_file(config.FIREWALLD_DIRECT)
        self.watcher.add_watch_file(config.FIREWALLD_CONF)

        dbus_introspection_prepare_properties(self,
                                              config.dbus.DBUS_INTERFACE_CONFIG,
                                              { "CleanupOnExit": "readwrite",
                                                "CleanupModulesOnExit": "readwrite",
                                                "IPv6_rpfilter": "readwrite",
                                                "Lockdown": "readwrite",
                                                "MinimalMark": "readwrite",
                                                "IndividualCalls": "readwrite",
                                                "LogDenied": "readwrite",
                                                "AutomaticHelpers": "readwrite",
                                                "FirewallBackend": "readwrite",
                                                "FlushAllOnReload": "readwrite",
                                                "RFC3964_IPv4": "readwrite",
                                                "AllowZoneDrifting": "readwrite",
                                              })

    @handle_exceptions
    def _init_vars(self):
        self.ipsets = [ ]
        self.ipset_idx = 0
        self.icmptypes = [ ]
        self.icmptype_idx = 0
        self.services = [ ]
        self.service_idx = 0
        self.zones = [ ]
        self.zone_idx = 0
        self.helpers = [ ]
        self.helper_idx = 0
        self.policy_objects = [ ]
        self.policy_object_idx = 0

        for ipset in self.config.get_ipsets():
            self._addIPSet(self.config.get_ipset(ipset))
        for icmptype in self.config.get_icmptypes():
            self._addIcmpType(self.config.get_icmptype(icmptype))
        for service in self.config.get_services():
            self._addService(self.config.get_service(service))
        for zone in self.config.get_zones():
            self._addZone(self.config.get_zone(zone))
        for helper in self.config.get_helpers():
            self._addHelper(self.config.get_helper(helper))
        for policy in self.config.get_policy_objects():
            self._addPolicy(self.config.get_policy_object(policy))

    @handle_exceptions
    def __del__(self):
        pass

    @handle_exceptions
    def reload(self):
        while len(self.ipsets) > 0:
            item = self.ipsets.pop()
            item.unregister()
            del item
        while len(self.icmptypes) > 0:
            item = self.icmptypes.pop()
            item.unregister()
            del item
        while len(self.services) > 0:
            item = self.services.pop()
            item.unregister()
            del item
        while len(self.zones) > 0:
            item = self.zones.pop()
            item.unregister()
            del item
        while len(self.helpers) > 0:
            item = self.helpers.pop()
            item.unregister()
            del item
        while len(self.policy_objects) > 0:
            item = self.policy_objects.pop()
            item.unregister()
            del item
        self._init_vars()

    @handle_exceptions
    def watch_updater(self, name):
        if name == config.FIREWALLD_CONF:
            old_props = self.GetAll(config.dbus.DBUS_INTERFACE_CONFIG)
            log.debug1("config: Reloading firewalld config file '%s'",
                       config.FIREWALLD_CONF)
            try:
                self.config.update_firewalld_conf()
            except Exception as msg:
                log.error("Failed to load firewalld.conf file '%s': %s" % \
                          (name, msg))
                return
            props = self.GetAll(config.dbus.DBUS_INTERFACE_CONFIG).copy()
            for key in list(props.keys()):
                if key in old_props and old_props[key] == props[key]:
                    del props[key]
            if len(props) > 0:
                self.PropertiesChanged(config.dbus.DBUS_INTERFACE_CONFIG,
                                       props, [])
            return

        if (name.startswith(config.FIREWALLD_ICMPTYPES) or \
            name.startswith(config.ETC_FIREWALLD_ICMPTYPES)) and \
           name.endswith(".xml"):
            try:
                (what, obj) = self.config.update_icmptype_from_path(name)
            except Exception as msg:
                log.error("Failed to load icmptype file '%s': %s" % (name, msg))
                return
            if what == "new":
                self._addIcmpType(obj)
            elif what == "remove":
                self.removeIcmpType(obj)
            elif what == "update":
                self._updateIcmpType(obj)

        elif (name.startswith(config.FIREWALLD_SERVICES) or \
              name.startswith(config.ETC_FIREWALLD_SERVICES)) and \
             name.endswith(".xml"):
            try:
                (what, obj) = self.config.update_service_from_path(name)
            except Exception as msg:
                log.error("Failed to load service file '%s': %s" % (name, msg))
                return
            if what == "new":
                self._addService(obj)
            elif what == "remove":
                self.removeService(obj)
            elif what == "update":
                self._updateService(obj)

        elif name.startswith(config.FIREWALLD_ZONES) or \
             name.startswith(config.ETC_FIREWALLD_ZONES):
            if name.endswith(".xml"):
                try:
                    (what, obj) = self.config.update_zone_from_path(name)
                except Exception as msg:
                    log.error("Failed to load zone file '%s': %s" % (name, msg))
                    return
                if what == "new":
                    self._addZone(obj)
                elif what == "remove":
                    self.removeZone(obj)
                elif what == "update":
                    self._updateZone(obj)
            elif name.startswith(config.ETC_FIREWALLD_ZONES):
                # possible combined zone base directory
                _name = name.replace(config.ETC_FIREWALLD_ZONES, "").strip("/")
                if len(_name) < 1 or "/" in _name:
                    # if there is a / in x, then it is a sub sub directory
                    # ignore it
                    return
                if os.path.isdir(name):
                    if not self.watcher.has_watch(name):
                        self.watcher.add_watch_dir(name)
                elif self.watcher.has_watch(name):
                    self.watcher.remove_watch(name)

        elif (name.startswith(config.FIREWALLD_IPSETS) or \
              name.startswith(config.ETC_FIREWALLD_IPSETS)) and \
             name.endswith(".xml"):
            try:
                (what, obj) = self.config.update_ipset_from_path(name)
            except Exception as msg:
                log.error("Failed to load ipset file '%s': %s" % (name,
                                                                  msg))

                return
            if what == "new":
                self._addIPSet(obj)
            elif what == "remove":
                self.removeIPSet(obj)
            elif what == "update":
                self._updateIPSet(obj)

        elif (name.startswith(config.FIREWALLD_HELPERS) or \
              name.startswith(config.ETC_FIREWALLD_HELPERS)) and \
             name.endswith(".xml"):
            try:
                (what, obj) = self.config.update_helper_from_path(name)
            except Exception as msg:
                log.error("Failed to load helper file '%s': %s" % (name,
                                                                  msg))

                return
            if what == "new":
                self._addHelper(obj)
            elif what == "remove":
                self.removeHelper(obj)
            elif what == "update":
                self._updateHelper(obj)

        elif name == config.LOCKDOWN_WHITELIST:
            try:
                self.config.update_lockdown_whitelist()
            except Exception as msg:
                log.error("Failed to load lockdown whitelist file '%s': %s" % \
                          (name, msg))
                return
            self.LockdownWhitelistUpdated()

        elif name == config.FIREWALLD_DIRECT:
            try:
                self.config.update_direct()
            except Exception as msg:
                log.error("Failed to load direct rules file '%s': %s" % (name,
                                                                         msg))
                return
            self.Updated()

        elif (name.startswith(config.FIREWALLD_POLICIES) or \
              name.startswith(config.ETC_FIREWALLD_POLICIES)) and \
             name.endswith(".xml"):
            try:
                (what, obj) = self.config.update_policy_object_from_path(name)
            except Exception as msg:
                log.error("Failed to load policy file '%s': %s" % (name, msg))
                return
            if what == "new":
                self._addPolicy(obj)
            elif what == "remove":
                self.removePolicy(obj)
            elif what == "update":
                self._updatePolicy(obj)

    @handle_exceptions
    def _addIcmpType(self, obj):
        # TODO: check for idx overflow
        config_icmptype = FirewallDConfigIcmpType(
            self, self.config, obj, self.icmptype_idx, self.busname,
            "%s/%d" % (config.dbus.DBUS_PATH_CONFIG_ICMPTYPE,
                       self.icmptype_idx))
        self.icmptypes.append(config_icmptype)
        self.icmptype_idx += 1
        self.IcmpTypeAdded(obj.name)
        return config_icmptype

    @handle_exceptions
    def _updateIcmpType(self, obj):
        for icmptype in self.icmptypes:
            if icmptype.obj.name == obj.name and \
                    icmptype.obj.path == obj.path and \
                    icmptype.obj.filename == obj.filename:
                icmptype.obj = obj
                icmptype.Updated(obj.name)

    @handle_exceptions
    def removeIcmpType(self, obj):
        index = 7 # see IMPORT_EXPORT_STRUCTURE in class Zone(IO_Object)
        for zone in self.zones:
            settings = zone.getSettings()
            # if this IcmpType is used in a zone remove it from that zone first
            if obj.name in settings[index]:
                settings[index].remove(obj.name)
                zone.obj = self.config.set_zone_config(zone.obj, settings)
                zone.Updated(zone.obj.name)

        for policy in self.policy_objects:
            settings = policy.getSettings()
            # if this IcmpType is used in a policy remove it from that policy first
            if "icmp_blocks" in settings and obj.name in settings["icmp_blocks"]:
                settings["icmp_blocks"].remove(obj.name)
                policy.obj = self.config.set_policy_object_config_dict(policy.obj, settings)
                policy.Updated(policy.obj.name)

        for icmptype in self.icmptypes:
            if icmptype.obj == obj:
                icmptype.Removed(obj.name)
                icmptype.unregister()
                self.icmptypes.remove(icmptype)
                del icmptype

    @handle_exceptions
    def _addService(self, obj):
        # TODO: check for idx overflow
        config_service = FirewallDConfigService(
            self, self.config, obj, self.service_idx, self.busname,
            "%s/%d" % (config.dbus.DBUS_PATH_CONFIG_SERVICE, self.service_idx))
        self.services.append(config_service)
        self.service_idx += 1
        self.ServiceAdded(obj.name)
        return config_service

    @handle_exceptions
    def _updateService(self, obj):
        for service in self.services:
            if service.obj.name == obj.name and \
                    service.obj.path == obj.path and \
                    service.obj.filename == obj.filename:
                service.obj = obj
                service.Updated(obj.name)

    @handle_exceptions
    def removeService(self, obj):
        index = 5 # see IMPORT_EXPORT_STRUCTURE in class Zone(IO_Object)
        for zone in self.zones:
            settings = zone.getSettings()
            # if this Service is used in a zone remove it from that zone first
            if obj.name in settings[index]:
                settings[index].remove(obj.name)
                zone.obj = self.config.set_zone_config(zone.obj, settings)
                zone.Updated(zone.obj.name)

        for policy in self.policy_objects:
            settings = policy.getSettings()
            # if this Service is used in a policy remove it from that policy first
            if "services" in settings and obj.name in settings["services"]:
                settings["services"].remove(obj.name)
                policy.obj = self.config.set_policy_object_config_dict(policy.obj, settings)
                policy.Updated(policy.obj.name)

        for service in self.services:
            if service.obj == obj:
                service.Removed(obj.name)
                service.unregister()
                self.services.remove(service)
                del service

    @handle_exceptions
    def _addZone(self, obj):
        # TODO: check for idx overflow
        config_zone = FirewallDConfigZone(
            self, self.config, obj, self.zone_idx, self.busname,
            "%s/%d" % (config.dbus.DBUS_PATH_CONFIG_ZONE, self.zone_idx))
        self.zones.append(config_zone)
        self.zone_idx += 1
        self.ZoneAdded(obj.name)
        return config_zone

    @handle_exceptions
    def _updateZone(self, obj):
        for zone in self.zones:
            if zone.obj.name == obj.name and zone.obj.path == obj.path and \
                    zone.obj.filename == obj.filename:
                zone.obj = obj
                zone.Updated(obj.name)

    @handle_exceptions
    def removeZone(self, obj):
        for zone in self.zones:
            if zone.obj == obj:
                zone.Removed(obj.name)
                zone.unregister()
                self.zones.remove(zone)
                del zone

    @handle_exceptions
    def _addPolicy(self, obj):
        # TODO: check for idx overflow
        config_policy = FirewallDConfigPolicy(
            self, self.config, obj, self.policy_object_idx, self.busname,
            "%s/%d" % (config.dbus.DBUS_PATH_CONFIG_POLICY, self.policy_object_idx))
        self.policy_objects.append(config_policy)
        self.policy_object_idx += 1
        self.PolicyAdded(obj.name)
        return config_policy

    @handle_exceptions
    def _updatePolicy(self, obj):
        for policy in self.policy_objects:
            if policy.obj.name == obj.name and policy.obj.path == obj.path and \
                    policy.obj.filename == obj.filename:
                policy.obj = obj
                policy.Updated(obj.name)

    @handle_exceptions
    def removePolicy(self, obj):
        for policy in self.policy_objects:
            if policy.obj == obj:
                policy.Removed(obj.name)
                policy.unregister()
                self.policy_objects.remove(policy)
                del policy

    @handle_exceptions
    def _addIPSet(self, obj):
        # TODO: check for idx overflow
        config_ipset = FirewallDConfigIPSet(
            self, self.config, obj, self.ipset_idx, self.busname,
            "%s/%d" % (config.dbus.DBUS_PATH_CONFIG_IPSET, self.ipset_idx))
        self.ipsets.append(config_ipset)
        self.ipset_idx += 1
        self.IPSetAdded(obj.name)
        return config_ipset

    @handle_exceptions
    def _updateIPSet(self, obj):
        for ipset in self.ipsets:
            if ipset.obj.name == obj.name and ipset.obj.path == obj.path and \
                    ipset.obj.filename == obj.filename:
                ipset.obj = obj
                ipset.Updated(obj.name)

    @handle_exceptions
    def removeIPSet(self, obj):
        for ipset in self.ipsets:
            if ipset.obj == obj:
                ipset.Removed(obj.name)
                ipset.unregister()
                self.ipsets.remove(ipset)
                del ipset

    # access check

    @handle_exceptions
    def _addHelper(self, obj):
        # TODO: check for idx overflow
        config_helper = FirewallDConfigHelper(
            self, self.config, obj, self.helper_idx, self.busname,
            "%s/%d" % (config.dbus.DBUS_PATH_CONFIG_HELPER, self.helper_idx))
        self.helpers.append(config_helper)
        self.helper_idx += 1
        self.HelperAdded(obj.name)
        return config_helper

    @handle_exceptions
    def _updateHelper(self, obj):
        for helper in self.helpers:
            if helper.obj.name == obj.name and helper.obj.path == obj.path and \
                    helper.obj.filename == obj.filename:
                helper.obj = obj
                helper.Updated(obj.name)

    @handle_exceptions
    def removeHelper(self, obj):
        for helper in self.helpers:
            if helper.obj == obj:
                helper.Removed(obj.name)
                helper.unregister()
                self.helpers.remove(helper)
                del helper

    # access check

    @dbus_handle_exceptions
    def accessCheck(self, sender):
        if self.config.lockdown_enabled():
            if sender is None:
                log.error("Lockdown not possible, sender not set.")
                return
            bus = dbus.SystemBus()
            context = context_of_sender(bus, sender)
            if self.config.access_check("context", context):
                return
            uid = uid_of_sender(bus, sender)
            if self.config.access_check("uid", uid):
                return
            user = user_of_uid(uid)
            if self.config.access_check("user", user):
                return
            command = command_of_sender(bus, sender)
            if self.config.access_check("command", command):
                return
            raise FirewallError(errors.ACCESS_DENIED, "lockdown is enabled")

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # P R O P E R T I E S

    @dbus_handle_exceptions
    def _get_property(self, prop):
        if prop not in [ "DefaultZone", "MinimalMark", "CleanupOnExit",
                         "CleanupModulesOnExit", "Lockdown", "IPv6_rpfilter",
                         "IndividualCalls", "LogDenied", "AutomaticHelpers",
                         "FirewallBackend", "FlushAllOnReload", "RFC3964_IPv4",
                         "AllowZoneDrifting" ]:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % prop)

        value = self.config.get_firewalld_conf().get(prop)

        if prop == "DefaultZone":
            if value is None:
                value = config.FALLBACK_ZONE
            return dbus.String(value)
        elif prop == "MinimalMark":
            if value is None:
                value = config.FALLBACK_MINIMAL_MARK
            else:
                value = int(value)
            return dbus.Int32(value)
        elif prop == "CleanupOnExit":
            if value is None:
                value = "yes" if config.FALLBACK_CLEANUP_ON_EXIT else "no"
            return dbus.String(value)
        elif prop == "CleanupModulesOnExit":
            if value is None:
                value = "yes" if config.FALLBACK_CLEANUP_MODULES_ON_EXIT else "no"
            return dbus.String(value)
        elif prop == "Lockdown":
            if value is None:
                value = "yes" if config.FALLBACK_LOCKDOWN else "no"
            return dbus.String(value)
        elif prop == "IPv6_rpfilter":
            if value is None:
                value = "yes" if config.FALLBACK_IPV6_RPFILTER else "no"
            return dbus.String(value)
        elif prop == "IndividualCalls":
            if value is None:
                value = "yes" if config.FALLBACK_INDIVIDUAL_CALLS else "no"
            return dbus.String(value)
        elif prop == "LogDenied":
            if value is None:
                value = config.FALLBACK_LOG_DENIED
            return dbus.String(value)
        elif prop == "AutomaticHelpers":
            if value is None:
                value = config.FALLBACK_AUTOMATIC_HELPERS
            return dbus.String(value)
        elif prop == "FirewallBackend":
            if value is None:
                value = config.FALLBACK_FIREWALL_BACKEND
            return dbus.String(value)
        elif prop == "FlushAllOnReload":
            if value is None:
                value = "yes" if config.FALLBACK_FLUSH_ALL_ON_RELOAD else "no"
            return dbus.String(value)
        elif prop == "RFC3964_IPv4":
            if value is None:
                value = "yes" if config.FALLBACK_RFC3964_IPV4 else "no"
            return dbus.String(value)
        elif prop == "AllowZoneDrifting":
            if value is None:
                value = "yes" if config.FALLBACK_ALLOW_ZONE_DRIFTING else "no"
            return dbus.String(value)

    @dbus_handle_exceptions
    def _get_dbus_property(self, prop):
        if prop == "DefaultZone":
            return dbus.String(self._get_property(prop))
        elif prop == "MinimalMark":
            return dbus.Int32(self._get_property(prop))
        elif prop == "CleanupOnExit":
            return dbus.String(self._get_property(prop))
        elif prop == "CleanupModulesOnExit":
            return dbus.String(self._get_property(prop))
        elif prop == "Lockdown":
            return dbus.String(self._get_property(prop))
        elif prop == "IPv6_rpfilter":
            return dbus.String(self._get_property(prop))
        elif prop == "IndividualCalls":
            return dbus.String(self._get_property(prop))
        elif prop == "LogDenied":
            return dbus.String(self._get_property(prop))
        elif prop == "AutomaticHelpers":
            return dbus.String(self._get_property(prop))
        elif prop == "FirewallBackend":
            return dbus.String(self._get_property(prop))
        elif prop == "FlushAllOnReload":
            return dbus.String(self._get_property(prop))
        elif prop == "RFC3964_IPv4":
            return dbus.String(self._get_property(prop))
        elif prop == "AllowZoneDrifting":
            return dbus.String(self._get_property(prop))
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % prop)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ss',
                         out_signature='v')
    @dbus_handle_exceptions
    def Get(self, interface_name, property_name, sender=None): # pylint: disable=W0613
        # get a property
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        log.debug1("config.Get('%s', '%s')", interface_name, property_name)

        if interface_name == config.dbus.DBUS_INTERFACE_CONFIG:
            return self._get_dbus_property(property_name)
        elif interface_name in [ config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                                 config.dbus.DBUS_INTERFACE_CONFIG_POLICIES ]:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % property_name)
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        return self._get_dbus_property(property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='s',
                         out_signature='a{sv}')
    @dbus_handle_exceptions
    def GetAll(self, interface_name, sender=None): # pylint: disable=W0613
        interface_name = dbus_to_python(interface_name, str)
        log.debug1("config.GetAll('%s')", interface_name)

        ret = { }
        if interface_name == config.dbus.DBUS_INTERFACE_CONFIG:
            for x in [ "DefaultZone", "MinimalMark", "CleanupOnExit",
                       "CleanupModulesOnExit", "Lockdown", "IPv6_rpfilter",
                       "IndividualCalls", "LogDenied", "AutomaticHelpers",
                       "FirewallBackend", "FlushAllOnReload", "RFC3964_IPv4",
                       "AllowZoneDrifting" ]:
                ret[x] = self._get_property(x)
        elif interface_name in [ config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                                 config.dbus.DBUS_INTERFACE_CONFIG_POLICIES ]:
            pass
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        return dbus.Dictionary(ret, signature="sv")

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ssv')
    @dbus_handle_exceptions
    def Set(self, interface_name, property_name, new_value, sender=None):
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        new_value = dbus_to_python(new_value)
        log.debug1("config.Set('%s', '%s', '%s')", interface_name,
                   property_name, new_value)
        self.accessCheck(sender)

        if interface_name == config.dbus.DBUS_INTERFACE_CONFIG:
            if property_name in [ "CleanupOnExit", "Lockdown", "CleanupModulesOnExit",
                                  "IPv6_rpfilter", "IndividualCalls",
                                  "LogDenied",
                                  "FirewallBackend", "FlushAllOnReload",
                                  "RFC3964_IPv4", "AllowZoneDrifting" ]:
                if property_name in [ "CleanupOnExit", "Lockdown", "CleanupModulesOnExit",
                                      "IPv6_rpfilter", "IndividualCalls" ]:
                    if new_value.lower() not in [ "yes", "no",
                                                  "true", "false" ]:
                        raise FirewallError(errors.INVALID_VALUE,
                                            "'%s' for %s" % \
                                            (new_value, property_name))
                if property_name == "LogDenied":
                    if new_value not in config.LOG_DENIED_VALUES:
                        raise FirewallError(errors.INVALID_VALUE,
                                            "'%s' for %s" % \
                                            (new_value, property_name))
                if property_name == "FirewallBackend":
                    if new_value not in config.FIREWALL_BACKEND_VALUES:
                        raise FirewallError(errors.INVALID_VALUE,
                                            "'%s' for %s" % \
                                            (new_value, property_name))
                if property_name == "FlushAllOnReload":
                    if new_value.lower() not in ["yes", "true", "no", "false"]:
                        raise FirewallError(errors.INVALID_VALUE,
                                            "'%s' for %s" % \
                                            (new_value, property_name))
                if property_name == "RFC3964_IPv4":
                    if new_value.lower() not in ["yes", "true", "no", "false"]:
                        raise FirewallError(errors.INVALID_VALUE,
                                            "'%s' for %s" % \
                                            (new_value, property_name))
                if property_name == "AllowZoneDrifting":
                    if new_value.lower() not in ["yes", "true", "no", "false"]:
                        raise FirewallError(errors.INVALID_VALUE,
                                            "'%s' for %s" % \
                                            (new_value, property_name))

                self.config.get_firewalld_conf().set(property_name, new_value)
                self.config.get_firewalld_conf().write()
                self.PropertiesChanged(interface_name,
                                       { property_name: new_value }, [ ])
            elif property_name in ["MinimalMark", "AutomaticHelpers"]:
                # deprecated fields. Ignore setting them.
                pass
            else:
                raise dbus.exceptions.DBusException(
                    "org.freedesktop.DBus.Error.InvalidArgs: "
                    "Property '%s' does not exist" % property_name)
        elif interface_name in [ config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                                 config.dbus.DBUS_INTERFACE_CONFIG_POLICIES ]:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % property_name)
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

    @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as')
    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("config.PropertiesChanged('%s', '%s', '%s')",
                   interface_name, changed_properties, invalidated_properties)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(dbus.INTROSPECTABLE_IFACE, out_signature='s')
    @dbus_handle_exceptions
    def Introspect(self, sender=None): # pylint: disable=W0613
        log.debug2("config.Introspect()")

        data = super(FirewallDConfig, self).Introspect(self.path,
                                                       self.busname.get_bus())
        return dbus_introspection_add_properties(
            self, data, config.dbus.DBUS_INTERFACE_CONFIG)

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # policies

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         out_signature=LockdownWhitelist.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def getLockdownWhitelist(self, sender=None): # pylint: disable=W0613
        log.debug1("config.policies.getLockdownWhitelist()")
        return self.config.get_policies().lockdown_whitelist.export_config()

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature=LockdownWhitelist.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def setLockdownWhitelist(self, settings, sender=None): # pylint: disable=W0613
        log.debug1("config.policies.setLockdownWhitelist(...)")
        settings = dbus_to_python(settings)
        self.config.get_policies().lockdown_whitelist.import_config(settings)
        self.config.get_policies().lockdown_whitelist.write()
        self.LockdownWhitelistUpdated()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES)
    @dbus_handle_exceptions
    def LockdownWhitelistUpdated(self):
        log.debug1("config.policies.LockdownWhitelistUpdated()")

    # command

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='s')
    @dbus_handle_exceptions
    def addLockdownWhitelistCommand(self, command, sender=None):
        command = dbus_to_python(command)
        log.debug1("config.policies.addLockdownWhitelistCommand('%s')", command)
        self.accessCheck(sender)
        settings = list(self.getLockdownWhitelist())
        if command in settings[0]:
            raise FirewallError(errors.ALREADY_ENABLED, command)
        settings[0].append(command)
        self.setLockdownWhitelist(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeLockdownWhitelistCommand(self, command, sender=None):
        command = dbus_to_python(command)
        log.debug1("config.policies.removeLockdownWhitelistCommand('%s')",
                   command)
        self.accessCheck(sender)
        settings = list(self.getLockdownWhitelist())
        if command not in settings[0]:
            raise FirewallError(errors.NOT_ENABLED, command)
        settings[0].remove(command)
        self.setLockdownWhitelist(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    def queryLockdownWhitelistCommand(self, command, sender=None): # pylint: disable=W0613
        command = dbus_to_python(command)
        log.debug1("config.policies.queryLockdownWhitelistCommand('%s')",
                   command)
        return command in self.getLockdownWhitelist()[0]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         out_signature='as')
    @dbus_handle_exceptions
    def getLockdownWhitelistCommands(self, sender=None): # pylint: disable=W0613
        log.debug1("config.policies.getLockdownWhitelistCommands()")
        return self.getLockdownWhitelist()[0]

    # context

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='s')
    @dbus_handle_exceptions
    def addLockdownWhitelistContext(self, context, sender=None):
        context = dbus_to_python(context)
        log.debug1("config.policies.addLockdownWhitelistContext('%s')", context)
        self.accessCheck(sender)
        settings = list(self.getLockdownWhitelist())
        if context in settings[1]:
            raise FirewallError(errors.ALREADY_ENABLED, context)
        settings[1].append(context)
        self.setLockdownWhitelist(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeLockdownWhitelistContext(self, context, sender=None):
        context = dbus_to_python(context)
        log.debug1("config.policies.removeLockdownWhitelistContext('%s')",
                   context)
        self.accessCheck(sender)
        settings = list(self.getLockdownWhitelist())
        if context not in settings[1]:
            raise FirewallError(errors.NOT_ENABLED, context)
        settings[1].remove(context)
        self.setLockdownWhitelist(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    def queryLockdownWhitelistContext(self, context, sender=None): # pylint: disable=W0613
        context = dbus_to_python(context)
        log.debug1("config.policies.queryLockdownWhitelistContext('%s')",
                   context)
        return context in self.getLockdownWhitelist()[1]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         out_signature='as')
    @dbus_handle_exceptions
    def getLockdownWhitelistContexts(self, sender=None): # pylint: disable=W0613
        log.debug1("config.policies.getLockdownWhitelistContexts()")
        return self.getLockdownWhitelist()[1]

    # user

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='s')
    @dbus_handle_exceptions
    def addLockdownWhitelistUser(self, user, sender=None):
        user = dbus_to_python(user)
        log.debug1("config.policies.addLockdownWhitelistUser('%s')", user)
        self.accessCheck(sender)
        settings = list(self.getLockdownWhitelist())
        if user in settings[2]:
            raise FirewallError(errors.ALREADY_ENABLED, user)
        settings[2].append(user)
        self.setLockdownWhitelist(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeLockdownWhitelistUser(self, user, sender=None):
        user = dbus_to_python(user)
        log.debug1("config.policies.removeLockdownWhitelistUser('%s')", user)
        self.accessCheck(sender)
        settings = list(self.getLockdownWhitelist())
        if user not in settings[2]:
            raise FirewallError(errors.NOT_ENABLED, user)
        settings[2].remove(user)
        self.setLockdownWhitelist(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    def queryLockdownWhitelistUser(self, user, sender=None): # pylint: disable=W0613
        user = dbus_to_python(user)
        log.debug1("config.policies.queryLockdownWhitelistUser('%s')", user)
        return user in self.getLockdownWhitelist()[2]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         out_signature='as')
    @dbus_handle_exceptions
    def getLockdownWhitelistUsers(self, sender=None): # pylint: disable=W0613
        log.debug1("config.policies.getLockdownWhitelistUsers()")
        return self.getLockdownWhitelist()[2]

    # uid

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='i')
    @dbus_handle_exceptions
    def addLockdownWhitelistUid(self, uid, sender=None):
        uid = dbus_to_python(uid)
        log.debug1("config.policies.addLockdownWhitelistUid(%d)", uid)
        self.accessCheck(sender)
        settings = list(self.getLockdownWhitelist())
        if uid in settings[3]:
            raise FirewallError(errors.ALREADY_ENABLED, uid)
        settings[3].append(uid)
        self.setLockdownWhitelist(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='i')
    @dbus_handle_exceptions
    def removeLockdownWhitelistUid(self, uid, sender=None):
        uid = dbus_to_python(uid)
        log.debug1("config.policies.removeLockdownWhitelistUid(%d)", uid)
        self.accessCheck(sender)
        settings = list(self.getLockdownWhitelist())
        if uid not in settings[3]:
            raise FirewallError(errors.NOT_ENABLED, uid)
        settings[3].remove(uid)
        self.setLockdownWhitelist(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         in_signature='i', out_signature='b')
    @dbus_handle_exceptions
    def queryLockdownWhitelistUid(self, uid, sender=None): # pylint: disable=W0613
        uid = dbus_to_python(uid)
        log.debug1("config.policies.queryLockdownWhitelistUid(%d)", uid)
        return uid in self.getLockdownWhitelist()[3]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_POLICIES,
                         out_signature='ai')
    @dbus_handle_exceptions
    def getLockdownWhitelistUids(self, sender=None): # pylint: disable=W0613
        log.debug1("config.policies.getLockdownWhitelistUids()")
        return self.getLockdownWhitelist()[3]

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # I P S E T S

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='ao')
    @dbus_handle_exceptions
    def listIPSets(self, sender=None): # pylint: disable=W0613
        """list ipsets objects paths
        """
        log.debug1("config.listIPSets()")
        return self.ipsets

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='as')
    @dbus_handle_exceptions
    def getIPSetNames(self, sender=None): # pylint: disable=W0613
        """get ipset names
        """
        log.debug1("config.getIPSetNames()")
        ipsets = [ ]
        for obj in self.ipsets:
            ipsets.append(obj.obj.name)
        return sorted(ipsets)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, in_signature='s',
                         out_signature='o')
    @dbus_handle_exceptions
    def getIPSetByName(self, ipset, sender=None): # pylint: disable=W0613
        """object path of ipset with given name
        """
        ipset = dbus_to_python(ipset, str)
        log.debug1("config.getIPSetByName('%s')", ipset)
        for obj in self.ipsets:
            if obj.obj.name == ipset:
                return obj
        raise FirewallError(errors.INVALID_IPSET, ipset)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG,
                         in_signature='s'+IPSet.DBUS_SIGNATURE,
                         out_signature='o')
    @dbus_handle_exceptions
    def addIPSet(self, ipset, settings, sender=None):
        """add ipset with given name and settings
        """
        ipset = dbus_to_python(ipset, str)
        settings = dbus_to_python(settings)
        log.debug1("config.addIPSet('%s')", ipset)
        self.accessCheck(sender)
        obj = self.config.new_ipset(ipset, settings)
        config_ipset = self._addIPSet(obj)
        return config_ipset

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG, signature='s')
    @dbus_handle_exceptions
    def IPSetAdded(self, ipset):
        ipset = dbus_to_python(ipset, str)
        log.debug1("config.IPSetAdded('%s')" % (ipset))

    # I C M P T Y P E S

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='ao')
    @dbus_handle_exceptions
    def listIcmpTypes(self, sender=None): # pylint: disable=W0613
        """list icmptypes objects paths
        """
        log.debug1("config.listIcmpTypes()")
        return self.icmptypes

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='as')
    @dbus_handle_exceptions
    def getIcmpTypeNames(self, sender=None): # pylint: disable=W0613
        """get icmptype names
        """
        log.debug1("config.getIcmpTypeNames()")
        icmptypes = [ ]
        for obj in self.icmptypes:
            icmptypes.append(obj.obj.name)
        return sorted(icmptypes)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, in_signature='s',
                         out_signature='o')
    @dbus_handle_exceptions
    def getIcmpTypeByName(self, icmptype, sender=None): # pylint: disable=W0613
        """object path of icmptype with given name
        """
        icmptype = dbus_to_python(icmptype, str)
        log.debug1("config.getIcmpTypeByName('%s')", icmptype)
        for obj in self.icmptypes:
            if obj.obj.name == icmptype:
                return obj
        raise FirewallError(errors.INVALID_ICMPTYPE, icmptype)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG,
                         in_signature='s'+IcmpType.DBUS_SIGNATURE,
                         out_signature='o')
    @dbus_handle_exceptions
    def addIcmpType(self, icmptype, settings, sender=None):
        """add icmptype with given name and settings
        """
        icmptype = dbus_to_python(icmptype, str)
        settings = dbus_to_python(settings)
        log.debug1("config.addIcmpType('%s')", icmptype)
        self.accessCheck(sender)
        obj = self.config.new_icmptype(icmptype, settings)
        config_icmptype = self._addIcmpType(obj)
        return config_icmptype

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG, signature='s')
    @dbus_handle_exceptions
    def IcmpTypeAdded(self, icmptype):
        log.debug1("config.IcmpTypeAdded('%s')" % (icmptype))

    # S E R V I C E S

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='ao')
    @dbus_handle_exceptions
    def listServices(self, sender=None): # pylint: disable=W0613
        """list services objects paths
        """
        log.debug1("config.listServices()")
        return self.services

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='as')
    @dbus_handle_exceptions
    def getServiceNames(self, sender=None): # pylint: disable=W0613
        """get service names
        """
        log.debug1("config.getServiceNames()")
        services = [ ]
        for obj in self.services:
            services.append(obj.obj.name)
        return sorted(services)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, in_signature='s',
                         out_signature='o')
    @dbus_handle_exceptions
    def getServiceByName(self, service, sender=None): # pylint: disable=W0613
        """object path of service with given name
        """
        service = dbus_to_python(service, str)
        log.debug1("config.getServiceByName('%s')", service)
        for obj in self.services:
            if obj.obj.name == service:
                return obj
        raise FirewallError(errors.INVALID_SERVICE, service)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG,
                         in_signature='s(sssa(ss)asa{ss}asa(ss))',
                         out_signature='o')
    @dbus_handle_exceptions
    def addService(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.addService('%s')", service)
        self.accessCheck(sender)
        obj = self.config.new_service(service, settings)
        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):
        log.debug1("config.ServiceAdded('%s')" % (service))

    # Z O N E S

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='ao')
    @dbus_handle_exceptions
    def listZones(self, sender=None): # pylint: disable=W0613
        """list zones objects paths
        """
        log.debug1("config.listZones()")
        return self.zones

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='as')
    @dbus_handle_exceptions
    def getZoneNames(self, sender=None): # pylint: disable=W0613
        """get zone names
        """
        log.debug1("config.getZoneNames()")
        zones = [ ]
        for obj in self.zones:
            zones.append(obj.obj.name)
        return sorted(zones)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, in_signature='s',
                         out_signature='o')
    @dbus_handle_exceptions
    def getZoneByName(self, zone, sender=None): # pylint: disable=W0613
        """object path of zone with given name
        """
        zone = dbus_to_python(zone, str)
        log.debug1("config.getZoneByName('%s')", zone)
        for obj in self.zones:
            if obj.obj.name == zone:
                return obj
        raise FirewallError(errors.INVALID_ZONE, zone)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, in_signature='s',
                         out_signature='s')
    @dbus_handle_exceptions
    def getZoneOfInterface(self, iface, sender=None): # pylint: disable=W0613
        """name of zone the given interface belongs to
        """
        iface = dbus_to_python(iface, str)
        log.debug1("config.getZoneOfInterface('%s')", iface)
        ret = []
        for obj in self.zones:
            if iface in obj.obj.interfaces:
                ret.append(obj.obj.name)
        if len(ret) > 1:
            # Even it shouldn't happen, it's actually possible that
            # the same interface is in several zone XML files
            return " ".join(ret) + \
                "  (ERROR: interface '%s' is in %s zone XML files, can be only in one)" % \
                (iface, len(ret))
        return ret[0] if ret else ""

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, in_signature='s',
                         out_signature='s')
    @dbus_handle_exceptions
    def getZoneOfSource(self, source, sender=None): # pylint: disable=W0613
        """name of zone the given source belongs to
        """
        source = dbus_to_python(source, str)
        log.debug1("config.getZoneOfSource('%s')", source)
        ret = []
        for obj in self.zones:
            if source in obj.obj.sources:
                ret.append(obj.obj.name)
        if len(ret) > 1:
            # Even it shouldn't happen, it's actually possible that
            # the same source is in several zone XML files
            return " ".join(ret) + \
                "  (ERROR: source '%s' is in %s zone XML files, can be only in one)" % \
                (source, len(ret))
        return ret[0] if ret else ""

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG,
                         in_signature="s(sssbsasa(ss)asba(ssss)asasasasa(ss)b)",
                         out_signature='o')
    @dbus_handle_exceptions
    def addZone(self, zone, settings, sender=None):
        """add zone with given name and settings
        """
        zone = dbus_to_python(zone, str)
        settings = dbus_to_python(settings)
        log.debug1("config.addZone('%s')", zone)
        self.accessCheck(sender)
        if settings[4] == "default":
            # convert to list, fix target, convert back to tuple
            _settings = list(settings)
            _settings[4] = DEFAULT_ZONE_TARGET
            settings = tuple(_settings)
        obj = self.config.new_zone(zone, settings)
        config_zone = self._addZone(obj)
        return config_zone

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG,
                         in_signature="sa{sv}",
                         out_signature='o')
    @dbus_handle_exceptions
    def addZone2(self, zone, settings, sender=None):
        """add zone with given name and settings
        """
        zone = dbus_to_python(zone, str)
        settings = dbus_to_python(settings)
        log.debug1("config.addZone('%s')", zone)
        self.accessCheck(sender)
        if "target" in settings and settings["target"] == "default":
            settings["target"] = DEFAULT_ZONE_TARGET
        obj = self.config.new_zone_dict(zone, settings)
        config_zone = self._addZone(obj)
        return config_zone

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG, signature='s')
    @dbus_handle_exceptions
    def ZoneAdded(self, zone):
        log.debug1("config.ZoneAdded('%s')" % (zone))

    # policies

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='ao')
    @dbus_handle_exceptions
    def listPolicies(self, sender=None):
        """list policies objects paths
        """
        log.debug1("config.listPolicies()")
        return self.policy_objects

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='as')
    @dbus_handle_exceptions
    def getPolicyNames(self, sender=None):
        """get policy names
        """
        log.debug1("config.getPolicyNames()")
        policies = [ ]
        for obj in self.policy_objects:
            policies.append(obj.obj.name)
        return sorted(policies)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, in_signature='s',
                         out_signature='o')
    @dbus_handle_exceptions
    def getPolicyByName(self, policy, sender=None):
        """object path of policy with given name
        """
        policy = dbus_to_python(policy, str)
        log.debug1("config.getPolicyByName('%s')", policy)
        for obj in self.policy_objects:
            if obj.obj.name == policy:
                return obj
        raise FirewallError(errors.INVALID_POLICY, policy)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG,
                         in_signature="sa{sv}",
                         out_signature='o')
    @dbus_handle_exceptions
    def addPolicy(self, policy, settings, sender=None):
        """add policy with given name and settings
        """
        policy = dbus_to_python(policy, str)
        settings = dbus_to_python(settings)
        log.debug1("config.addPolicy('%s')", policy)
        self.accessCheck(sender)
        obj = self.config.new_policy_object_dict(policy, settings)
        config_policy = self._addPolicy(obj)
        return config_policy

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG, signature='s')
    @dbus_handle_exceptions
    def PolicyAdded(self, policy):
        log.debug1("config.PolicyAdded('%s')" % (policy))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # H E L P E R S

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='ao')
    @dbus_handle_exceptions
    def listHelpers(self, sender=None): # pylint: disable=W0613
        """list helpers objects paths
        """
        log.debug1("config.listHelpers()")
        return self.helpers

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, out_signature='as')
    @dbus_handle_exceptions
    def getHelperNames(self, sender=None): # pylint: disable=W0613
        """get helper names
        """
        log.debug1("config.getHelperNames()")
        helpers = [ ]
        for obj in self.helpers:
            helpers.append(obj.obj.name)
        return sorted(helpers)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, in_signature='s',
                         out_signature='o')
    @dbus_handle_exceptions
    def getHelperByName(self, helper, sender=None): # pylint: disable=W0613
        """object path of helper with given name
        """
        helper = dbus_to_python(helper, str)
        log.debug1("config.getHelperByName('%s')", helper)
        for obj in self.helpers:
            if obj.obj.name == helper:
                return obj
        raise FirewallError(errors.INVALID_HELPER, helper)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG,
                         in_signature='s'+Helper.DBUS_SIGNATURE,
                         out_signature='o')
    @dbus_handle_exceptions
    def addHelper(self, helper, settings, sender=None):
        """add helper with given name and settings
        """
        helper = dbus_to_python(helper, str)
        settings = dbus_to_python(settings)
        log.debug1("config.addHelper('%s')", helper)
        self.accessCheck(sender)
        obj = self.config.new_helper(helper, settings)
        config_helper = self._addHelper(obj)
        return config_helper

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG, signature='s')
    @dbus_handle_exceptions
    def HelperAdded(self, helper):
        helper = dbus_to_python(helper, str)
        log.debug1("config.HelperAdded('%s')" % (helper))

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # DIRECT

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         out_signature=Direct.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def getSettings(self, sender=None): # pylint: disable=W0613
        # returns list ipv, table, list of chains
        log.debug1("config.direct.getSettings()")
        return self.config.get_direct().export_config()

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature=Direct.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def update(self, settings, sender=None): # pylint: disable=W0613
        # 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()

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT)
    @dbus_handle_exceptions
    def Updated(self):
        log.debug1("config.direct.Updated()")

    # chain

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='sss')
    @dbus_handle_exceptions
    def addChain(self, ipv, table, chain, sender=None):
        ipv = dbus_to_python(ipv)
        table = dbus_to_python(table)
        chain = dbus_to_python(chain)
        log.debug1("config.direct.addChain('%s', '%s', '%s')" % \
                   (ipv, table, chain))
        self.accessCheck(sender)
        idx = tuple((ipv, table, chain))
        settings = list(self.getSettings())
        if idx in settings[0]:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "chain '%s' already is in '%s:%s'" % \
                                (chain, ipv, table))
        settings[0].append(idx)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='sss')
    @dbus_handle_exceptions
    def removeChain(self, ipv, table, chain, sender=None):
        ipv = dbus_to_python(ipv)
        table = dbus_to_python(table)
        chain = dbus_to_python(chain)
        log.debug1("config.direct.removeChain('%s', '%s', '%s')" % \
                   (ipv, table, chain))
        self.accessCheck(sender)
        idx = tuple((ipv, table, chain))
        settings = list(self.getSettings())
        if idx not in settings[0]:
            raise FirewallError(errors.NOT_ENABLED,
                                "chain '%s' is not in '%s:%s'" % (chain, ipv,
                                                                  table))
        settings[0].remove(idx)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='sss', out_signature='b')
    @dbus_handle_exceptions
    def queryChain(self, ipv, table, chain, sender=None): # pylint: disable=W0613
        ipv = dbus_to_python(ipv)
        table = dbus_to_python(table)
        chain = dbus_to_python(chain)
        log.debug1("config.direct.queryChain('%s', '%s', '%s')" % \
                   (ipv, table, chain))
        idx = tuple((ipv, table, chain))
        return idx in self.getSettings()[0]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='ss', out_signature='as')
    @dbus_handle_exceptions
    def getChains(self, ipv, table, sender=None): # pylint: disable=W0613
        ipv = dbus_to_python(ipv)
        table = dbus_to_python(table)
        log.debug1("config.direct.getChains('%s', '%s')" % (ipv, table))
        ret = [ ]
        for idx in self.getSettings()[0]:
            if idx[0] == ipv and idx[1] == table:
                ret.append(idx[2])
        return ret

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='', out_signature='a(sss)')
    @dbus_handle_exceptions
    def getAllChains(self, sender=None): # pylint: disable=W0613
        log.debug1("config.direct.getAllChains()")
        return self.getSettings()[0]

    # rule

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='sssias')
    @dbus_handle_exceptions
    def addRule(self, ipv, table, chain, priority, args, sender=None): # pylint: disable=R0913
        ipv = dbus_to_python(ipv)
        table = dbus_to_python(table)
        chain = dbus_to_python(chain)
        priority = dbus_to_python(priority)
        args = dbus_to_python(args)
        log.debug1("config.direct.addRule('%s', '%s', '%s', %d, '%s')" % \
                   (ipv, table, chain, priority, "','".join(args)))
        self.accessCheck(sender)
        idx = (ipv, table, chain, priority, args)
        settings = list(self.getSettings())
        if idx in settings[1]:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "rule '%s' already is in '%s:%s:%s'" % \
                                (args, ipv, table, chain))
        settings[1].append(idx)
        self.update(tuple(settings))

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='sssias')
    @dbus_handle_exceptions
    def removeRule(self, ipv, table, chain, priority, args, sender=None): # pylint: disable=R0913
        ipv = dbus_to_python(ipv)
        table = dbus_to_python(table)
        chain = dbus_to_python(chain)
        priority = dbus_to_python(priority)
        args = dbus_to_python(args)
        log.debug1("config.direct.removeRule('%s', '%s', '%s', %d, '%s')" % \
                   (ipv, table, chain, priority, "','".join(args)))
        self.accessCheck(sender)
        idx = (ipv, table, chain, priority, args)
        settings = list(self.getSettings())
        if idx not in settings[1]:
            raise FirewallError(errors.NOT_ENABLED,
                                "rule '%s' is not in '%s:%s:%s'" % \
                                (args, ipv, table, chain))
        settings[1].remove(idx)
        self.update(tuple(settings))

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='sssias', out_signature='b')
    @dbus_handle_exceptions
    def queryRule(self, ipv, table, chain, priority, args, sender=None): # pylint: disable=W0613,R0913
        ipv = dbus_to_python(ipv)
        table = dbus_to_python(table)
        chain = dbus_to_python(chain)
        priority = dbus_to_python(priority)
        args = dbus_to_python(args)
        log.debug1("config.direct.queryRule('%s', '%s', '%s', %d, '%s')" % \
                   (ipv, table, chain, priority, "','".join(args)))
        idx = (ipv, table, chain, priority, args)
        return idx in self.getSettings()[1]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='sss')
    @dbus_handle_exceptions
    def removeRules(self, ipv, table, chain, sender=None):
        ipv = dbus_to_python(ipv)
        table = dbus_to_python(table)
        chain = dbus_to_python(chain)
        log.debug1("config.direct.removeRules('%s', '%s', '%s')" % \
                   (ipv, table, chain, ))
        self.accessCheck(sender)
        settings = list(self.getSettings())
        for rule in settings[1][:]:
            if (ipv, table, chain) == (rule[0], rule[1], rule[2]):
                settings[1].remove(rule)
        self.update(tuple(settings))

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='sss', out_signature='a(ias)')
    @dbus_handle_exceptions
    def getRules(self, ipv, table, chain, sender=None): # pylint: disable=W0613
        ipv = dbus_to_python(ipv)
        table = dbus_to_python(table)
        chain = dbus_to_python(chain)
        log.debug1("config.direct.getRules('%s', '%s', '%s')" % \
                   (ipv, table, chain))
        ret = [ ]
        for idx in self.getSettings()[1]:
            if idx[0] == ipv and idx[1] == table and idx[2] == chain:
                ret.append((idx[3], idx[4]))
        return ret

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='', out_signature='a(sssias)')
    @dbus_handle_exceptions
    def getAllRules(self, sender=None): # pylint: disable=W0613
        log.debug1("config.direct.getAllRules()")
        return self.getSettings()[1]

    # passthrough

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='sas')
    @dbus_handle_exceptions
    def addPassthrough(self, ipv, args, sender=None):
        ipv = dbus_to_python(ipv)
        args = dbus_to_python(args)
        log.debug1("config.direct.addPassthrough('%s', '%s')" % \
                   (ipv, "','".join(args)))
        self.accessCheck(sender)
        idx = (ipv, args)
        settings = list(self.getSettings())
        if idx in settings[2]:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "passthrough '%s', '%s'" % (ipv, args))
        settings[2].append(idx)
        self.update(settings)


    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='sas')
    @dbus_handle_exceptions
    def removePassthrough(self, ipv, args, sender=None):
        ipv = dbus_to_python(ipv)
        args = dbus_to_python(args)
        log.debug1("config.direct.removePassthrough('%s', '%s')" % \
                   (ipv, "','".join(args)))
        self.accessCheck(sender)
        idx = (ipv, args)
        settings = list(self.getSettings())
        if idx not in settings[2]:
            raise FirewallError(errors.NOT_ENABLED,
                                "passthrough '%s', '%s'" % (ipv, args))
        settings[2].remove(idx)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='sas', out_signature='b')
    @dbus_handle_exceptions
    def queryPassthrough(self, ipv, args, sender=None): # pylint: disable=W0613
        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]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         in_signature='s', out_signature='aas')
    @dbus_handle_exceptions
    def getPassthroughs(self, ipv, sender=None): # pylint: disable=W0613
        ipv = dbus_to_python(ipv)
        log.debug1("config.direct.getPassthroughs('%s')" % (ipv))
        ret = [ ]
        for idx in self.getSettings()[2]:
            if idx[0] == ipv:
                ret.append(idx[1])
        return ret

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
                         out_signature='a(sas)')
    @dbus_handle_exceptions
    def getAllPassthroughs(self, sender=None): # pylint: disable=W0613
        log.debug1("config.direct.getAllPassthroughs()")
        return self.getSettings()[2]
server/config_icmptype.py000064400000035123150351351720011611 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.

# force use of pygobject3 in python-slip
from gi.repository import GObject
import sys
sys.modules['gobject'] = GObject

import dbus
import dbus.service
import slip.dbus
import slip.dbus.service

from firewall import config
from firewall.dbus_utils import dbus_to_python, \
    dbus_introspection_prepare_properties, \
    dbus_introspection_add_properties
from firewall.core.io.icmptype import IcmpType
from firewall.core.logger import log
from firewall.server.decorators import handle_exceptions, \
    dbus_handle_exceptions, dbus_service_method
from firewall import errors
from firewall.errors import FirewallError

############################################################################
#
# class FirewallDConfigIcmpType
#
############################################################################

class FirewallDConfigIcmpType(slip.dbus.service.Object):
    """FirewallD main class"""

    persistent = True
    """ Make FirewallD persistent. """
    default_polkit_auth_required = config.dbus.PK_ACTION_CONFIG
    """ Use PK_ACTION_INFO as a default """

    @handle_exceptions
    def __init__(self, parent, conf, icmptype, item_id, *args, **kwargs):
        super(FirewallDConfigIcmpType, self).__init__(*args, **kwargs)
        self.parent = parent
        self.config = conf
        self.obj = icmptype
        self.item_id = item_id
        self.busname = args[0]
        self.path = args[1]
        self._log_prefix = "config.icmptype.%d" % self.item_id
        dbus_introspection_prepare_properties(
            self, config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE)

    @dbus_handle_exceptions
    def __del__(self):
        pass

    @dbus_handle_exceptions
    def unregister(self):
        self.remove_from_connection()

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # P R O P E R T I E S

    @dbus_handle_exceptions
    def _get_property(self, property_name):
        if property_name == "name":
            return dbus.String(self.obj.name)
        elif property_name == "filename":
            return dbus.String(self.obj.filename)
        elif property_name == "path":
            return dbus.String(self.obj.path)
        elif property_name == "default":
            return dbus.Boolean(self.obj.default)
        elif property_name == "builtin":
            return dbus.Boolean(self.obj.builtin)
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ss',
                         out_signature='v')
    @dbus_handle_exceptions
    def Get(self, interface_name, property_name, sender=None): # pylint: disable=W0613
        # get a property
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        log.debug1("%s.Get('%s', '%s')", self._log_prefix,
                   interface_name, property_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        return self._get_property(property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='s',
                         out_signature='a{sv}')
    @dbus_handle_exceptions
    def GetAll(self, interface_name, sender=None): # pylint: disable=W0613
        interface_name = dbus_to_python(interface_name, str)
        log.debug1("%s.GetAll('%s')", self._log_prefix, interface_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        ret = { }
        for x in [ "name", "filename", "path", "default", "builtin" ]:
            ret[x] = self._get_property(x)
        return dbus.Dictionary(ret, signature="sv")

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ssv')
    @dbus_handle_exceptions
    def Set(self, interface_name, property_name, new_value, sender=None):
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        new_value = dbus_to_python(new_value)
        log.debug1("%s.Set('%s', '%s', '%s')", self._log_prefix,
                   interface_name, property_name, new_value)
        self.parent.accessCheck(sender)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        raise dbus.exceptions.DBusException(
            "org.freedesktop.DBus.Error.PropertyReadOnly: "
            "Property '%s' is read-only" % property_name)

    @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as')
    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)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(dbus.INTROSPECTABLE_IFACE, out_signature='s')
    @dbus_handle_exceptions
    def Introspect(self, sender=None): # pylint: disable=W0613
        log.debug2("%s.Introspect()", self._log_prefix)

        data = super(FirewallDConfigIcmpType, self).Introspect(
            self.path, self.busname.get_bus())

        return dbus_introspection_add_properties(
            self, data, config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE)

    # S E T T I N G S

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         out_signature=IcmpType.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def getSettings(self, sender=None): # pylint: disable=W0613
        """get settings for icmptype
        """
        log.debug1("%s.getSettings()", self._log_prefix)
        return self.config.get_icmptype_config(self.obj)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         in_signature=IcmpType.DBUS_SIGNATURE)
    @dbus_handle_exceptions
    def update(self, settings, sender=None):
        """update settings for icmptype
        """
        settings = dbus_to_python(settings)
        log.debug1("%s.update('...')", self._log_prefix)
        self.parent.accessCheck(sender)
        self.obj = self.config.set_icmptype_config(self.obj, settings)
        self.Updated(self.obj.name)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE)
    @dbus_handle_exceptions
    def loadDefaults(self, sender=None):
        """load default settings for builtin icmptype
        """
        log.debug1("%s.loadDefaults()", self._log_prefix)
        self.parent.accessCheck(sender)
        self.obj = self.config.load_icmptype_defaults(self.obj)
        self.Updated(self.obj.name)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         signature='s')
    @dbus_handle_exceptions
    def Updated(self, name):
        log.debug1("%s.Updated('%s')" % (self._log_prefix, name))

    # R E M O V E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE)
    @dbus_handle_exceptions
    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)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         signature='s')
    @dbus_handle_exceptions
    def Removed(self, name):
        log.debug1("%s.Removed('%s')" % (self._log_prefix, name))

    # R E N A M E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         in_signature='s')
    @dbus_handle_exceptions
    def rename(self, name, sender=None):
        """rename icmptype
        """
        name = dbus_to_python(name, str)
        log.debug1("%s.rename('%s')", self._log_prefix, name)
        self.parent.accessCheck(sender)
        self.obj = self.config.rename_icmptype(self.obj, name)
        self.Renamed(name)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         signature='s')
    @dbus_handle_exceptions
    def Renamed(self, name):
        log.debug1("%s.Renamed('%s')" % (self._log_prefix, name))

    # version

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         out_signature='s')
    @dbus_handle_exceptions
    def getVersion(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getVersion()", self._log_prefix)
        return self.getSettings()[0]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # short

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         out_signature='s')
    @dbus_handle_exceptions
    def getShort(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getShort()", self._log_prefix)
        return self.getSettings()[1]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # description

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         out_signature='s')
    @dbus_handle_exceptions
    def getDescription(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getDescription()", self._log_prefix)
        return self.getSettings()[2]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # destination

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         out_signature='as')
    @dbus_handle_exceptions
    def getDestinations(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getDestinations()", self._log_prefix)
        return sorted(self.getSettings()[3])

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         in_signature='as')
    @dbus_handle_exceptions
    def setDestinations(self, destinations, sender=None):
        destinations = dbus_to_python(destinations, list)
        log.debug1("%s.setDestinations('[%s]')", self._log_prefix,
                   ",".join(destinations))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[3] = destinations
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         in_signature='s')
    @dbus_handle_exceptions
    def addDestination(self, destination, sender=None):
        destination = dbus_to_python(destination, str)
        log.debug1("%s.addDestination('%s')", self._log_prefix,
                   destination)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if destination in settings[3]:
            raise FirewallError(errors.ALREADY_ENABLED, destination)
        settings[3].append(destination)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeDestination(self, destination, sender=None):
        destination = dbus_to_python(destination, str)
        log.debug1("%s.removeDestination('%s')", self._log_prefix,
                   destination)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if settings[3]:
            if destination not in settings[3]:
                raise FirewallError(errors.NOT_ENABLED, destination)
            else:
                settings[3].remove(destination)
        else:  # empty means all
            settings[3] = list(set(['ipv4', 'ipv6']) -
                               set([destination]))
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_ICMPTYPE,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    def queryDestination(self, destination, sender=None): # pylint: disable=W0613
        destination = dbus_to_python(destination, str)
        log.debug1("%s.queryDestination('%s')", self._log_prefix,
                   destination)
        settings = self.getSettings()
        # empty means all
        return (not settings[3] or
                destination in settings[3])
server/decorators.py000064400000005557150351351720010607 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2012-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.

"""This module contains decorators for use with and without D-Bus"""

__all__ = ["FirewallDBusException", "handle_exceptions",
           "dbus_handle_exceptions", "dbus_service_method"]

import dbus
import dbus.service
import traceback
from dbus.exceptions import DBusException
from decorator import decorator

from firewall import config
from firewall.errors import FirewallError
from firewall import errors
from firewall.core.logger import log

############################################################################
#
# Exception handler decorators
#
############################################################################

class FirewallDBusException(dbus.DBusException):
    """FirewallDBusException"""
    _dbus_error_name = "%s.Exception" % config.dbus.DBUS_INTERFACE

@decorator
def handle_exceptions(func, *args, **kwargs):
    """Decorator to handle exceptions and log them. Used if not conneced
    to D-Bus.
    """
    try:
        return func(*args, **kwargs)
    except FirewallError as error:
        log.debug1(traceback.format_exc())
        log.error(error)
    except Exception:  # pylint: disable=W0703
        log.exception()

@decorator
def dbus_handle_exceptions(func, *args, **kwargs):
    """Decorator to handle exceptions, log and report them into D-Bus

    :Raises DBusException: on a firewall error code problems.
    """
    try:
        return func(*args, **kwargs)
    except FirewallError as error:
        code = FirewallError.get_code(str(error))
        if code in [ errors.ALREADY_ENABLED, errors.NOT_ENABLED,
                     errors.ZONE_ALREADY_SET, errors.ALREADY_SET ]:
            log.warning(str(error))
        else:
            log.debug1(traceback.format_exc())
            log.error(str(error))
        raise FirewallDBusException(str(error))
    except DBusException as ex:
        # only log DBusExceptions once
        raise ex
    except Exception as ex:
        log.exception()
        raise FirewallDBusException(str(ex))

def dbus_service_method(*args, **kwargs):
    """Add sender argument for D-Bus"""
    kwargs.setdefault("sender_keyword", "sender")
    return dbus.service.method(*args, **kwargs)
server/server.py000064400000007371150351351720007744 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#
# signal handling and run_server derived from setroubleshoot
# Copyright (C) 2006,2007,2008,2009 Red Hat, Inc.
# Authors:
#   John Dennis <jdennis@redhat.com>
#   Thomas Liu  <tliu@redhat.com>
#   Dan Walsh <dwalsh@redhat.com>

__all__ = [ "run_server" ]

import sys
import signal

# force use of pygobject3 in python-slip
from gi.repository import GObject, GLib
sys.modules['gobject'] = GObject

import dbus
import dbus.service
import dbus.mainloop.glib
import slip.dbus

from firewall import config
from firewall.core.logger import log
from firewall.server.firewalld import FirewallD

############################################################################
#
# signal handlers
#
############################################################################

def sighup(service):
    service.reload()
    return True

def sigterm(mainloop):
    mainloop.quit()

############################################################################
#
# run_server function
#
############################################################################

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")
            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:
            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:
        log.debug1("Stopping..")

    except SystemExit:
        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()
server/config_service.py000064400000072677150351351720011436 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.

# force use of pygobject3 in python-slip
from gi.repository import GObject
import sys
sys.modules['gobject'] = GObject

import dbus
import dbus.service
import slip.dbus
import slip.dbus.service

from firewall import config
from firewall.dbus_utils import dbus_to_python, \
    dbus_introspection_prepare_properties, \
    dbus_introspection_add_properties
from firewall.core.logger import log
from firewall.server.decorators import handle_exceptions, \
    dbus_handle_exceptions, dbus_service_method
from firewall import errors
from firewall.errors import FirewallError

############################################################################
#
# class FirewallDConfig
#
############################################################################

class FirewallDConfigService(slip.dbus.service.Object):
    """FirewallD main class"""

    persistent = True
    """ Make FirewallD persistent. """
    default_polkit_auth_required = config.dbus.PK_ACTION_CONFIG
    """ Use PK_ACTION_INFO as a default """

    @handle_exceptions
    def __init__(self, parent, conf, service, item_id, *args, **kwargs):
        super(FirewallDConfigService, self).__init__(*args, **kwargs)
        self.parent = parent
        self.config = conf
        self.obj = service
        self.item_id = item_id
        self.busname = args[0]
        self.path = args[1]
        self._log_prefix = "config.service.%d" % self.item_id
        dbus_introspection_prepare_properties(
            self, config.dbus.DBUS_INTERFACE_CONFIG_SERVICE)

    @dbus_handle_exceptions
    def __del__(self):
        pass

    @dbus_handle_exceptions
    def unregister(self):
        self.remove_from_connection()

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    # P R O P E R T I E S

    @dbus_handle_exceptions
    def _get_property(self, property_name):
        if property_name == "name":
            return dbus.String(self.obj.name)
        elif property_name == "filename":
            return dbus.String(self.obj.filename)
        elif property_name == "path":
            return dbus.String(self.obj.path)
        elif property_name == "default":
            return dbus.Boolean(self.obj.default)
        elif property_name == "builtin":
            return dbus.Boolean(self.obj.builtin)
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.InvalidArgs: "
                "Property '%s' does not exist" % property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ss',
                         out_signature='v')
    @dbus_handle_exceptions
    def Get(self, interface_name, property_name, sender=None): # pylint: disable=W0613
        # get a property
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        log.debug1("%s.Get('%s', '%s')", self._log_prefix,
                   interface_name, property_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_SERVICE:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        return self._get_property(property_name)

    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='s',
                         out_signature='a{sv}')
    @dbus_handle_exceptions
    def GetAll(self, interface_name, sender=None): # pylint: disable=W0613
        interface_name = dbus_to_python(interface_name, str)
        log.debug1("%s.GetAll('%s')", self._log_prefix, interface_name)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_SERVICE:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        ret = { }
        for x in [ "name", "filename", "path", "default", "builtin" ]:
            ret[x] = self._get_property(x)
        return dbus.Dictionary(ret, signature="sv")

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
    @dbus_service_method(dbus.PROPERTIES_IFACE, in_signature='ssv')
    @dbus_handle_exceptions
    def Set(self, interface_name, property_name, new_value, sender=None):
        interface_name = dbus_to_python(interface_name, str)
        property_name = dbus_to_python(property_name, str)
        new_value = dbus_to_python(new_value)
        log.debug1("%s.Set('%s', '%s', '%s')", self._log_prefix,
                   interface_name, property_name, new_value)
        self.parent.accessCheck(sender)

        if interface_name != config.dbus.DBUS_INTERFACE_CONFIG_SERVICE:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "Interface '%s' does not exist" % interface_name)

        raise dbus.exceptions.DBusException(
            "org.freedesktop.DBus.Error.PropertyReadOnly: "
            "Property '%s' is read-only" % property_name)

    @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as')
    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)

    @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO)
    @dbus_service_method(dbus.INTROSPECTABLE_IFACE, out_signature='s')
    @dbus_handle_exceptions
    def Introspect(self, sender=None): # pylint: disable=W0613
        log.debug2("%s.Introspect()", self._log_prefix)

        data = super(FirewallDConfigService, self).Introspect(
            self.path, self.busname.get_bus())

        return dbus_introspection_add_properties(
            self, data, config.dbus.DBUS_INTERFACE_CONFIG_SERVICE)

    # S E T T I N G S

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         out_signature='(sssa(ss)asa{ss}asa(ss))')
    @dbus_handle_exceptions
    def getSettings(self, sender=None): # pylint: disable=W0613
        """get settings for service
        """
        log.debug1("%s.getSettings()", self._log_prefix)
        return self.config.get_service_config(self.obj)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         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
        """
        settings = dbus_to_python(settings)
        log.debug1("%s.update('...')", self._log_prefix)
        self.parent.accessCheck(sender)
        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):
        """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)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         signature='s')
    @dbus_handle_exceptions
    def Updated(self, name):
        log.debug1("%s.Updated('%s')" % (self._log_prefix, name))

    # R E M O V E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE)
    @dbus_handle_exceptions
    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)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         signature='s')
    @dbus_handle_exceptions
    def Removed(self, name):
        log.debug1("%s.Removed('%s')" % (self._log_prefix, name))

    # R E N A M E

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s')
    @dbus_handle_exceptions
    def rename(self, name, sender=None):
        """rename service
        """
        name = dbus_to_python(name, str)
        log.debug1("%s.rename('%s')", self._log_prefix, name)
        self.parent.accessCheck(sender)
        self.obj = self.config.rename_service(self.obj, name)
        self.Renamed(name)

    @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         signature='s')
    @dbus_handle_exceptions
    def Renamed(self, name):
        log.debug1("%s.Renamed('%s')" % (self._log_prefix, name))

    # version

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         out_signature='s')
    @dbus_handle_exceptions
    def getVersion(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getVersion()", self._log_prefix)
        return self.getSettings()[0]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # short

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         out_signature='s')
    @dbus_handle_exceptions
    def getShort(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getShort()", self._log_prefix)
        return self.getSettings()[1]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # description

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         out_signature='s')
    @dbus_handle_exceptions
    def getDescription(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getDescription()", self._log_prefix)
        return self.getSettings()[2]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s')
    @dbus_handle_exceptions
    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)

    # port

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         out_signature='a(ss)')
    @dbus_handle_exceptions
    def getPorts(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getPorts()", self._log_prefix)
        return self.getSettings()[3]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='a(ss)')
    @dbus_handle_exceptions
    def setPorts(self, ports, sender=None):
        _ports = [ ]
        # convert embedded lists to tuples
        for port in dbus_to_python(ports, list):
            if isinstance(port, list):
                _ports.append(tuple(port))
            else:
                _ports.append(port)
        ports = _ports
        log.debug1("%s.setPorts('[%s]')", self._log_prefix,
                   ",".join("('%s, '%s')" % (port[0], port[1]) for port in ports))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[3] = ports
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='ss')
    @dbus_handle_exceptions
    def addPort(self, port, protocol, sender=None):
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.addPort('%s', '%s')", self._log_prefix, port,
                   protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if (port,protocol) in settings[3]:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "%s:%s" % (port, protocol))
        settings[3].append((port,protocol))
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='ss')
    @dbus_handle_exceptions
    def removePort(self, port, protocol, sender=None):
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.removePort('%s', '%s')", self._log_prefix, port,
                   protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if (port,protocol) not in settings[3]:
            raise FirewallError(errors.NOT_ENABLED, "%s:%s" % (port, protocol))
        settings[3].remove((port,protocol))
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='ss', out_signature='b')
    @dbus_handle_exceptions
    def queryPort(self, port, protocol, sender=None): # pylint: disable=W0613
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.queryPort('%s', '%s')", self._log_prefix, port,
                   protocol)
        return (port,protocol) in self.getSettings()[3]

    # protocol

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         out_signature='as')
    @dbus_handle_exceptions
    def getProtocols(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getProtocols()", self._log_prefix)
        return self.getSettings()[6]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='as')
    @dbus_handle_exceptions
    def setProtocols(self, protocols, sender=None):
        protocols = dbus_to_python(protocols, list)
        log.debug1("%s.setProtocols('[%s]')", self._log_prefix,
                   ",".join(protocols))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[6] = protocols
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s')
    @dbus_handle_exceptions
    def addProtocol(self, protocol, sender=None):
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.addProtocol('%s')", self._log_prefix, protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if protocol in settings[6]:
            raise FirewallError(errors.ALREADY_ENABLED, protocol)
        settings[6].append(protocol)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeProtocol(self, protocol, sender=None):
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.removeProtocol('%s')", self._log_prefix, protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if protocol not in settings[6]:
            raise FirewallError(errors.NOT_ENABLED, protocol)
        settings[6].remove(protocol)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    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()[6]

    # source port

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         out_signature='a(ss)')
    @dbus_handle_exceptions
    def getSourcePorts(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getSourcePorts()", self._log_prefix)
        return self.getSettings()[7]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='a(ss)')
    @dbus_handle_exceptions
    def setSourcePorts(self, ports, sender=None):
        _ports = [ ]
        # convert embedded lists to tuples
        for port in dbus_to_python(ports, list):
            if isinstance(port, list):
                _ports.append(tuple(port))
            else:
                _ports.append(port)
        ports = _ports
        log.debug1("%s.setSourcePorts('[%s]')", self._log_prefix,
                   ",".join("('%s, '%s')" % (port[0], port[1]) for port in ports))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[7] = ports
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='ss')
    @dbus_handle_exceptions
    def addSourcePort(self, port, protocol, sender=None):
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.addSourcePort('%s', '%s')", self._log_prefix, port,
                   protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if (port,protocol) in settings[7]:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "%s:%s" % (port, protocol))
        settings[7].append((port,protocol))
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='ss')
    @dbus_handle_exceptions
    def removeSourcePort(self, port, protocol, sender=None):
        port = dbus_to_python(port, str)
        protocol = dbus_to_python(protocol, str)
        log.debug1("%s.removeSourcePort('%s', '%s')", self._log_prefix, port,
                   protocol)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if (port,protocol) not in settings[7]:
            raise FirewallError(errors.NOT_ENABLED, "%s:%s" % (port, protocol))
        settings[7].remove((port,protocol))
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='ss', out_signature='b')
    @dbus_handle_exceptions
    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()[7]

    # module

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         out_signature='as')
    @dbus_handle_exceptions
    def getModules(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getModules()", self._log_prefix)
        return self.getSettings()[4]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='as')
    @dbus_handle_exceptions
    def setModules(self, modules, sender=None):
        modules = dbus_to_python(modules, list)
        _modules = [ ]
        for module in modules:
            if module.startswith("nf_conntrack_"):
                module = module.replace("nf_conntrack_", "")
                if "_" in module:
                    module = module.replace("_", "-")
            _modules.append(module)
        modules = _modules
        log.debug1("%s.setModules('[%s]')", self._log_prefix,
                   ",".join(modules))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[4] = modules
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s')
    @dbus_handle_exceptions
    def addModule(self, module, sender=None):
        module = dbus_to_python(module, str)
        if module.startswith("nf_conntrack_"):
            module = module.replace("nf_conntrack_", "")
            if "_" in module:
                module = module.replace("_", "-")
        log.debug1("%s.addModule('%s')", self._log_prefix, module)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if module in settings[4]:
            raise FirewallError(errors.ALREADY_ENABLED, module)
        settings[4].append(module)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeModule(self, module, sender=None):
        module = dbus_to_python(module, str)
        if module.startswith("nf_conntrack_"):
            module = module.replace("nf_conntrack_", "")
            if "_" in module:
                module = module.replace("_", "-")
        log.debug1("%s.removeModule('%s')", self._log_prefix, module)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if module not in settings[4]:
            raise FirewallError(errors.NOT_ENABLED, module)
        settings[4].remove(module)
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    def queryModule(self, module, sender=None): # pylint: disable=W0613
        module = dbus_to_python(module, str)
        if module.startswith("nf_conntrack_"):
            module = module.replace("nf_conntrack_", "")
            if "_" in module:
                module = module.replace("_", "-")
        log.debug1("%s.queryModule('%s')", self._log_prefix, module)
        return module in self.getSettings()[4]

    # destination

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         out_signature='a{ss}')
    @dbus_handle_exceptions
    def getDestinations(self, sender=None): # pylint: disable=W0613
        log.debug1("%s.getDestinations()", self._log_prefix)
        return self.getSettings()[5]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='a{ss}')
    @dbus_handle_exceptions
    def setDestinations(self, destinations, sender=None):
        destinations = dbus_to_python(destinations, dict)
        log.debug1("%s.setDestinations({ipv4:'%s', ipv6:'%s'})",
                   self._log_prefix, destinations.get('ipv4'),
                   destinations.get('ipv6'))
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        settings[5] = destinations
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s', out_signature='s')
    @dbus_handle_exceptions
    def getDestination(self, family, sender=None):
        family = dbus_to_python(family, str)
        log.debug1("%s.getDestination('%s')", self._log_prefix,
                   family)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if family not in settings[5]:
            raise FirewallError(errors.NOT_ENABLED, family)
        return settings[5][family]

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='ss')
    @dbus_handle_exceptions
    def setDestination(self, family, address, sender=None):
        family = dbus_to_python(family, str)
        address = dbus_to_python(address, str)
        log.debug1("%s.setDestination('%s', '%s')", self._log_prefix,
                   family, address)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if family in settings[5] and settings[5][family] == address:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s': '%s'" % (family, address))
        settings[5][family] = address
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeDestination(self, family, sender=None):
        family = dbus_to_python(family, str)
        log.debug1("%s.removeDestination('%s')", self._log_prefix,
                   family)
        self.parent.accessCheck(sender)
        settings = list(self.getSettings())
        if family not in settings[5]:
            raise FirewallError(errors.NOT_ENABLED, family)
        del settings[5][family]
        self.update(settings)

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='ss', out_signature='b')
    @dbus_handle_exceptions
    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])

    # includes

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         out_signature='as')
    @dbus_handle_exceptions
    def getIncludes(self, sender=None):
        log.debug1("%s.getIncludes()", self._log_prefix)
        self.parent.accessCheck(sender)
        settings = self.config.get_service_config_dict(self.obj)
        return settings["includes"] if "includes" in settings else []

    @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE,
                         in_signature='as')
    @dbus_handle_exceptions
    def setIncludes(self, includes, sender=None):
        includes = dbus_to_python(includes, list)
        log.debug1("%s.setIncludes('%s')", self._log_prefix, includes)
        self.parent.accessCheck(sender)
        settings = {"includes": includes[:]}
        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,
                         in_signature='s')
    @dbus_handle_exceptions
    def addInclude(self, include, sender=None):
        include = dbus_to_python(include, str)
        log.debug1("%s.addInclude('%s')", self._log_prefix, include)
        self.parent.accessCheck(sender)
        settings = self.config.get_service_config_dict(self.obj)
        settings.setdefault("includes", []).append(include)
        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,
                         in_signature='s')
    @dbus_handle_exceptions
    def removeInclude(self, include, sender=None):
        include = dbus_to_python(include, str)
        log.debug1("%s.removeInclude('%s')", self._log_prefix, include)
        self.parent.accessCheck(sender)
        settings = self.config.get_service_config_dict(self.obj)
        settings["includes"].remove(include)
        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,
                         in_signature='s', out_signature='b')
    @dbus_handle_exceptions
    def queryInclude(self, include, sender=None):
        include = dbus_to_python(include, str)
        log.debug1("%s.queryInclude('%s')", self._log_prefix, include)
        settings = self.config.get_service_config_dict(self.obj)
        return include in settings["includes"] if "includes" in settings else False
functions.py000064400000045447150351351720007146 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2007,2008,2011,2012 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "PY2", "getPortID", "getPortRange", "portStr", "getServiceName",
            "checkIP", "checkIP6", "checkIPnMask", "checkIP6nMask",
            "checkProtocol", "checkInterface", "checkUINT32",
            "firewalld_is_active", "tempFile", "readfile", "writefile",
            "enable_ip_forwarding", "check_port", "check_address",
            "check_single_address", "check_mac", "uniqify", "ppid_of_pid",
            "max_zone_name_len", "checkUser", "checkUid", "checkCommand",
            "checkContext", "joinArgs", "splitArgs",
            "b2u", "u2b", "u2b_if_py2", "max_policy_name_len",
            "stripNonPrintableCharacters"]

import socket
import os
import os.path
import shlex
import pipes
import string
import sys
import tempfile
from firewall.core.logger import log
from firewall.config import FIREWALLD_TEMPDIR, FIREWALLD_PIDFILE

PY2 = sys.version < '3'

NOPRINT_TRANS_TABLE = {
    # Limit to C0 and C1 code points. Building entries for all unicode code
    # points requires too much memory.
    # C0 = [0, 31]
    # C1 = [127, 159]
    #
    i: None for i in range(0, 160) if not (i > 31 and i < 127)
}

def getPortID(port):
    """ Check and Get port id from port string or port id using socket.getservbyname

    @param port port string or port id
    @return Port id if valid, -1 if port can not be found and -2 if port is too big
    """

    if isinstance(port, int):
        _id = port
    else:
        if port:
            port = port.strip()
        try:
            _id = int(port)
        except ValueError:
            try:
                _id = socket.getservbyname(port)
            except socket.error:
                return -1
    if _id > 65535:
        return -2
    return _id

def getPortRange(ports):
    """ Get port range for port range string or single port id

    @param ports an integer or port string or port range string
    @return Array containing start and end port id for a valid range or -1 if port can not be found and -2 if port is too big for integer input or -1 for invalid ranges or None if the range is ambiguous.
    """

    # (port, port)  or [port, port] case
    if isinstance(ports, tuple) or isinstance(ports, list):
        return ports

    # "<port-id>" case
    if isinstance(ports, int) or ports.isdigit():
        id1 = getPortID(ports)
        if id1 >= 0:
            return (id1,)
        return id1

    splits = ports.split("-")

    # "<port-id>-<port-id>" case
    if len(splits) == 2 and splits[0].isdigit() and splits[1].isdigit():
        id1 = getPortID(splits[0])
        id2 = getPortID(splits[1])
        if id1 >= 0 and id2 >= 0:
            if id1 < id2:
                return (id1, id2)
            elif id1 > id2:
                return (id2, id1)
            else: # ids are the same
                return (id1,)

    # everything else "<port-str>[-<port-str>]"
    matched = [ ]
    for i in range(len(splits), 0, -1):
        id1 = getPortID("-".join(splits[:i]))
        port2 = "-".join(splits[i:])
        if len(port2) > 0:
            id2 = getPortID(port2)
            if id1 >= 0 and id2 >= 0:
                if id1 < id2:
                    matched.append((id1, id2))
                elif id1 > id2:
                    matched.append((id2, id1))
                else:
                    matched.append((id1, ))
        else:
            if id1 >= 0:
                matched.append((id1,))
                if i == len(splits):
                    # full match, stop here
                    break
    if len(matched) < 1:
        return -1
    elif len(matched) > 1:
        return None
    return matched[0]

def portStr(port, delimiter=":"):
    """ Create port and port range string

    @param port port or port range int or [int, int]
    @param delimiter of the output string for port ranges, default ':'
    @return Port or port range string, empty string if port isn't specified, None if port or port range is not valid
    """
    if port == "":
        return ""

    _range = getPortRange(port)
    if isinstance(_range, int) and _range < 0:
        return None
    elif len(_range) == 1:
        return "%s" % _range
    else:
        return "%s%s%s" % (_range[0], delimiter, _range[1])

def portInPortRange(port, range):
    _port = getPortRange(port)
    _range = getPortRange(range)

    if len(_port) == 1:
        if len(_range) == 1:
            return getPortID(_port[0]) == getPortID(_range[0])
        if len(_range) == 2 and \
           getPortID(_port[0]) >= getPortID(_range[0]) and getPortID(_port[0]) <= getPortID(_range[1]):
            return True
    elif len(_port) == 2:
        if len(_range) == 2 and \
           getPortID(_port[0]) >= getPortID(_range[0]) and getPortID(_port[0]) <= getPortID(_range[1]) and \
           getPortID(_port[1]) >= getPortID(_range[0]) and getPortID(_port[1]) <= getPortID(_range[1]):
            return True

    return False

def coalescePortRange(new_range, ranges):
    """ Coalesce a port range with existing list of port ranges

        @param new_range tuple/list/string
        @param ranges list of tuple/list/string
        @return tuple of (list of ranges added after coalescing, list of removed original ranges)
    """

    coalesced_range = getPortRange(new_range)
    # normalize singleton ranges, e.g. (x,) --> (x,x)
    if len(coalesced_range) == 1:
        coalesced_range = (coalesced_range[0], coalesced_range[0])
    _ranges = map(getPortRange, ranges)
    _ranges = sorted(map(lambda x: (x[0],x[0]) if len(x) == 1 else x, _ranges), key=lambda x: x[0])

    removed_ranges = []
    for range in _ranges:
        if coalesced_range[0] <= range[0] and coalesced_range[1] >= range[1]:
            # new range covers this
            removed_ranges.append(range)
        elif coalesced_range[0] <= range[0] and coalesced_range[1] <  range[1] and \
                                                coalesced_range[1] >= range[0]:
            # expand beginning of range
            removed_ranges.append(range)
            coalesced_range = (coalesced_range[0], range[1])
        elif coalesced_range[0] >  range[0] and coalesced_range[1] >= range[1] and \
                                                coalesced_range[0] <= range[1]:
            # expand end of range
            removed_ranges.append(range)
            coalesced_range = (range[0], coalesced_range[1])

    # normalize singleton ranges, e.g. (x,x) --> (x,)
    removed_ranges = list(map(lambda x: (x[0],) if x[0] == x[1] else x, removed_ranges))
    if coalesced_range[0] == coalesced_range[1]:
        coalesced_range = (coalesced_range[0],)

    return ([coalesced_range], removed_ranges)

def breakPortRange(remove_range, ranges):
    """ break a port range from existing list of port ranges

        @param remove_range tuple/list/string
        @param ranges list of tuple/list/string
        @return tuple of (list of ranges added after breaking up, list of removed original ranges)
    """

    remove_range = getPortRange(remove_range)
    # normalize singleton ranges, e.g. (x,) --> (x,x)
    if len(remove_range) == 1:
        remove_range = (remove_range[0], remove_range[0])
    _ranges = map(getPortRange, ranges)
    _ranges = sorted(map(lambda x: (x[0],x[0]) if len(x) == 1 else x, _ranges), key=lambda x: x[0])

    removed_ranges = []
    added_ranges = []
    for range in _ranges:
        if remove_range[0] <= range[0] and remove_range[1] >= range[1]:
            # remove entire range
            removed_ranges.append(range)
        elif remove_range[0] <= range[0] and remove_range[1] <  range[1] and \
                                             remove_range[1] >= range[0]:
            # remove from beginning of range
            removed_ranges.append(range)
            added_ranges.append((remove_range[1] + 1, range[1]))
        elif remove_range[0] >  range[0] and remove_range[1] >= range[1] and \
                                             remove_range[0] <= range[1]:
            # remove from end of range
            removed_ranges.append(range)
            added_ranges.append((range[0], remove_range[0] - 1))
        elif remove_range[0] > range[0] and remove_range[1] < range[1]:
            # remove inside range
            removed_ranges.append(range)
            added_ranges.append((range[0], remove_range[0] - 1))
            added_ranges.append((remove_range[1] + 1, range[1]))

    # normalize singleton ranges, e.g. (x,x) --> (x,)
    removed_ranges = list(map(lambda x: (x[0],) if x[0] == x[1] else x, removed_ranges))
    added_ranges = list(map(lambda x: (x[0],) if x[0] == x[1] else x, added_ranges))

    return (added_ranges, removed_ranges)

def getServiceName(port, proto):
    """ Check and Get service name from port and proto string combination using socket.getservbyport

    @param port string or id
    @param protocol string
    @return Service name if port and protocol are valid, else None
    """

    try:
        name = socket.getservbyport(int(port), proto)
    except socket.error:
        return None
    return name

def checkIP(ip):
    """ Check IPv4 address.
    
    @param ip address string
    @return True if address is valid, else False
    """

    try:
        socket.inet_pton(socket.AF_INET, ip)
    except socket.error:
        return False
    return True

def normalizeIP6(ip):
    """ Normalize the IPv6 address

    This is mostly about converting URL-like IPv6 address to normal ones.
    e.g. [1234::4321] --> 1234:4321
    """
    return ip.strip("[]")

def checkIP6(ip):
    """ Check IPv6 address.
    
    @param ip address string
    @return True if address is valid, else False
    """

    try:
        socket.inet_pton(socket.AF_INET6, normalizeIP6(ip))
    except socket.error:
        return False
    return True

def checkIPnMask(ip):
    if "/" in ip:
        addr = ip[:ip.index("/")]
        mask = ip[ip.index("/")+1:]
        if len(addr) < 1 or len(mask) < 1:
            return False
    else:
        addr = ip
        mask = None
    if not checkIP(addr):
        return False
    if mask:
        if "." in mask:
            return checkIP(mask)
        else:
            try:
                i = int(mask)
            except ValueError:
                return False
            if i < 0 or i > 32:
                return False
    return True

def stripNonPrintableCharacters(rule_str):
    return rule_str.translate(NOPRINT_TRANS_TABLE)

def checkIP6nMask(ip):
    if "/" in ip:
        addr = ip[:ip.index("/")]
        mask = ip[ip.index("/")+1:]
        if len(addr) < 1 or len(mask) < 1:
            return False
    else:
        addr = ip
        mask = None
    if not checkIP6(addr):
        return False
    if mask:
        try:
            i = int(mask)
        except ValueError:
            return False
        if i < 0 or i > 128:
            return False

    return True

def checkProtocol(protocol):
    try:
        i = int(protocol)
    except ValueError:
        # string
        try:
            socket.getprotobyname(protocol)
        except socket.error:
            return False
    else:
        if i < 0 or i > 255:
            return False

    return True

def checkInterface(iface):
    """ Check interface string

    @param interface string
    @return True if interface is valid (maximum 16 chars and does not contain ' ', '/', '!', ':', '*'), else False
    """

    if not iface or len(iface) > 16:
        return False
    for ch in [ ' ', '/', '!', '*' ]:
        # !:* are limits for iptables <= 1.4.5
        if ch in iface:
            return False
    # disabled old iptables check
    #if iface == "+":
    #    # limit for iptables <= 1.4.5
    #    return False
    return True

def checkUINT32(val):
    try:
        x = int(val, 0)
    except ValueError:
        return False
    else:
        if x >= 0 and x <= 4294967295:
            return True
    return False

def firewalld_is_active():
    """ Check if firewalld is active

    @return True if there is a firewalld pid file and the pid is used by firewalld
    """

    if not os.path.exists(FIREWALLD_PIDFILE):
        return False

    try:
        with open(FIREWALLD_PIDFILE, "r") as fd:
            pid = fd.readline()
    except Exception:
        return False

    if not os.path.exists("/proc/%s" % pid):
        return False

    try:
        with open("/proc/%s/cmdline" % pid, "r") as fd:
            cmdline = fd.readline()
    except Exception:
        return False

    if "firewalld" in cmdline:
        return True

    return False

def tempFile():
    try:
        if not os.path.exists(FIREWALLD_TEMPDIR):
            os.mkdir(FIREWALLD_TEMPDIR, 0o750)

        return tempfile.NamedTemporaryFile(mode='wt', prefix="temp.",
                                           dir=FIREWALLD_TEMPDIR, delete=False)
    except Exception as msg:
        log.error("Failed to create temporary file: %s" % msg)
        raise
    return None

def readfile(filename):
    try:
        with open(filename, "r") as f:
            return f.readlines()
    except Exception as e:
        log.error('Failed to read file "%s": %s' % (filename, e))
    return None

def writefile(filename, line):
    try:
        with open(filename, "w") as f:
            f.write(line)
    except Exception as e:
        log.error('Failed to write to file "%s": %s' % (filename, e))
        return False
    return True

def enable_ip_forwarding(ipv):
    if ipv == "ipv4":
        return writefile("/proc/sys/net/ipv4/ip_forward", "1\n")
    elif ipv == "ipv6":
        return writefile("/proc/sys/net/ipv6/conf/all/forwarding", "1\n")
    return False

def get_nf_conntrack_short_name(module):
    return module.replace("_","-").replace("nf-conntrack-", "")

def check_port(port):
    _range = getPortRange(port)
    if _range == -2 or _range == -1 or _range is None or \
            (len(_range) == 2 and _range[0] >= _range[1]):
        if _range == -2:
            log.debug2("'%s': port > 65535" % port)
        elif _range == -1:
            log.debug2("'%s': port is invalid" % port)
        elif _range is None:
            log.debug2("'%s': port is ambiguous" % port)
        elif len(_range) == 2 and _range[0] >= _range[1]:
            log.debug2("'%s': range start >= end" % port)
        return False
    return True

def check_address(ipv, source):
    if ipv == "ipv4":
        return checkIPnMask(source)
    elif ipv == "ipv6":
        return checkIP6nMask(source)
    else:
        return False

def check_single_address(ipv, source):
    if ipv == "ipv4":
        return checkIP(source)
    elif ipv == "ipv6":
        return checkIP6(source)
    else:
        return False

def check_mac(mac):
    if len(mac) == 12+5:
        # 0 1 : 3 4 : 6 7 : 9 10 : 12 13 : 15 16
        for i in (2, 5, 8, 11, 14):
            if mac[i] != ":":
                return False
        for i in (0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16):
            if mac[i] not in string.hexdigits:
                return False
        return True
    return False

def uniqify(_list):
    # removes duplicates from list, whilst preserving order
    output = []
    for x in _list:
        if x not in output:
            output.append(x)
    return output

def ppid_of_pid(pid):
    """ Get parent for pid """
    try:
        f = os.popen("ps -o ppid -h -p %d 2>/dev/null" % pid)
        pid = int(f.readlines()[0].strip())
        f.close()
    except Exception:
        return None
    return pid

def max_policy_name_len():
    """
    iptables limits length of chain to (currently) 28 chars.
    The longest chain we create is POST_<policy>_allow,
    which leaves 28 - 11 = 17 chars for <policy>.
    """
    from firewall.core.ipXtables import POLICY_CHAIN_PREFIX
    from firewall.core.base import SHORTCUTS
    longest_shortcut = max(map(len, SHORTCUTS.values()))
    return 28 - (longest_shortcut + len(POLICY_CHAIN_PREFIX) + len("_allow"))

def max_zone_name_len():
    """
    Netfilter limits length of chain to (currently) 28 chars.
    The longest chain we create is FWDI_<zone>_allow,
    which leaves 28 - 11 = 17 chars for <zone>.
    """
    from firewall.core.base import SHORTCUTS
    longest_shortcut = max(map(len, SHORTCUTS.values()))
    return 28 - (longest_shortcut + len("__allow"))

def checkUser(user):
    if len(user) < 1 or len(user) > os.sysconf('SC_LOGIN_NAME_MAX'):
        return False
    for c in user:
        if c not in string.ascii_letters and \
           c not in string.digits and \
           c not in [ ".", "-", "_", "$" ]:
            return False
    return True

def checkUid(uid):
    if isinstance(uid, str):
        try:
            uid = int(uid)
        except ValueError:
            return False
    if uid >= 0 and uid <= 2**31-1:
        return True
    return False

def checkCommand(command):
    if len(command) < 1 or len(command) > 1024:
        return False
    for ch in [ "|", "\n", "\0" ]:
        if ch in command:
            return False
    if command[0] != "/":
        return False
    return True

def checkContext(context):
    splits = context.split(":")
    if len(splits) not in [4, 5]:
        return False
    # user ends with _u if not root
    if splits[0] != "root" and splits[0][-2:] != "_u":
        return False
    # role ends with _r
    if splits[1][-2:] != "_r":
        return False
    # type ends with _t
    if splits[2][-2:] != "_t":
        return False
    # level might also contain :
    if len(splits[3]) < 1:
        return False
    return True

def joinArgs(args):
    if "quote" in dir(shlex):
        return " ".join(shlex.quote(a) for a in args)
    else:
        return " ".join(pipes.quote(a) for a in args)

def splitArgs(_string):
    if PY2 and isinstance(_string, unicode): # noqa: F821
        # Python2's shlex doesn't like unicode
        _string = u2b(_string)
        splits = shlex.split(_string)
        return map(b2u, splits)
    else:
        return shlex.split(_string)

def b2u(_string):
    """ bytes to unicode """
    if isinstance(_string, bytes):
        return _string.decode('UTF-8', 'replace')
    return _string

def u2b(_string):
    """ unicode to bytes """
    if not isinstance(_string, bytes):
        return _string.encode('UTF-8', 'replace')
    return _string

def u2b_if_py2(_string):
    """ unicode to bytes only if Python 2"""
    if PY2 and isinstance(_string, unicode): # noqa: F821
        return _string.encode('UTF-8', 'replace')
    return _string
errors.py000064400000010343150351351720006435 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2012 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

ALREADY_ENABLED     =   11
NOT_ENABLED         =   12
COMMAND_FAILED      =   13
NO_IPV6_NAT         =   14
PANIC_MODE          =   15
ZONE_ALREADY_SET    =   16
UNKNOWN_INTERFACE   =   17
ZONE_CONFLICT       =   18
BUILTIN_CHAIN       =   19
EBTABLES_NO_REJECT  =   20
NOT_OVERLOADABLE    =   21
NO_DEFAULTS         =   22
BUILTIN_ZONE        =   23
BUILTIN_SERVICE     =   24
BUILTIN_ICMPTYPE    =   25
NAME_CONFLICT       =   26
NAME_MISMATCH       =   27
PARSE_ERROR         =   28
ACCESS_DENIED       =   29
UNKNOWN_SOURCE      =   30
RT_TO_PERM_FAILED   =   31
IPSET_WITH_TIMEOUT  =   32
BUILTIN_IPSET       =   33
ALREADY_SET         =   34
MISSING_IMPORT      =   35
DBUS_ERROR          =   36
BUILTIN_HELPER      =   37
NOT_APPLIED         =   38

INVALID_ACTION      =  100
INVALID_SERVICE     =  101
INVALID_PORT        =  102
INVALID_PROTOCOL    =  103
INVALID_INTERFACE   =  104
INVALID_ADDR        =  105
INVALID_FORWARD     =  106
INVALID_ICMPTYPE    =  107
INVALID_TABLE       =  108
INVALID_CHAIN       =  109
INVALID_TARGET      =  110
INVALID_IPV         =  111
INVALID_ZONE        =  112
INVALID_PROPERTY    =  113
INVALID_VALUE       =  114
INVALID_OBJECT      =  115
INVALID_NAME        =  116
INVALID_FILENAME    =  117
INVALID_DIRECTORY   =  118
INVALID_TYPE        =  119
INVALID_SETTING     =  120
INVALID_DESTINATION =  121
INVALID_RULE        =  122
INVALID_LIMIT       =  123
INVALID_FAMILY      =  124
INVALID_LOG_LEVEL   =  125
INVALID_AUDIT_TYPE  =  126
INVALID_MARK        =  127
INVALID_CONTEXT     =  128
INVALID_COMMAND     =  129
INVALID_USER        =  130
INVALID_UID         =  131
INVALID_MODULE      =  132
INVALID_PASSTHROUGH =  133
INVALID_MAC         =  134
INVALID_IPSET       =  135
INVALID_ENTRY       =  136
INVALID_OPTION      =  137
INVALID_HELPER      =  138
INVALID_PRIORITY    =  139
INVALID_POLICY      =  140

MISSING_TABLE       =  200
MISSING_CHAIN       =  201
MISSING_PORT        =  202
MISSING_PROTOCOL    =  203
MISSING_ADDR        =  204
MISSING_NAME        =  205
MISSING_SETTING     =  206
MISSING_FAMILY      =  207

RUNNING_BUT_FAILED  =  251
NOT_RUNNING         =  252
NOT_AUTHORIZED      =  253
UNKNOWN_ERROR       =  254

import sys

class FirewallError(Exception):
    def __init__(self, code, msg=None):
        self.code = code
        if msg is not None:
            # escape msg if needed
            if sys.version < '3':
                try:
                    x = str(msg) # noqa: F841
                except UnicodeEncodeError:
                    msg = unicode(msg).encode("unicode_escape") # noqa: F821
        self.msg = msg

    def __repr__(self):
        return '%s(%r, %r)' % (self.__class__, self.code, self.msg)

    def __str__(self):
        if self.msg:
            return "%s: %s" % (self.errors[self.code], self.msg)
        return self.errors[self.code]

    def get_code(msg):
        if ":" in msg:
            idx = msg.index(":")
            ecode = msg[:idx]
        else:
            ecode = msg

        try:
            code = FirewallError.codes[ecode]
        except KeyError:
            code = UNKNOWN_ERROR

        return code

    get_code = staticmethod(get_code)

mod = sys.modules[FirewallError.__module__]
FirewallError.errors = { getattr(mod,varname) : varname
                         for varname in dir(mod)
                         if not varname.startswith("_") and \
                         type(getattr(mod,varname)) == int }
FirewallError.codes =  { FirewallError.errors[code] : code
                         for code in FirewallError.errors }
command.py000064400000057301150351351720006544 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""FirewallCommand class for command line client simplification"""

__all__ = [ "FirewallCommand" ]

import sys

from firewall import errors
from firewall.errors import FirewallError
from dbus.exceptions import DBusException
from firewall.functions import checkIPnMask, checkIP6nMask, check_mac, \
    check_port, check_single_address

class FirewallCommand(object):
    def __init__(self, quiet=False, verbose=False):
        self.quiet = quiet
        self.verbose = verbose
        self.__use_exception_handler = True
        self.fw = None

    def set_fw(self, fw):
        self.fw = fw

    def set_quiet(self, flag):
        self.quiet = flag

    def get_quiet(self):
        return self.quiet

    def set_verbose(self, flag):
        self.verbose = flag

    def get_verbose(self):
        return self.verbose

    def print_msg(self, msg=None):
        if msg is not None and not self.quiet:
            sys.stdout.write(msg + "\n")

    def print_error_msg(self, msg=None):
        if msg is not None and not self.quiet:
            sys.stderr.write(msg + "\n")

    def print_warning(self, msg=None):
        FAIL = '\033[91m'
        END = '\033[00m'
        if sys.stderr.isatty():
            msg = FAIL + msg + END
        self.print_error_msg(msg)

    def print_and_exit(self, msg=None, exit_code=0):
        #OK = '\033[92m'
        #END = '\033[00m'
        if exit_code > 1:
            self.print_warning(msg)
        else:
            #if sys.stdout.isatty():
            #   msg = OK + msg + END
            self.print_msg(msg)
        sys.exit(exit_code)

    def fail(self, msg=None):
        self.print_and_exit(msg, 2)

    def print_if_verbose(self, msg=None):
        if msg is not None and self.verbose:
            sys.stdout.write(msg + "\n")

    def __cmd_sequence(self, cmd_type, option, action_method, query_method, # pylint: disable=W0613, R0913, R0914
                       parse_method, message, start_args=None, end_args=None, # pylint: disable=W0613
                       no_exit=False):
        if self.fw is not None:
            self.fw.authorizeAll()
        items = [ ]
        _errors = 0
        _error_codes = [ ]
        for item in option:
            if parse_method is not None:
                try:
                    item = parse_method(item)
                except Exception as msg:
                    code = FirewallError.get_code(str(msg))
                    if len(option) > 1:
                        self.print_warning("Warning: %s" % msg)
                    else:
                        self.print_and_exit("Error: %s" % msg, code)
                    if code not in _error_codes:
                        _error_codes.append(code)
                    _errors += 1
                    continue

            items.append(item)

        for item in items:
            call_item = [ ]
            if start_args is not None:
                call_item += start_args
            if not isinstance(item, list) and not isinstance(item, tuple):
                call_item.append(item)
            else:
                call_item += item
            if end_args is not None:
                call_item += end_args
            self.deactivate_exception_handler()
            try:
                action_method(*call_item)
            except (DBusException, Exception) as msg:
                if isinstance(msg, DBusException):
                    self.fail_if_not_authorized(msg.get_dbus_name())
                    msg = msg.get_dbus_message()
                else:
                    msg = str(msg)
                code = FirewallError.get_code(msg)
                if code in [ errors.ALREADY_ENABLED, errors.NOT_ENABLED,
                             errors.ZONE_ALREADY_SET, errors.ALREADY_SET ]:
                    code = 0
                if len(option) > 1:
                    self.print_warning("Warning: %s" % msg)
                elif code == 0:
                    self.print_warning("Warning: %s" % msg)
                    return
                else:
                    self.print_and_exit("Error: %s" % msg, code)
                if code not in _error_codes:
                    _error_codes.append(code)
                _errors += 1
            self.activate_exception_handler()

        if not no_exit:
            if len(option) > _errors or 0 in _error_codes:
                # There have been more options than errors or there
                # was at least one error code 0, return.
                return
            elif len(_error_codes) == 1:
                # Exactly one error code, use it.
                sys.exit(_error_codes[0])
            elif len(_error_codes) > 1:
                # There is more than error, exit using
                # UNKNOWN_ERROR. This could happen within sequences
                # where parsing failed with different errors like
                # INVALID_PORT and INVALID_PROTOCOL.
                sys.exit(errors.UNKNOWN_ERROR)

    def add_sequence(self, option, action_method, query_method, parse_method, # pylint: disable=R0913
                     message, no_exit=False):
        self.__cmd_sequence("add", option, action_method, query_method,
                            parse_method, message, no_exit=no_exit)

    def x_add_sequence(self, x, option, action_method, query_method, # pylint: disable=R0913
                       parse_method, message, no_exit=False):
        self.__cmd_sequence("add", option, action_method, query_method,
                            parse_method, message, start_args=[x],
                            no_exit=no_exit)

    def zone_add_timeout_sequence(self, zone, option, action_method, # pylint: disable=R0913
                                  query_method, parse_method, message,
                                  timeout, no_exit=False):
        self.__cmd_sequence("add", option, action_method, query_method,
                            parse_method, message, start_args=[zone],
                            end_args=[timeout], no_exit=no_exit)

    def remove_sequence(self, option, action_method, query_method, # pylint: disable=R0913
                        parse_method, message, no_exit=False):
        self.__cmd_sequence("remove", option, action_method, query_method,
                            parse_method, message, no_exit=no_exit)

    def x_remove_sequence(self, x, option, action_method, query_method, # pylint: disable=R0913
                          parse_method, message, no_exit=False):
        self.__cmd_sequence("remove", option, action_method, query_method,
                            parse_method, message, start_args=[x],
                            no_exit=no_exit)


    def __query_sequence(self, option, query_method, parse_method, message, # pylint: disable=R0913
                         start_args=None, no_exit=False):
        items = [ ]
        for item in option:
            if parse_method is not None:
                try:
                    item = parse_method(item)
                except Exception as msg:
                    if len(option) > 1:
                        self.print_warning("Warning: %s" % msg)
                        continue
                    else:
                        code = FirewallError.get_code(str(msg))
                        self.print_and_exit("Error: %s" % msg, code)
            items.append(item)

        for item in items:
            call_item = [ ]
            if start_args is not None:
                call_item += start_args
            if not isinstance(item, list) and not isinstance(item, tuple):
                call_item.append(item)
            else:
                call_item += item
            self.deactivate_exception_handler()
            try:
                res = query_method(*call_item)
            except DBusException as msg:
                self.fail_if_not_authorized(msg.get_dbus_name())
                code = FirewallError.get_code(msg.get_dbus_message())
                if len(option) > 1:
                    self.print_warning("Warning: %s" % msg.get_dbus_message())
                    continue
                else:
                    self.print_and_exit("Error: %s" % msg.get_dbus_message(),
                                        code)
            except Exception as msg:
                code = FirewallError.get_code(str(msg))
                if len(option) > 1:
                    self.print_warning("Warning: %s" % msg)
                else:
                    self.print_and_exit("Error: %s" % msg, code)
            self.activate_exception_handler()
            if len(option) > 1:
                self.print_msg("%s: %s" % (message % item, ("no", "yes")[res]))
            else:
                self.print_query_result(res)
        if not no_exit:
            sys.exit(0)

    def query_sequence(self, option, query_method, parse_method, message, # pylint: disable=R0913
                       no_exit=False):
        self.__query_sequence(option, query_method, parse_method,
                              message, no_exit=no_exit)

    def x_query_sequence(self, x, option, query_method, parse_method, # pylint: disable=R0913
                         message, no_exit=False):
        self.__query_sequence(option, query_method, parse_method,
                              message, start_args=[x], no_exit=no_exit)


    def parse_source(self, value):
        if not checkIPnMask(value) and not checkIP6nMask(value) \
           and not check_mac(value) and not \
           (value.startswith("ipset:") and len(value) > 6):
            raise FirewallError(errors.INVALID_ADDR,
                                "'%s' is no valid IPv4, IPv6 or MAC address, nor an ipset" % value)
        return value

    def parse_port(self, value, separator="/"):
        try:
            (port, proto) = value.split(separator)
        except ValueError:
            raise FirewallError(errors.INVALID_PORT, "bad port (most likely "
                                "missing protocol), correct syntax is "
                                "portid[-portid]%sprotocol" % separator)
        if not check_port(port):
            raise FirewallError(errors.INVALID_PORT, port)
        if proto not in [ "tcp", "udp", "sctp", "dccp" ]:
            raise FirewallError(errors.INVALID_PROTOCOL,
                                "'%s' not in {'tcp'|'udp'|'sctp'|'dccp'}" % \
                                proto)
        return (port, proto)

    def parse_forward_port(self, value, compat=False):
        port = None
        protocol = None
        toport = None
        toaddr = None
        i = 0
        while ("=" in value[i:]):
            opt = value[i:].split("=", 1)[0]
            i += len(opt) + 1
            if "=" in value[i:]:
                val = value[i:].split(":", 1)[0]
            else:
                val = value[i:]
            i += len(val) + 1

            if opt == "port":
                port = val
            elif opt == "proto":
                protocol = val
            elif opt == "toport":
                toport = val
            elif opt == "toaddr":
                toaddr = val
            elif opt == "if" and compat:
                # ignore if option in compat mode
                pass
            else:
                raise FirewallError(errors.INVALID_FORWARD,
                                    "invalid forward port arg '%s'" % (opt))
        if not port:
            raise FirewallError(errors.INVALID_FORWARD, "missing port")
        if not protocol:
            raise FirewallError(errors.INVALID_FORWARD, "missing protocol")
        if not (toport or toaddr):
            raise FirewallError(errors.INVALID_FORWARD, "missing destination")

        if not check_port(port):
            raise FirewallError(errors.INVALID_PORT, port)
        if protocol not in [ "tcp", "udp", "sctp", "dccp" ]:
            raise FirewallError(errors.INVALID_PROTOCOL,
                                "'%s' not in {'tcp'|'udp'|'sctp'|'dccp'}" % \
                                protocol)
        if toport and not check_port(toport):
            raise FirewallError(errors.INVALID_PORT, toport)
        if toaddr and not check_single_address("ipv4", toaddr):
            if compat or not check_single_address("ipv6", toaddr):
                raise FirewallError(errors.INVALID_ADDR, toaddr)

        return (port, protocol, toport, toaddr)

    def parse_ipset_option(self, value):
        args = value.split("=")
        if len(args) == 1:
            return (args[0], "")
        elif len(args) == 2:
            return args
        else:
            raise FirewallError(errors.INVALID_OPTION,
                                "invalid ipset option '%s'" % (value))

    def check_destination_ipv(self, value):
        ipvs = [ "ipv4", "ipv6", ]
        if value not in ipvs:
            raise FirewallError(errors.INVALID_IPV,
                                "invalid argument: %s (choose from '%s')" % \
                                (value, "', '".join(ipvs)))
        return value

    def parse_service_destination(self, value):
        try:
            (ipv, destination) = value.split(":", 1)
        except ValueError:
            raise FirewallError(errors.INVALID_DESTINATION,
                                "destination syntax is ipv:address[/mask]")
        return (self.check_destination_ipv(ipv), destination)

    def check_ipv(self, value):
        ipvs = [ "ipv4", "ipv6", "eb" ]
        if value not in ipvs:
            raise FirewallError(errors.INVALID_IPV,
                                "invalid argument: %s (choose from '%s')" % \
                                (value, "', '".join(ipvs)))
        return value

    def check_helper_family(self, value):
        ipvs = [ "", "ipv4", "ipv6" ]
        if value not in ipvs:
            raise FirewallError(errors.INVALID_IPV,
                                "invalid argument: %s (choose from '%s')" % \
                                (value, "', '".join(ipvs)))
        return value

    def check_module(self, value):
        if not value.startswith("nf_conntrack_"):
            raise FirewallError(
                errors.INVALID_MODULE,
                "'%s' does not start with 'nf_conntrack_'" % value)
        if len(value.replace("nf_conntrack_", "")) < 1:
            raise FirewallError(errors.INVALID_MODULE,
                                "Module name '%s' too short" % value)
        return value

    def print_zone_policy_info(self, zone, settings, default_zone=None, extra_interfaces=[], isPolicy=True): # pylint: disable=R0914
        target = settings.getTarget()
        services = settings.getServices()
        ports = settings.getPorts()
        protocols = settings.getProtocols()
        masquerade = settings.getMasquerade()
        forward_ports = settings.getForwardPorts()
        source_ports = settings.getSourcePorts()
        icmp_blocks = settings.getIcmpBlocks()
        rules = settings.getRichRules()
        description = settings.getDescription()
        short_description = settings.getShort()
        if isPolicy:
            ingress_zones = settings.getIngressZones()
            egress_zones = settings.getEgressZones()
            priority = settings.getPriority()
        else:
            icmp_block_inversion = settings.getIcmpBlockInversion()
            interfaces = sorted(set(settings.getInterfaces() + extra_interfaces))
            sources = settings.getSources()
            forward = settings.getForward()

        def rich_rule_sorted_key(rule):
            priority = 0
            search_str = "priority="
            try:
                i = rule.index(search_str)
            except ValueError:
                pass
            else:
                i += len(search_str)
                priority = int(rule[i:i+(rule[i:].index(" "))].replace("\"", ""))

            return priority

        attributes = []
        if default_zone is not None:
            if zone == default_zone:
                attributes.append("default")
        if (not isPolicy and (interfaces or sources)) or \
           (    isPolicy and ingress_zones and egress_zones):
            attributes.append("active")
        if attributes:
            zone = zone + " (%s)" % ", ".join(attributes)
        self.print_msg(zone)
        if self.verbose:
            self.print_msg("  summary: " + short_description)
            self.print_msg("  description: " + description)
        if isPolicy:
            self.print_msg("  priority: " + str(priority))
        self.print_msg("  target: " + target)
        if not isPolicy:
            self.print_msg("  icmp-block-inversion: %s" % \
                           ("yes" if icmp_block_inversion else "no"))
        if isPolicy:
            self.print_msg("  ingress-zones: " + " ".join(ingress_zones))
            self.print_msg("  egress-zones: " + " ".join(egress_zones))
        else:
            self.print_msg("  interfaces: " + " ".join(interfaces))
            self.print_msg("  sources: " + " ".join(sources))
        self.print_msg("  services: " + " ".join(sorted(services)))
        self.print_msg("  ports: " + " ".join(["%s/%s" % (port[0], port[1])
                                               for port in ports]))
        self.print_msg("  protocols: " + " ".join(sorted(protocols)))
        if not isPolicy:
            self.print_msg("  forward: %s" % ("yes" if forward else "no"))
        self.print_msg("  masquerade: %s" % ("yes" if masquerade else "no"))
        self.print_msg("  forward-ports: " + ("\n\t" if forward_ports else "") +
                       "\n\t".join(["port=%s:proto=%s:toport=%s:toaddr=%s" % \
                                    (port, proto, toport, toaddr)
                                    for (port, proto, toport, toaddr) in \
                                    forward_ports]))
        self.print_msg("  source-ports: " +
                       " ".join(["%s/%s" % (port[0], port[1])
                                 for port in source_ports]))
        self.print_msg("  icmp-blocks: " + " ".join(icmp_blocks))
        self.print_msg("  rich rules: " + ("\n\t" if rules else "") +
                            "\n\t".join(sorted(rules, key=rich_rule_sorted_key)))

    def print_zone_info(self, zone, settings, default_zone=None, extra_interfaces=[]):
        self.print_zone_policy_info(zone, settings, default_zone=default_zone, extra_interfaces=extra_interfaces, isPolicy=False)

    def print_policy_info(self, policy, settings, default_zone=None, extra_interfaces=[]):
        self.print_zone_policy_info(policy, settings, default_zone=default_zone, extra_interfaces=extra_interfaces, isPolicy=True)

    def print_service_info(self, service, settings):
        ports = settings.getPorts()
        protocols = settings.getProtocols()
        source_ports = settings.getSourcePorts()
        modules = settings.getModules()
        description = settings.getDescription()
        destinations = settings.getDestinations()
        short_description = settings.getShort()
        includes = settings.getIncludes()
        helpers = settings.getHelpers()
        self.print_msg(service)
        if self.verbose:
            self.print_msg("  summary: " + short_description)
            self.print_msg("  description: " + description)
        self.print_msg("  ports: " + " ".join(["%s/%s" % (port[0], port[1])
                                               for port in ports]))
        self.print_msg("  protocols: " + " ".join(protocols))
        self.print_msg("  source-ports: " +
                       " ".join(["%s/%s" % (port[0], port[1])
                                 for port in source_ports]))
        self.print_msg("  modules: " + " ".join(modules))
        self.print_msg("  destination: " +
                       " ".join(["%s:%s" % (k, v)
                                 for k, v in destinations.items()]))
        self.print_msg("  includes: " + " ".join(sorted(includes)))
        self.print_msg("  helpers: " + " ".join(sorted(helpers)))

    def print_icmptype_info(self, icmptype, settings):
        destinations = settings.getDestinations()
        description = settings.getDescription()
        short_description = settings.getShort()
        if len(destinations) == 0:
            destinations = [ "ipv4", "ipv6" ]
        self.print_msg(icmptype)
        if self.verbose:
            self.print_msg("  summary: " + short_description)
            self.print_msg("  description: " + description)
        self.print_msg("  destination: " + " ".join(destinations))

    def print_ipset_info(self, ipset, settings):
        ipset_type = settings.getType()
        options = settings.getOptions()
        entries = settings.getEntries()
        description = settings.getDescription()
        short_description = settings.getShort()
        self.print_msg(ipset)
        if self.verbose:
            self.print_msg("  summary: " + short_description)
            self.print_msg("  description: " + description)
        self.print_msg("  type: " + ipset_type)
        self.print_msg("  options: " + " ".join(["%s=%s" % (k, v) if v else k
                                                 for k, v in options.items()]))
        self.print_msg("  entries: " + " ".join(entries))

    def print_helper_info(self, helper, settings):
        ports = settings.getPorts()
        module = settings.getModule()
        family = settings.getFamily()
        description = settings.getDescription()
        short_description = settings.getShort()
        self.print_msg(helper)
        if self.verbose:
            self.print_msg("  summary: " + short_description)
            self.print_msg("  description: " + description)
        self.print_msg("  family: " + family)
        self.print_msg("  module: " + module)
        self.print_msg("  ports: " + " ".join(["%s/%s" % (port[0], port[1])
                                               for port in ports]))

    def print_query_result(self, value):
        if value:
            self.print_and_exit("yes")
        else:
            self.print_and_exit("no", 1)

    def exception_handler(self, exception_message):
        if not self.__use_exception_handler:
            raise
        self.fail_if_not_authorized(exception_message)
        code = FirewallError.get_code(str(exception_message))
        if code in [ errors.ALREADY_ENABLED, errors.NOT_ENABLED,
                     errors.ZONE_ALREADY_SET, errors.ALREADY_SET ]:
            self.print_warning("Warning: %s" % exception_message)
        else:
            self.print_and_exit("Error: %s" % exception_message, code)

    def fail_if_not_authorized(self, exception_message):
        if "NotAuthorizedException" in exception_message:
            msg = """Authorization failed.
    Make sure polkit agent is running or run the application as superuser."""
            self.print_and_exit(msg, errors.NOT_AUTHORIZED)

    def deactivate_exception_handler(self):
        self.__use_exception_handler = False

    def activate_exception_handler(self):
        self.__use_exception_handler = True

    def get_ipset_entries_from_file(self, filename):
        entries = [ ]
        entries_set = set()
        f = open(filename)
        for line in f:
            if not line:
                break
            line = line.strip()
            if len(line) < 1 or line[0] in ['#', ';']:
                continue
            if line not in entries_set:
                entries.append(line)
                entries_set.add(line)
        f.close()
        return entries
core/__init__.py000064400000000000150351351720007575 0ustar00core/nftables.py000064400000305427150351351720007661 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2018 Red Hat, Inc.
#
# Authors:
# Eric Garver <e@erig.me>
#
# 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/>.
#
from __future__ import absolute_import

import copy
import json
import ipaddress

from firewall.core.logger import log
from firewall.functions import check_mac, getPortRange, normalizeIP6, \
                               check_single_address, check_address
from firewall.errors import FirewallError, UNKNOWN_ERROR, INVALID_RULE, \
                            INVALID_ICMPTYPE, INVALID_TYPE, INVALID_ENTRY, \
                            INVALID_PORT
from firewall.core.rich import Rich_Accept, Rich_Reject, Rich_Drop, Rich_Mark, \
                               Rich_Masquerade, Rich_ForwardPort, Rich_IcmpBlock
from nftables.nftables import Nftables

TABLE_NAME = "firewalld"
TABLE_NAME_POLICY = TABLE_NAME + "_" + "policy_drop"
POLICY_CHAIN_PREFIX = "policy_"

# Map iptables (table, chain) to hooks and priorities.
# These are well defined by NF_IP_PRI_* defines in netfilter.
#
# This is analogous to ipXtables.BUILT_IN_CHAINS, but we omit the chains that
# are only used for direct rules.
#
# Note: All hooks use their standard position + NFT_HOOK_OFFSET. This means
# iptables will have DROP precedence. It also means that even if iptables
# ACCEPTs a packet it may still be dropped later by firewalld's rules.
#
NFT_HOOK_OFFSET = 10
IPTABLES_TO_NFT_HOOK = {
    #"security": {
    #    "INPUT": ("input", 50 + NFT_HOOK_OFFSET),
    #    "OUTPUT": ("output", 50 + NFT_HOOK_OFFSET),
    #    "FORWARD": ("forward", 50 + NFT_HOOK_OFFSET),
    #},
    "raw": {
    #   "PREROUTING": ("prerouting", -300 + NFT_HOOK_OFFSET),
    #   "OUTPUT": ("output", -300 + NFT_HOOK_OFFSET),
    },
    "mangle": {
        "PREROUTING": ("prerouting", -150 + NFT_HOOK_OFFSET),
    #    "POSTROUTING": ("postrouting", -150 + NFT_HOOK_OFFSET),
    #    "INPUT": ("input", -150 + NFT_HOOK_OFFSET),
    #    "OUTPUT": ("output", -150 + NFT_HOOK_OFFSET),
    #    "FORWARD": ("forward", -150 + NFT_HOOK_OFFSET),
    },
    "nat": {
        "PREROUTING": ("prerouting", -100 + NFT_HOOK_OFFSET),
        "POSTROUTING": ("postrouting", 100 + NFT_HOOK_OFFSET),
    #    "INPUT": ("input", 100 + NFT_HOOK_OFFSET),
    #    "OUTPUT": ("output", -100 + NFT_HOOK_OFFSET),
    },
    "filter": {
        "PREROUTING": ("prerouting", 0 + NFT_HOOK_OFFSET),
        "INPUT": ("input", 0 + NFT_HOOK_OFFSET),
        "FORWARD": ("forward", 0 + NFT_HOOK_OFFSET),
        "OUTPUT": ("output", 0 + NFT_HOOK_OFFSET),
    },
}

def _icmp_types_fragments(protocol, type, code=None):
    fragments = [{"match": {"left": {"payload": {"protocol": protocol, "field": "type"}},
                            "op": "==",
                            "right": type}}]
    if code is not None:
        fragments.append({"match": {"left": {"payload": {"protocol": protocol, "field": "code"}},
                                    "op": "==",
                                    "right": code}})
    return fragments

# Most ICMP types are provided by nft, but for the codes we have to use numeric
# values.
#
ICMP_TYPES_FRAGMENTS = {
    "ipv4": {
        "communication-prohibited":     _icmp_types_fragments("icmp", "destination-unreachable", 13),
        "destination-unreachable":      _icmp_types_fragments("icmp", "destination-unreachable"),
        "echo-reply":                   _icmp_types_fragments("icmp", "echo-reply"),
        "echo-request":                 _icmp_types_fragments("icmp", "echo-request"),
        "fragmentation-needed":         _icmp_types_fragments("icmp", "destination-unreachable", 4),
        "host-precedence-violation":    _icmp_types_fragments("icmp", "destination-unreachable", 14),
        "host-prohibited":              _icmp_types_fragments("icmp", "destination-unreachable", 10),
        "host-redirect":                _icmp_types_fragments("icmp", "redirect", 1),
        "host-unknown":                 _icmp_types_fragments("icmp", "destination-unreachable", 7),
        "host-unreachable":             _icmp_types_fragments("icmp", "destination-unreachable", 1),
        "ip-header-bad":                _icmp_types_fragments("icmp", "parameter-problem", 1),
        "network-prohibited":           _icmp_types_fragments("icmp", "destination-unreachable", 8),
        "network-redirect":             _icmp_types_fragments("icmp", "redirect", 0),
        "network-unknown":              _icmp_types_fragments("icmp", "destination-unreachable", 6),
        "network-unreachable":          _icmp_types_fragments("icmp", "destination-unreachable", 0),
        "parameter-problem":            _icmp_types_fragments("icmp", "parameter-problem"),
        "port-unreachable":             _icmp_types_fragments("icmp", "destination-unreachable", 3),
        "precedence-cutoff":            _icmp_types_fragments("icmp", "destination-unreachable", 15),
        "protocol-unreachable":         _icmp_types_fragments("icmp", "destination-unreachable", 2),
        "redirect":                     _icmp_types_fragments("icmp", "redirect"),
        "required-option-missing":      _icmp_types_fragments("icmp", "parameter-problem", 1),
        "router-advertisement":         _icmp_types_fragments("icmp", "router-advertisement"),
        "router-solicitation":          _icmp_types_fragments("icmp", "router-solicitation"),
        "source-quench":                _icmp_types_fragments("icmp", "source-quench"),
        "source-route-failed":          _icmp_types_fragments("icmp", "destination-unreachable", 5),
        "time-exceeded":                _icmp_types_fragments("icmp", "time-exceeded"),
        "timestamp-reply":              _icmp_types_fragments("icmp", "timestamp-reply"),
        "timestamp-request":            _icmp_types_fragments("icmp", "timestamp-request"),
        "tos-host-redirect":            _icmp_types_fragments("icmp", "redirect", 3),
        "tos-host-unreachable":         _icmp_types_fragments("icmp", "destination-unreachable", 12),
        "tos-network-redirect":         _icmp_types_fragments("icmp", "redirect", 2),
        "tos-network-unreachable":      _icmp_types_fragments("icmp", "destination-unreachable", 11),
        "ttl-zero-during-reassembly":   _icmp_types_fragments("icmp", "time-exceeded", 1),
        "ttl-zero-during-transit":      _icmp_types_fragments("icmp", "time-exceeded", 0),
    },

    "ipv6": {
        "address-unreachable":          _icmp_types_fragments("icmpv6", "destination-unreachable", 3),
        "bad-header":                   _icmp_types_fragments("icmpv6", "parameter-problem", 0),
        "beyond-scope":                 _icmp_types_fragments("icmpv6", "destination-unreachable", 2),
        "communication-prohibited":     _icmp_types_fragments("icmpv6", "destination-unreachable", 1),
        "destination-unreachable":      _icmp_types_fragments("icmpv6", "destination-unreachable"),
        "echo-reply":                   _icmp_types_fragments("icmpv6", "echo-reply"),
        "echo-request":                 _icmp_types_fragments("icmpv6", "echo-request"),
        "failed-policy":                _icmp_types_fragments("icmpv6", "destination-unreachable", 5),
        "mld-listener-done":            _icmp_types_fragments("icmpv6", "mld-listener-done"),
        "mld-listener-query":           _icmp_types_fragments("icmpv6", "mld-listener-query"),
        "mld-listener-report":          _icmp_types_fragments("icmpv6", "mld-listener-report"),
        "mld2-listener-report":         _icmp_types_fragments("icmpv6", "mld2-listener-report"),
        "neighbour-advertisement":      _icmp_types_fragments("icmpv6", "nd-neighbor-advert"),
        "neighbour-solicitation":       _icmp_types_fragments("icmpv6", "nd-neighbor-solicit"),
        "no-route":                     _icmp_types_fragments("icmpv6", "destination-unreachable", 0),
        "packet-too-big":               _icmp_types_fragments("icmpv6", "packet-too-big"),
        "parameter-problem":            _icmp_types_fragments("icmpv6", "parameter-problem"),
        "port-unreachable":             _icmp_types_fragments("icmpv6", "destination-unreachable", 4),
        "redirect":                     _icmp_types_fragments("icmpv6", "nd-redirect"),
        "reject-route":                 _icmp_types_fragments("icmpv6", "destination-unreachable", 6),
        "router-advertisement":         _icmp_types_fragments("icmpv6", "nd-router-advert"),
        "router-solicitation":          _icmp_types_fragments("icmpv6", "nd-router-solicit"),
        "time-exceeded":                _icmp_types_fragments("icmpv6", "time-exceeded"),
        "ttl-zero-during-reassembly":   _icmp_types_fragments("icmpv6", "time-exceeded", 1),
        "ttl-zero-during-transit":      _icmp_types_fragments("icmpv6", "time-exceeded", 0),
        "unknown-header-type":          _icmp_types_fragments("icmpv6", "parameter-problem", 1),
        "unknown-option":               _icmp_types_fragments("icmpv6", "parameter-problem", 2),
    }
}

class nftables(object):
    name = "nftables"
    policies_supported = True

    def __init__(self, fw):
        self._fw = fw
        self.restore_command_exists = True
        self.available_tables = []
        self.rule_to_handle = {}
        self.rule_ref_count = {}
        self.rich_rule_priority_counts = {}
        self.policy_priority_counts = {}
        self.zone_source_index_cache = {}
        self.created_tables = {"inet": [], "ip": [], "ip6": []}

        self.nftables = Nftables()
        self.nftables.set_echo_output(True)
        self.nftables.set_handle_output(True)

    def _run_replace_zone_source(self, rule, zone_source_index_cache):
        for verb in ["add", "insert", "delete"]:
            if verb in rule:
                break

        if "%%ZONE_SOURCE%%" in rule[verb]["rule"]:
            zone_source = (rule[verb]["rule"]["%%ZONE_SOURCE%%"]["zone"],
                           rule[verb]["rule"]["%%ZONE_SOURCE%%"]["address"])
            del rule[verb]["rule"]["%%ZONE_SOURCE%%"]
        elif "%%ZONE_INTERFACE%%" in rule[verb]["rule"]:
            zone_source = None
            del rule[verb]["rule"]["%%ZONE_INTERFACE%%"]
        else:
            return

        family = rule[verb]["rule"]["family"]

        if zone_source and verb == "delete":
            if family in zone_source_index_cache and \
               zone_source in zone_source_index_cache[family]:
                zone_source_index_cache[family].remove(zone_source)
        elif verb != "delete":
            if family not in zone_source_index_cache:
                zone_source_index_cache[family] = []

            if zone_source:
                # order source based dispatch by zone name
                if zone_source not in zone_source_index_cache[family]:
                    zone_source_index_cache[family].append(zone_source)
                    zone_source_index_cache[family].sort(key=lambda x: x[0])

                index = zone_source_index_cache[family].index(zone_source)
            else:
                if self._fw._allow_zone_drifting:
                    index = 0
                else:
                    index = len(zone_source_index_cache[family])

            _verb_snippet = rule[verb]
            del rule[verb]
            if index == 0:
                rule["insert"] = _verb_snippet
            else:
                index -= 1 # point to the rule before insertion point
                rule["add"] = _verb_snippet
                rule["add"]["rule"]["index"] = index

    def reverse_rule(self, dict):
        if "insert" in dict:
            return {"delete": copy.deepcopy(dict["insert"])}
        elif "add" in dict:
            return {"delete": copy.deepcopy(dict["add"])}
        else:
            raise FirewallError(UNKNOWN_ERROR, "Failed to reverse rule")

    def _set_rule_replace_priority(self, rule, priority_counts, token):
        for verb in ["add", "insert", "delete"]:
            if verb in rule:
                break

        if token in rule[verb]["rule"]:
            priority = rule[verb]["rule"][token]
            del rule[verb]["rule"][token]
            if type(priority) != int:
                raise FirewallError(INVALID_RULE, "priority must be followed by a number")
            chain = (rule[verb]["rule"]["family"], rule[verb]["rule"]["chain"]) # family, chain
            # Add the rule to the priority counts. We don't need to store the
            # rule, just bump the ref count for the priority value.
            if verb == "delete":
                if chain not in priority_counts or \
                   priority not in priority_counts[chain] or \
                   priority_counts[chain][priority] <= 0:
                    raise FirewallError(UNKNOWN_ERROR, "nonexistent or underflow of priority count")

                priority_counts[chain][priority] -= 1
            else:
                if chain not in priority_counts:
                    priority_counts[chain] = {}
                if priority not in priority_counts[chain]:
                    priority_counts[chain][priority] = 0

                # calculate index of new rule
                index = 0
                for p in sorted(priority_counts[chain].keys()):
                    if p == priority and verb == "insert":
                        break
                    index += priority_counts[chain][p]
                    if p == priority and verb == "add":
                        break

                priority_counts[chain][priority] += 1

                _verb_snippet = rule[verb]
                del rule[verb]
                if index == 0:
                    rule["insert"] = _verb_snippet
                else:
                    index -= 1 # point to the rule before insertion point
                    rule["add"] = _verb_snippet
                    rule["add"]["rule"]["index"] = index

    def _get_rule_key(self, rule):
        for verb in ["add", "insert", "delete"]:
            if verb in rule and "rule" in rule[verb]:
                rule_key = copy.deepcopy(rule[verb]["rule"])
                for non_key in ["index", "handle", "position"]:
                    if non_key in rule_key:
                        del rule_key[non_key]
                # str(rule_key) is insufficient because dictionary order is
                # not stable.. so abuse the JSON library
                rule_key = json.dumps(rule_key, sort_keys=True)
                return rule_key
        # Not a rule (it's a table, chain, etc)
        return None

    def set_rules(self, rules, log_denied):
        _valid_verbs = ["add", "insert", "delete", "flush", "replace"]
        _valid_add_verbs = ["add", "insert", "replace"]
        _deduplicated_rules = []
        _executed_rules = []
        rich_rule_priority_counts = copy.deepcopy(self.rich_rule_priority_counts)
        policy_priority_counts = copy.deepcopy(self.policy_priority_counts)
        zone_source_index_cache = copy.deepcopy(self.zone_source_index_cache)
        rule_ref_count = self.rule_ref_count.copy()
        for rule in rules:
            if type(rule) != dict:
                raise FirewallError(UNKNOWN_ERROR, "rule must be a dictionary, rule: %s" % (rule))

            for verb in _valid_verbs:
                if verb in rule:
                    break
            if verb not in rule:
                raise FirewallError(INVALID_RULE, "no valid verb found, rule: %s" % (rule))

            rule_key = self._get_rule_key(rule)

            # rule deduplication
            if rule_key in rule_ref_count:
                log.debug2("%s: prev rule ref cnt %d, %s", self.__class__,
                           rule_ref_count[rule_key], rule_key)
                if verb != "delete":
                    rule_ref_count[rule_key] += 1
                    continue
                elif rule_ref_count[rule_key] > 1:
                    rule_ref_count[rule_key] -= 1
                    continue
                elif rule_ref_count[rule_key] == 1:
                    rule_ref_count[rule_key] -= 1
                else:
                    raise FirewallError(UNKNOWN_ERROR, "rule ref count bug: rule_key '%s', cnt %d"
                                                       % (rule_key, rule_ref_count[rule_key]))
            elif rule_key and verb != "delete":
                rule_ref_count[rule_key] = 1

            _deduplicated_rules.append(rule)

            _rule = copy.deepcopy(rule)
            if rule_key:
                # filter empty rule expressions. Rich rules add quite a bit of
                # them, but it makes the rest of the code simpler. libnftables
                # does not tolerate them.
                _rule[verb]["rule"]["expr"] = list(filter(None, _rule[verb]["rule"]["expr"]))

                self._set_rule_replace_priority(_rule, rich_rule_priority_counts, "%%RICH_RULE_PRIORITY%%")
                self._set_rule_replace_priority(_rule, policy_priority_counts, "%%POLICY_PRIORITY%%")
                self._run_replace_zone_source(_rule, zone_source_index_cache)

                # delete using rule handle
                if verb == "delete":
                    _rule = {"delete": {"rule": {"family": _rule["delete"]["rule"]["family"],
                                                 "table": _rule["delete"]["rule"]["table"],
                                                 "chain": _rule["delete"]["rule"]["chain"],
                                                 "handle": self.rule_to_handle[rule_key]}}}

            _executed_rules.append(_rule)

        json_blob = {"nftables": [{"metainfo": {"json_schema_version": 1}}] + _executed_rules}
        if log.getDebugLogLevel() >= 3:
            # guarded with if statement because json.dumps() is expensive.
            log.debug3("%s: calling python-nftables with JSON blob: %s", self.__class__,
                       json.dumps(json_blob))
        rc, output, error = self.nftables.json_cmd(json_blob)
        if rc != 0:
            raise ValueError("'%s' failed: %s\nJSON blob:\n%s" % ("python-nftables", error, json.dumps(json_blob)))

        self.rich_rule_priority_counts = rich_rule_priority_counts
        self.policy_priority_counts = policy_priority_counts
        self.zone_source_index_cache = zone_source_index_cache
        self.rule_ref_count = rule_ref_count

        index = 0
        for rule in _deduplicated_rules:
            index += 1 # +1 due to metainfo
            rule_key = self._get_rule_key(rule)

            if not rule_key:
                continue

            if "delete" in rule:
                del self.rule_to_handle[rule_key]
                del self.rule_ref_count[rule_key]
                continue

            for verb in _valid_add_verbs:
                if verb in output["nftables"][index]:
                    break
            if verb not in output["nftables"][index]:
                continue

            self.rule_to_handle[rule_key] = output["nftables"][index][verb]["rule"]["handle"]

    def set_rule(self, rule, log_denied):
        self.set_rules([rule], log_denied)
        return ""

    def get_available_tables(self, table=None):
        # Tables always exist in nftables
        return [table] if table else IPTABLES_TO_NFT_HOOK.keys()

    def _build_delete_table_rules(self, table):
        # To avoid nftables returning ENOENT we always add the table before
        # deleting to guarantee it will exist.
        #
        # In the future, this add+delete should be replaced with "destroy", but
        # that verb is too new to rely upon.
        rules = []
        for family in ["inet", "ip", "ip6"]:
            rules.append({"add": {"table": {"family": family,
                                            "name": table}}})
            rules.append({"delete": {"table": {"family": family,
                                               "name": table}}})
        return rules

    def build_flush_rules(self):
        # Policy is stashed in a separate table that we're _not_ going to
        # flush. As such, we retain the policy rule handles and ref counts.
        saved_rule_to_handle = {}
        saved_rule_ref_count = {}
        for rule in self._build_set_policy_rules_ct_rules(True):
            policy_key = self._get_rule_key(rule)
            if policy_key in self.rule_to_handle:
                saved_rule_to_handle[policy_key] = self.rule_to_handle[policy_key]
                saved_rule_ref_count[policy_key] = self.rule_ref_count[policy_key]

        self.rule_to_handle = saved_rule_to_handle
        self.rule_ref_count = saved_rule_ref_count
        self.rich_rule_priority_counts = {}
        self.policy_priority_counts = {}
        self.zone_source_index_cache = {}

        for family in ["inet", "ip", "ip6"]:
            if TABLE_NAME in self.created_tables[family]:
                self.created_tables[family].remove(TABLE_NAME)

        return self._build_delete_table_rules(TABLE_NAME)

    def _build_set_policy_rules_ct_rules(self, enable):
        add_del = { True: "add", False: "delete" }[enable]
        rules = []
        for hook in ["input", "forward", "output"]:
            rules.append({add_del: {"rule": {"family": "inet",
                                             "table": TABLE_NAME_POLICY,
                                             "chain": "%s_%s" % ("filter", hook),
                                             "expr": [{"match": {"left": {"ct": {"key": "state"}},
                                                                 "op": "in",
                                                                 "right": {"set": ["established", "related"]}}},
                                                      {"accept": None}]}}})
        return rules

    def build_set_policy_rules(self, policy):
        # Policy is not exposed to the user. It's only to make sure we DROP
        # packets while reloading and for panic mode. As such, using hooks with
        # a higher priority than our base chains is sufficient.
        rules = []
        if policy == "PANIC":
            rules.append({"add": {"table": {"family": "inet",
                                            "name": TABLE_NAME_POLICY}}})
            self.created_tables["inet"].append(TABLE_NAME_POLICY)

            # Use "raw" priority for panic mode. This occurs before
            # conntrack, mangle, nat, etc
            for hook in ["prerouting", "output"]:
                rules.append({"add": {"chain": {"family": "inet",
                                                "table": TABLE_NAME_POLICY,
                                                "name": "%s_%s" % ("raw", hook),
                                                "type": "filter",
                                                "hook": hook,
                                                "prio": -300 + NFT_HOOK_OFFSET - 1,
                                                "policy": "drop"}}})
        if policy == "DROP":
            rules.append({"add": {"table": {"family": "inet",
                                            "name": TABLE_NAME_POLICY}}})
            self.created_tables["inet"].append(TABLE_NAME_POLICY)

            # To drop everything except existing connections we use
            # "filter" because it occurs _after_ conntrack.
            for hook in ["input", "forward", "output"]:
                rules.append({"add": {"chain": {"family": "inet",
                                                "table": TABLE_NAME_POLICY,
                                                "name": "%s_%s" % ("filter", hook),
                                                "type": "filter",
                                                "hook": hook,
                                                "prio": 0 + NFT_HOOK_OFFSET - 1,
                                                "policy": "drop"}}})

            rules += self._build_set_policy_rules_ct_rules(True)
        elif policy == "ACCEPT":
            for rule in self._build_set_policy_rules_ct_rules(False):
                policy_key = self._get_rule_key(rule)
                if policy_key in self.rule_to_handle:
                    rules.append(rule)

            rules += self._build_delete_table_rules(TABLE_NAME_POLICY)

            if TABLE_NAME_POLICY in self.created_tables["inet"]:
                self.created_tables["inet"].remove(TABLE_NAME_POLICY)
        else:
            FirewallError(UNKNOWN_ERROR, "not implemented")

        return rules

    def supported_icmp_types(self, ipv=None):
        # nftables supports any icmp_type via arbitrary type/code matching.
        # We just need a translation for it in ICMP_TYPES_FRAGMENTS.
        supported = set()

        for _ipv in [ipv] if ipv else ICMP_TYPES_FRAGMENTS.keys():
            supported.update(ICMP_TYPES_FRAGMENTS[_ipv].keys())

        return list(supported)

    def build_default_tables(self):
        default_tables = []
        for family in ["inet", "ip", "ip6"]:
            default_tables.append({"add": {"table": {"family": family,
                                                     "name": TABLE_NAME}}})
            self.created_tables[family].append(TABLE_NAME)
        return default_tables

    def build_default_rules(self, log_denied="off"):
        default_rules = []
        for chain in IPTABLES_TO_NFT_HOOK["mangle"].keys():
            default_rules.append({"add": {"chain": {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "name": "mangle_%s" % chain,
                                                    "type": "filter",
                                                    "hook": "%s" % IPTABLES_TO_NFT_HOOK["mangle"][chain][0],
                                                    "prio": IPTABLES_TO_NFT_HOOK["mangle"][chain][1]}}})
            for dispatch_suffix in ["POLICIES_pre", "ZONES_SOURCE", "ZONES", "POLICIES_post"] if self._fw._allow_zone_drifting else ["POLICIES_pre", "ZONES", "POLICIES_post"]:
                default_rules.append({"add": {"chain": {"family": "inet",
                                                        "table": TABLE_NAME,
                                                        "name": "mangle_%s_%s" % (chain, dispatch_suffix)}}})
                default_rules.append({"add": {"rule":  {"family": "inet",
                                                        "table": TABLE_NAME,
                                                        "chain": "mangle_%s" % chain,
                                                        "expr": [{"jump": {"target": "mangle_%s_%s" % (chain, dispatch_suffix)}}]}}})

        for family in ["ip", "ip6"]:
            for chain in IPTABLES_TO_NFT_HOOK["nat"].keys():
                default_rules.append({"add": {"chain": {"family": family,
                                                        "table": TABLE_NAME,
                                                        "name": "nat_%s" % chain,
                                                        "type": "nat",
                                                        "hook": "%s" % IPTABLES_TO_NFT_HOOK["nat"][chain][0],
                                                        "prio": IPTABLES_TO_NFT_HOOK["nat"][chain][1]}}})

                for dispatch_suffix in ["POLICIES_pre", "ZONES_SOURCE", "ZONES", "POLICIES_post"] if self._fw._allow_zone_drifting else ["POLICIES_pre", "ZONES", "POLICIES_post"]:
                    default_rules.append({"add": {"chain": {"family": family,
                                                            "table": TABLE_NAME,
                                                            "name": "nat_%s_%s" % (chain, dispatch_suffix)}}})
                    default_rules.append({"add": {"rule":  {"family": family,
                                                            "table": TABLE_NAME,
                                                            "chain": "nat_%s" % chain,
                                                            "expr": [{"jump": {"target": "nat_%s_%s" % (chain, dispatch_suffix)}}]}}})

        for chain in IPTABLES_TO_NFT_HOOK["filter"].keys():
            default_rules.append({"add": {"chain": {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "name": "filter_%s" % chain,
                                                    "type": "filter",
                                                    "hook": "%s" % IPTABLES_TO_NFT_HOOK["filter"][chain][0],
                                                    "prio": IPTABLES_TO_NFT_HOOK["filter"][chain][1]}}})

        # filter, INPUT
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_%s" % "INPUT",
                                                "expr": [{"match": {"left": {"ct": {"key": "state"}},
                                                                    "op": "in",
                                                                    "right": {"set": ["established", "related"]}}},
                                                         {"accept": None}]}}})
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_%s" % "INPUT",
                                                "expr": [{"match": {"left": {"ct": {"key": "status"}},
                                                                    "op": "in",
                                                                    "right": "dnat"}},
                                                         {"accept": None}]}}})
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_%s" % "INPUT",
                                                "expr": [{"match": {"left": {"meta": {"key": "iifname"}},
                                                                    "op": "==",
                                                                    "right": "lo"}},
                                                         {"accept": None}]}}})
        for dispatch_suffix in ["POLICIES_pre", "ZONES_SOURCE", "ZONES", "POLICIES_post"] if self._fw._allow_zone_drifting else ["POLICIES_pre", "ZONES", "POLICIES_post"]:
            default_rules.append({"add": {"chain": {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "name": "filter_%s_%s" % ("INPUT", dispatch_suffix)}}})
            default_rules.append({"add": {"rule":  {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "chain": "filter_%s" % "INPUT",
                                                    "expr": [{"jump": {"target": "filter_%s_%s" % ("INPUT", dispatch_suffix)}}]}}})
        if log_denied != "off":
            default_rules.append({"add": {"rule":  {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "chain": "filter_%s" % "INPUT",
                                                    "expr": [{"match": {"left": {"ct": {"key": "state"}},
                                                                        "op": "in",
                                                                        "right": {"set": ["invalid"]}}},
                                                             self._pkttype_match_fragment(log_denied),
                                                             {"log": {"prefix": "STATE_INVALID_DROP: "}}]}}})
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_%s" % "INPUT",
                                                "expr": [{"match": {"left": {"ct": {"key": "state"}},
                                                                    "op": "in",
                                                                    "right": {"set": ["invalid"]}}},
                                                         {"drop": None}]}}})
        if log_denied != "off":
            default_rules.append({"add": {"rule":  {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "chain": "filter_%s" % "INPUT",
                                                    "expr": [self._pkttype_match_fragment(log_denied),
                                                             {"log": {"prefix": "FINAL_REJECT: "}}]}}})
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_%s" % "INPUT",
                                                "expr": [{"reject": {"type": "icmpx", "expr": "admin-prohibited"}}]}}})

        # filter, FORWARD
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_%s" % "FORWARD",
                                                "expr": [{"match": {"left": {"ct": {"key": "state"}},
                                                                    "op": "in",
                                                                    "right": {"set": ["established", "related"]}}},
                                                         {"accept": None}]}}})
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_%s" % "FORWARD",
                                                "expr": [{"match": {"left": {"ct": {"key": "status"}},
                                                                    "op": "in",
                                                                    "right": "dnat"}},
                                                         {"accept": None}]}}})
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_%s" % "FORWARD",
                                                "expr": [{"match": {"left": {"meta": {"key": "iifname"}},
                                                                    "op": "==",
                                                                    "right": "lo"}},
                                                         {"accept": None}]}}})
        for dispatch_suffix in ["POLICIES_pre"]:
            default_rules.append({"add": {"chain": {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "name": "filter_%s_%s" % ("FORWARD", dispatch_suffix)}}})
            default_rules.append({"add": {"rule":  {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "chain": "filter_%s" % "FORWARD",
                                                    "expr": [{"jump": {"target": "filter_%s_%s" % ("FORWARD", dispatch_suffix)}}]}}})
        for direction in ["IN", "OUT"]:
            for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]:
                default_rules.append({"add": {"chain": {"family": "inet",
                                                        "table": TABLE_NAME,
                                                        "name": "filter_%s_%s_%s" % ("FORWARD", direction, dispatch_suffix)}}})
                default_rules.append({"add": {"rule":  {"family": "inet",
                                                        "table": TABLE_NAME,
                                                        "chain": "filter_%s" % "FORWARD",
                                                        "expr": [{"jump": {"target": "filter_%s_%s_%s" % ("FORWARD", direction, dispatch_suffix)}}]}}})
        for dispatch_suffix in ["POLICIES_post"]:
            default_rules.append({"add": {"chain": {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "name": "filter_%s_%s" % ("FORWARD", dispatch_suffix)}}})
            default_rules.append({"add": {"rule":  {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "chain": "filter_%s" % "FORWARD",
                                                    "expr": [{"jump": {"target": "filter_%s_%s" % ("FORWARD", dispatch_suffix)}}]}}})
        if log_denied != "off":
            default_rules.append({"add": {"rule":  {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "chain": "filter_%s" % "FORWARD",
                                                    "expr": [{"match": {"left": {"ct": {"key": "state"}},
                                                                        "op": "in",
                                                                        "right": {"set": ["invalid"]}}},
                                                             self._pkttype_match_fragment(log_denied),
                                                             {"log": {"prefix": "STATE_INVALID_DROP: "}}]}}})
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_%s" % "FORWARD",
                                                "expr": [{"match": {"left": {"ct": {"key": "state"}},
                                                                    "op": "in",
                                                                    "right": {"set": ["invalid"]}}},
                                                         {"drop": None}]}}})
        if log_denied != "off":
            default_rules.append({"add": {"rule":  {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "chain": "filter_%s" % "FORWARD",
                                                    "expr": [self._pkttype_match_fragment(log_denied),
                                                             {"log": {"prefix": "FINAL_REJECT: "}}]}}})
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_%s" % "FORWARD",
                                                "expr": [{"reject": {"type": "icmpx", "expr": "admin-prohibited"}}]}}})

        # filter, OUTPUT
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_%s" % "OUTPUT",
                                                "expr": [{"match": {"left": {"ct": {"key": "state"}},
                                                                    "op": "in",
                                                                    "right": {"set": ["established", "related"]}}},
                                                         {"accept": None}]}}})
        default_rules.append({"add": {"rule":  {"family": "inet",
                                                "table": TABLE_NAME,
                                                "chain": "filter_OUTPUT",
                                                "expr": [{"match": {"left": {"meta": {"key": "oifname"}},
                                                          "op": "==",
                                                          "right": "lo"}},
                                                         {"accept": None}]}}})
        for dispatch_suffix in ["POLICIES_pre"]:
            default_rules.append({"add": {"chain": {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "name": "filter_%s_%s" % ("OUTPUT", dispatch_suffix)}}})
            default_rules.append({"add": {"rule":  {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "chain": "filter_%s" % "OUTPUT",
                                                    "expr": [{"jump": {"target": "filter_%s_%s" % ("OUTPUT", dispatch_suffix)}}]}}})
        for dispatch_suffix in ["POLICIES_post"]:
            default_rules.append({"add": {"chain": {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "name": "filter_%s_%s" % ("OUTPUT", dispatch_suffix)}}})
            default_rules.append({"add": {"rule":  {"family": "inet",
                                                    "table": TABLE_NAME,
                                                    "chain": "filter_%s" % "OUTPUT",
                                                    "expr": [{"jump": {"target": "filter_%s_%s" % ("OUTPUT", dispatch_suffix)}}]}}})

        return default_rules

    def get_zone_table_chains(self, table):
        if table == "filter":
            return ["INPUT", "FORWARD_IN", "FORWARD_OUT"]
        if table == "mangle":
            return ["PREROUTING"]
        if table == "nat":
            return ["PREROUTING", "POSTROUTING"]

        return []

    def build_policy_ingress_egress_rules(self, enable, policy, table, chain,
                                          ingress_interfaces, egress_interfaces,
                                          ingress_sources, egress_sources,
                                          family="inet"):
        # nat tables need to use ip/ip6 family
        if table == "nat" and family == "inet":
            rules = []
            rules.extend(self.build_policy_ingress_egress_rules(enable, policy, table, chain,
                                          ingress_interfaces, egress_interfaces,
                                          ingress_sources, egress_sources,
                                          family="ip"))
            rules.extend(self.build_policy_ingress_egress_rules(enable, policy, table, chain,
                                          ingress_interfaces, egress_interfaces,
                                          ingress_sources, egress_sources,
                                          family="ip6"))
            return rules

        p_obj = self._fw.policy.get_policy(policy)
        chain_suffix = "pre" if p_obj.priority < 0 else "post"
        isSNAT = True if (table == "nat" and chain == "POSTROUTING") else False
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX, isSNAT)

        ingress_fragments = []
        egress_fragments = []
        if ingress_interfaces:
            ingress_fragments.append({"match": {"left": {"meta": {"key": "iifname"}},
                                                "op": "==",
                                                "right": {"set": list(ingress_interfaces)}}})
        if egress_interfaces:
            egress_fragments.append({"match": {"left": {"meta": {"key": "oifname"}},
                                               "op": "==",
                                               "right": {"set": list(egress_interfaces)}}})
        ipv_to_family = {"ipv4": "ip", "ipv6": "ip6"}
        if ingress_sources:
            for src in ingress_sources:
                # skip if this source doesn't apply to the current family.
                if table == "nat":
                    ipv = self._fw.zone.check_source(src)
                    if ipv in ipv_to_family and family != ipv_to_family[ipv]:
                        continue

                ingress_fragments.append(self._rule_addr_fragment("saddr", src))
        if egress_sources:
            for dst in egress_sources:
                # skip if this source doesn't apply to the current family.
                if table == "nat":
                    ipv = self._fw.zone.check_source(dst)
                    if ipv in ipv_to_family and family != ipv_to_family[ipv]:
                        continue

                egress_fragments.append(self._rule_addr_fragment("daddr", dst))

        def _generate_policy_dispatch_rule(ingress_fragment, egress_fragment):
            expr_fragments = []
            if ingress_fragment:
                expr_fragments.append(ingress_fragment)
            if egress_fragment:
                expr_fragments.append(egress_fragment)
            expr_fragments.append({"jump": {"target": "%s_%s" % (table, _policy)}})

            rule = {"family": family,
                    "table": TABLE_NAME,
                    "chain": "%s_%s_POLICIES_%s" % (table, chain, chain_suffix),
                    "expr": expr_fragments}
            rule.update(self._policy_priority_fragment(p_obj))

            if enable:
                return {"add": {"rule": rule}}
            else:
                return {"delete": {"rule": rule}}

        rules = []
        if ingress_fragments: # zone --> [zone, ANY, HOST]
            for ingress_fragment in ingress_fragments:
                if egress_fragments:
                    # zone --> zone
                    for egress_fragment in egress_fragments:
                        rules.append(_generate_policy_dispatch_rule(ingress_fragment, egress_fragment))
                elif table =="nat" and egress_sources:
                    # if the egress source is not for the current family (there
                    # are no egress fragments), then avoid creating an invalid
                    # catch all rule.
                    pass
                else:
                    # zone --> [ANY, HOST]
                    rules.append(_generate_policy_dispatch_rule(ingress_fragment, None))
        elif table =="nat" and ingress_sources:
            # if the ingress source is not for the current family (there are no
            # ingress fragments), then avoid creating an invalid catch all
            # rule.
            pass
        else: # [ANY, HOST] --> [zone, ANY, HOST]
            if egress_fragments:
                # [ANY, HOST] --> zone
                for egress_fragment in egress_fragments:
                    rules.append(_generate_policy_dispatch_rule(None, egress_fragment))
            elif table =="nat" and egress_sources:
                # if the egress source is not for the current family (there are
                # no egress fragments), then avoid creating an invalid catch
                # all rule.
                pass
            else:
                # [ANY, HOST] --> [ANY, HOST]
                rules.append(_generate_policy_dispatch_rule(None, None))

        return rules

    def build_zone_source_interface_rules(self, enable, zone, policy, interface,
                                          table, chain, append=False,
                                          family="inet"):
        # nat tables needs to use ip/ip6 family
        if table == "nat" and family == "inet":
            rules = []
            rules.extend(self.build_zone_source_interface_rules(enable, zone, policy,
                            interface, table, chain, append, "ip"))
            rules.extend(self.build_zone_source_interface_rules(enable, zone, policy,
                            interface, table, chain, append, "ip6"))
            return rules

        isSNAT = True if (table == "nat" and chain == "POSTROUTING") else False
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX, isSNAT=isSNAT)
        opt = {
            "PREROUTING": "iifname",
            "POSTROUTING": "oifname",
            "INPUT": "iifname",
            "FORWARD_IN": "iifname",
            "FORWARD_OUT": "oifname",
            "OUTPUT": "oifname",
        }[chain]

        if interface[len(interface)-1] == "+":
            interface = interface[:len(interface)-1] + "*"

        action = "goto"

        if interface == "*":
            expr_fragments = [{action: {"target": "%s_%s" % (table, _policy)}}]
        else:
            expr_fragments = [{"match": {"left": {"meta": {"key": opt}},
                                         "op": "==",
                                         "right": interface}},
                              {action: {"target": "%s_%s" % (table, _policy)}}]

        if enable and not append:
            verb = "insert"
            rule = {"family": family,
                    "table": TABLE_NAME,
                    "chain": "%s_%s_ZONES" % (table, chain),
                    "expr": expr_fragments}
            rule.update(self._zone_interface_fragment())
        elif enable:
            verb = "add"
            rule = {"family": family,
                    "table": TABLE_NAME,
                    "chain": "%s_%s_ZONES" % (table, chain),
                    "expr": expr_fragments}
        else:
            verb = "delete"
            rule = {"family": family,
                    "table": TABLE_NAME,
                    "chain": "%s_%s_ZONES" % (table, chain),
                    "expr": expr_fragments}
            if not append:
                rule.update(self._zone_interface_fragment())

        return [{verb: {"rule": rule}}]

    def build_zone_source_address_rules(self, enable, zone, policy,
                                        address, table, chain, family="inet"):
        # nat tables needs to use ip/ip6 family
        if table == "nat" and family == "inet":
            rules = []
            if address.startswith("ipset:"):
                ipset_family = self._set_get_family(address[len("ipset:"):])
            else:
                ipset_family = None

            if check_address("ipv4", address) or check_mac(address) or ipset_family == "ip":
                rules.extend(self.build_zone_source_address_rules(enable, zone, policy,
                                    address, table, chain, "ip"))
            if check_address("ipv6", address) or check_mac(address) or ipset_family == "ip6":
                rules.extend(self.build_zone_source_address_rules(enable, zone, policy,
                                    address, table, chain, "ip6"))
            return rules

        isSNAT = True if (table == "nat" and chain == "POSTROUTING") else False
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX, isSNAT=isSNAT)
        add_del = { True: "insert", False: "delete" }[enable]

        opt = {
            "PREROUTING": "saddr",
            "POSTROUTING": "daddr",
            "INPUT": "saddr",
            "FORWARD_IN": "saddr",
            "FORWARD_OUT": "daddr",
            "OUTPUT": "daddr",
        }[chain]

        if self._fw._allow_zone_drifting:
            zone_dispatch_chain = "%s_%s_ZONES_SOURCE" % (table, chain)
        else:
            zone_dispatch_chain = "%s_%s_ZONES" % (table, chain)

        action = "goto"

        rule = {"family": family,
                "table": TABLE_NAME,
                "chain": zone_dispatch_chain,
                "expr": [self._rule_addr_fragment(opt, address),
                         {action: {"target": "%s_%s" % (table, _policy)}}]}
        rule.update(self._zone_source_fragment(zone, address))
        return [{add_del: {"rule": rule}}]

    def build_policy_chain_rules(self, enable, policy, table, chain, family="inet"):
        # nat tables needs to use ip/ip6 family
        if table == "nat" and family == "inet":
            rules = []
            rules.extend(self.build_policy_chain_rules(enable, policy, table, chain, "ip"))
            rules.extend(self.build_policy_chain_rules(enable, policy, table, chain, "ip6"))
            return rules

        add_del = { True: "add", False: "delete" }[enable]
        isSNAT = True if (table == "nat" and chain == "POSTROUTING") else False
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX, isSNAT=isSNAT)

        rules = []
        rules.append({add_del: {"chain": {"family": family,
                                          "table": TABLE_NAME,
                                          "name": "%s_%s" % (table, _policy)}}})
        for chain_suffix in ["pre", "log", "deny", "allow", "post"]:
            rules.append({add_del: {"chain": {"family": family,
                                              "table": TABLE_NAME,
                                              "name": "%s_%s_%s" % (table, _policy, chain_suffix)}}})

        for chain_suffix in ["pre", "log", "deny", "allow", "post"]:
            rules.append({add_del: {"rule": {"family": family,
                                             "table": TABLE_NAME,
                                             "chain": "%s_%s" % (table, _policy),
                                             "expr": [{"jump": {"target": "%s_%s_%s" % (table, _policy, chain_suffix)}}]}}})

        target = self._fw.policy._policies[policy].target

        if self._fw.get_log_denied() != "off":
            if table == "filter":
                if target in ["REJECT", "%%REJECT%%", "DROP"]:
                    log_suffix = target
                    if target == "%%REJECT%%":
                        log_suffix = "REJECT"
                    rules.append({add_del: {"rule": {"family": family,
                                                     "table": TABLE_NAME,
                                                     "chain": "%s_%s" % (table, _policy),
                                                     "expr": [self._pkttype_match_fragment(self._fw.get_log_denied()),
                                                              {"log": {"prefix": "\"filter_%s_%s: \"" % (_policy, log_suffix)}}]}}})

        if table == "filter" and \
           target in ["ACCEPT", "REJECT", "%%REJECT%%", "DROP"]:
            if target in ["%%REJECT%%", "REJECT"]:
                target_fragment = self._reject_fragment()
            else:
                target_fragment = {target.lower(): None}
            rules.append({add_del: {"rule": {"family": family,
                                             "table": TABLE_NAME,
                                             "chain": "%s_%s" % (table, _policy),
                                             "expr": [target_fragment]}}})

        if not enable:
            rules.reverse()

        return rules

    def _pkttype_match_fragment(self, pkttype):
        if pkttype == "all":
            return {}
        elif pkttype in ["unicast", "broadcast", "multicast"]:
            return {"match": {"left": {"meta": {"key": "pkttype"}},
                               "op": "==",
                               "right": pkttype}}

        raise FirewallError(INVALID_RULE, "Invalid pkttype \"%s\"", pkttype)

    def _reject_types_fragment(self, reject_type):
        frags = {
            # REJECT_TYPES              : <nft reject rule fragment>
            "icmp-host-prohibited"      : {"reject": {"type": "icmp", "expr": "host-prohibited"}},
            "host-prohib"               : {"reject": {"type": "icmp", "expr": "host-prohibited"}},
            "icmp-net-prohibited"       : {"reject": {"type": "icmp", "expr": "net-prohibited"}},
            "net-prohib"                : {"reject": {"type": "icmp", "expr": "net-prohibited"}},
            "icmp-admin-prohibited"     : {"reject": {"type": "icmp", "expr": "admin-prohibited"}},
            "admin-prohib"              : {"reject": {"type": "icmp", "expr": "admin-prohibited"}},
            "icmp6-adm-prohibited"      : {"reject": {"type": "icmpv6", "expr": "admin-prohibited"}},
            "adm-prohibited"            : {"reject": {"type": "icmpv6", "expr": "admin-prohibited"}},

            "icmp-net-unreachable"      : {"reject": {"type": "icmp", "expr": "net-unreachable"}},
            "net-unreach"               : {"reject": {"type": "icmp", "expr": "net-unreachable"}},
            "icmp-host-unreachable"     : {"reject": {"type": "icmp", "expr": "host-unreachable"}},
            "host-unreach"              : {"reject": {"type": "icmp", "expr": "host-unreachable"}},
            "icmp-port-unreachable"     : {"reject": {"type": "icmp", "expr": "port-unreachable"}},
            "icmp6-port-unreachable"    : {"reject": {"type": "icmpv6", "expr": "port-unreachable"}},
            "port-unreach"              : {"reject": {"type": "icmpx", "expr": "port-unreachable"}},
            "icmp-proto-unreachable"    : {"reject": {"type": "icmp", "expr": "prot-unreachable"}},
            "proto-unreach"             : {"reject": {"type": "icmp", "expr": "prot-unreachable"}},
            "icmp6-addr-unreachable"    : {"reject": {"type": "icmpv6", "expr": "addr-unreachable"}},
            "addr-unreach"              : {"reject": {"type": "icmpv6", "expr": "addr-unreachable"}},

            "icmp6-no-route"            : {"reject": {"type": "icmpv6", "expr": "no-route"}},
            "no-route"                  : {"reject": {"type": "icmpv6", "expr": "no-route"}},

            "tcp-reset"                 : {"reject": {"type": "tcp reset"}},
            "tcp-rst"                   : {"reject": {"type": "tcp reset"}},
        }
        return frags[reject_type]

    def _reject_fragment(self):
        return {"reject": {"type": "icmpx",
                           "expr": "admin-prohibited"}}

    def _icmp_match_fragment(self):
        return {"match": {"left": {"meta": {"key": "l4proto"}},
                          "op": "==",
                          "right": {"set": ["icmp", "icmpv6"]}}}

    def _rich_rule_limit_fragment(self, limit):
        if not limit:
            return {}

        rich_to_nft = {
            "s" : "second",
            "m" : "minute",
            "h" : "hour",
            "d" : "day",
        }

        rate, duration = limit.value_parse()

        d = {
            "rate": rate,
            "per": rich_to_nft[duration],
        }

        burst = limit.burst_parse()
        if burst is not None:
            d["burst"] = burst

        return {"limit": d}

    def _rich_rule_chain_suffix(self, rich_rule):
        if type(rich_rule.element) in [Rich_Masquerade, Rich_ForwardPort, Rich_IcmpBlock]:
            # These are special and don't have an explicit action
            pass
        elif rich_rule.action:
            if type(rich_rule.action) not in [Rich_Accept, Rich_Reject, Rich_Drop, Rich_Mark]:
                raise FirewallError(INVALID_RULE, "Unknown action %s" % type(rich_rule.action))
        else:
            raise FirewallError(INVALID_RULE, "No rule action specified.")

        if rich_rule.priority == 0:
            if type(rich_rule.element) in [Rich_Masquerade, Rich_ForwardPort] or \
               type(rich_rule.action) in [Rich_Accept, Rich_Mark]:
                return "allow"
            elif type(rich_rule.element) in [Rich_IcmpBlock] or \
                 type(rich_rule.action) in [Rich_Reject, Rich_Drop]:
                return "deny"
        elif rich_rule.priority < 0:
            return "pre"
        else:
            return "post"

    def _rich_rule_chain_suffix_from_log(self, rich_rule):
        if not rich_rule.log and not rich_rule.audit:
            raise FirewallError(INVALID_RULE, "Not log or audit")

        if rich_rule.priority == 0:
            return "log"
        elif rich_rule.priority < 0:
            return "pre"
        else:
            return "post"

    def _zone_interface_fragment(self):
        return {"%%ZONE_INTERFACE%%": None}

    def _zone_source_fragment(self, zone, address):
        if check_single_address("ipv6", address):
            address = normalizeIP6(address)
        elif check_address("ipv6", address):
            addr_split = address.split("/")
            address = normalizeIP6(addr_split[0]) + "/" + addr_split[1]
        return {"%%ZONE_SOURCE%%": {"zone": zone, "address": address}}

    def _policy_priority_fragment(self, policy):
        return {"%%POLICY_PRIORITY%%": policy.priority}

    def _rich_rule_priority_fragment(self, rich_rule):
        if not rich_rule or rich_rule.priority == 0:
            return {}
        return {"%%RICH_RULE_PRIORITY%%": rich_rule.priority}

    def _rich_rule_log(self, policy, rich_rule, enable, table, expr_fragments):
        if not rich_rule.log:
            return {}

        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        add_del = { True: "add", False: "delete" }[enable]

        chain_suffix = self._rich_rule_chain_suffix_from_log(rich_rule)

        log_options = {}
        if rich_rule.log.prefix:
            log_options["prefix"] = "%s" % rich_rule.log.prefix
        if rich_rule.log.level:
            level = "warn" if "warning" == rich_rule.log.level else rich_rule.log.level
            log_options["level"] = "%s" % level

        rule = {"family": "inet",
                "table": TABLE_NAME,
                "chain": "%s_%s_%s" % (table, _policy, chain_suffix),
                "expr": expr_fragments +
                        [self._rich_rule_limit_fragment(rich_rule.log.limit),
                         {"log": log_options}]}
        rule.update(self._rich_rule_priority_fragment(rich_rule))
        return {add_del: {"rule": rule}}

    def _rich_rule_audit(self, policy, rich_rule, enable, table, expr_fragments):
        if not rich_rule.audit:
            return {}

        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        add_del = { True: "add", False: "delete" }[enable]

        chain_suffix = self._rich_rule_chain_suffix_from_log(rich_rule)
        rule = {"family": "inet",
                "table": TABLE_NAME,
                "chain": "%s_%s_%s" % (table, _policy, chain_suffix),
                "expr": expr_fragments +
                        [self._rich_rule_limit_fragment(rich_rule.audit.limit),
                         {"log": {"level": "audit"}}]}
        rule.update(self._rich_rule_priority_fragment(rich_rule))
        return {add_del: {"rule": rule}}

    def _rich_rule_action(self, policy, rich_rule, enable, table, expr_fragments):
        if not rich_rule.action:
            return {}

        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        add_del = { True: "add", False: "delete" }[enable]

        chain_suffix = self._rich_rule_chain_suffix(rich_rule)
        chain = "%s_%s_%s" % (table, _policy, chain_suffix)
        if type(rich_rule.action) == Rich_Accept:
            rule_action = {"accept": None}
        elif type(rich_rule.action) == Rich_Reject:
            if rich_rule.action.type:
                rule_action = self._reject_types_fragment(rich_rule.action.type)
            else:
                rule_action = {"reject": None}
        elif type(rich_rule.action) ==  Rich_Drop:
            rule_action = {"drop": None}
        elif type(rich_rule.action) == Rich_Mark:
            table = "mangle"
            _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
            chain = "%s_%s_%s" % (table, _policy, chain_suffix)
            value = rich_rule.action.set.split("/")
            if len(value) > 1:
                rule_action = {"mangle": {"key": {"meta": {"key": "mark"}},
                                          "value": {"^": [{"&": [{"meta": {"key": "mark"}}, value[1]]}, value[0]]}}}
            else:
                rule_action = {"mangle": {"key": {"meta": {"key": "mark"}},
                                          "value": value[0]}}

        else:
            raise FirewallError(INVALID_RULE,
                                "Unknown action %s" % type(rich_rule.action))

        rule = {"family": "inet",
                "table": TABLE_NAME,
                "chain": chain,
                "expr": expr_fragments +
                        [self._rich_rule_limit_fragment(rich_rule.action.limit), rule_action]}
        rule.update(self._rich_rule_priority_fragment(rich_rule))
        return {add_del: {"rule": rule}}

    def _rule_addr_fragment(self, addr_field, address, invert=False):
        if address.startswith("ipset:"):
            return self._set_match_fragment(address[len("ipset:"):], True if "daddr" == addr_field else False, invert)
        else:
            if check_mac(address):
                family = "ether"
            elif check_single_address("ipv4", address):
                family = "ip"
            elif check_address("ipv4", address):
                family = "ip"
                normalized_address = ipaddress.IPv4Network(address, strict=False)
                address = {"prefix": {"addr": normalized_address.network_address.compressed, "len": normalized_address.prefixlen}}
            elif check_single_address("ipv6", address):
                family = "ip6"
                address = normalizeIP6(address)
            else:
                family = "ip6"
                addr_len = address.split("/")
                address = {"prefix": {"addr": normalizeIP6(addr_len[0]), "len": int(addr_len[1])}}

            return {"match": {"left": {"payload": {"protocol": family,
                                                   "field": addr_field}},
                              "op": "!=" if invert else "==",
                              "right": address}}

    def _rich_rule_family_fragment(self, rich_family):
        if not rich_family:
            return {}
        if rich_family not in ["ipv4", "ipv6"]:
            raise FirewallError(INVALID_RULE,
                                "Invalid family" % rich_family)

        return {"match": {"left": {"meta": {"key": "nfproto"}},
                          "op": "==",
                          "right": rich_family}}

    def _rich_rule_destination_fragment(self, rich_dest):
        if not rich_dest:
            return {}
        if rich_dest.addr:
            address = rich_dest.addr
        elif rich_dest.ipset:
            address = "ipset:" + rich_dest.ipset

        return self._rule_addr_fragment("daddr", address, invert=rich_dest.invert)

    def _rich_rule_source_fragment(self, rich_source):
        if not rich_source:
            return {}

        if rich_source.addr:
            address = rich_source.addr
        elif hasattr(rich_source, "mac") and rich_source.mac:
            address = rich_source.mac
        elif hasattr(rich_source, "ipset") and rich_source.ipset:
            address = "ipset:" + rich_source.ipset

        return self._rule_addr_fragment("saddr", address, invert=rich_source.invert)

    def _port_fragment(self, port):
        range = getPortRange(port)
        if isinstance(range, int) and range < 0:
            raise FirewallError(INVALID_PORT)
        elif len(range) == 1:
            return range[0]
        else:
            return {"range": [range[0], range[1]]}

    def build_policy_ports_rules(self, enable, policy, proto, port, destination=None, rich_rule=None):
        add_del = { True: "add", False: "delete" }[enable]
        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        expr_fragments = []
        if rich_rule:
            expr_fragments.append(self._rich_rule_family_fragment(rich_rule.family))
        if destination:
            expr_fragments.append(self._rule_addr_fragment("daddr", destination))
        if rich_rule:
            expr_fragments.append(self._rich_rule_destination_fragment(rich_rule.destination))
            expr_fragments.append(self._rich_rule_source_fragment(rich_rule.source))

        expr_fragments.append({"match": {"left": {"payload": {"protocol": proto,
                                                              "field": "dport"}},
                                         "op": "==",
                                         "right": self._port_fragment(port)}})
        if not rich_rule or type(rich_rule.action) != Rich_Mark:
            expr_fragments.append({"match": {"left": {"ct": {"key": "state"}},
                                             "op": "in",
                                             "right": {"set": ["new", "untracked"]}}})

        rules = []
        if rich_rule:
            rules.append(self._rich_rule_log(policy, rich_rule, enable, table, expr_fragments))
            rules.append(self._rich_rule_audit(policy, rich_rule, enable, table, expr_fragments))
            rules.append(self._rich_rule_action(policy, rich_rule, enable, table, expr_fragments))
        else:
            rules.append({add_del: {"rule": {"family": "inet",
                                             "table": TABLE_NAME,
                                             "chain": "%s_%s_allow" % (table, _policy),
                                             "expr": expr_fragments + [{"accept": None}]}}})

        return rules

    def build_policy_protocol_rules(self, enable, policy, protocol, destination=None, rich_rule=None):
        add_del = { True: "add", False: "delete" }[enable]
        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        expr_fragments = []
        if rich_rule:
            expr_fragments.append(self._rich_rule_family_fragment(rich_rule.family))
        if destination:
            expr_fragments.append(self._rule_addr_fragment("daddr", destination))
        if rich_rule:
            expr_fragments.append(self._rich_rule_destination_fragment(rich_rule.destination))
            expr_fragments.append(self._rich_rule_source_fragment(rich_rule.source))

        expr_fragments.append({"match": {"left": {"meta": {"key": "l4proto"}},
                                         "op": "==",
                                         "right": protocol}})
        if not rich_rule or type(rich_rule.action) != Rich_Mark:
            expr_fragments.append({"match": {"left": {"ct": {"key": "state"}},
                                             "op": "in",
                                             "right": {"set": ["new", "untracked"]}}})

        rules = []
        if rich_rule:
            rules.append(self._rich_rule_log(policy, rich_rule, enable, table, expr_fragments))
            rules.append(self._rich_rule_audit(policy, rich_rule, enable, table, expr_fragments))
            rules.append(self._rich_rule_action(policy, rich_rule, enable, table, expr_fragments))
        else:
            rules.append({add_del: {"rule": {"family": "inet",
                                             "table": TABLE_NAME,
                                             "chain": "%s_%s_allow" % (table, _policy),
                                             "expr": expr_fragments + [{"accept": None}]}}})

        return rules

    def build_policy_source_ports_rules(self, enable, policy, proto, port,
                                      destination=None, rich_rule=None):
        add_del = { True: "add", False: "delete" }[enable]
        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        expr_fragments = []
        if rich_rule:
            expr_fragments.append(self._rich_rule_family_fragment(rich_rule.family))
        if destination:
            expr_fragments.append(self._rule_addr_fragment("daddr", destination))
        if rich_rule:
            expr_fragments.append(self._rich_rule_destination_fragment(rich_rule.destination))
            expr_fragments.append(self._rich_rule_source_fragment(rich_rule.source))

        expr_fragments.append({"match": {"left": {"payload": {"protocol": proto,
                                                              "field": "sport"}},
                                         "op": "==",
                                         "right": self._port_fragment(port)}})
        if not rich_rule or type(rich_rule.action) != Rich_Mark:
            expr_fragments.append({"match": {"left": {"ct": {"key": "state"}},
                                             "op": "in",
                                             "right": {"set": ["new", "untracked"]}}})

        rules = []
        if rich_rule:
            rules.append(self._rich_rule_log(policy, rich_rule, enable, table, expr_fragments))
            rules.append(self._rich_rule_audit(policy, rich_rule, enable, table, expr_fragments))
            rules.append(self._rich_rule_action(policy, rich_rule, enable, table, expr_fragments))
        else:
            rules.append({add_del: {"rule": {"family": "inet",
                                             "table": TABLE_NAME,
                                             "chain": "%s_%s_allow" % (table, _policy),
                                             "expr": expr_fragments + [{"accept": None}]}}})

        return rules

    def build_policy_helper_ports_rules(self, enable, policy, proto, port,
                                        destination, helper_name, module_short_name):
        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
        add_del = { True: "add", False: "delete" }[enable]
        rules = []

        if enable:
            rules.append({"add": {"ct helper": {"family": "inet",
                                                "table": TABLE_NAME,
                                                "name": "helper-%s-%s" % (helper_name, proto),
                                                "type": module_short_name,
                                                "protocol": proto}}})

        expr_fragments = []
        if destination:
            expr_fragments.append(self._rule_addr_fragment("daddr", destination))
        expr_fragments.append({"match": {"left": {"payload": {"protocol": proto,
                                                              "field": "dport"}},
                                         "op": "==",
                                         "right": self._port_fragment(port)}})
        expr_fragments.append({"ct helper": "helper-%s-%s" % (helper_name, proto)})
        rules.append({add_del: {"rule": {"family": "inet",
                                         "table": TABLE_NAME,
                                         "chain": "filter_%s_allow" % (_policy),
                                         "expr": expr_fragments}}})

        return rules

    def build_zone_forward_rules(self, enable, zone, policy, table, interface=None, source=None):
        add_del = { True: "add", False: "delete" }[enable]
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        rules = []

        if interface:
            if interface[len(interface)-1] == "+":
                interface = interface[:len(interface)-1] + "*"

            expr = [{"match": {"left": {"meta": {"key": "oifname"}},
                               "op": "==",
                               "right": interface}},
                    {"accept": None}]
        else: # source
            expr = [self._rule_addr_fragment("daddr", source), {"accept": None}]

        rule = {"family": "inet",
                "table": TABLE_NAME,
                "chain": "filter_%s_allow" % (_policy),
                "expr": expr}
        rules.append({add_del: {"rule": rule}})

        return rules

    def _build_policy_masquerade_nat_rules(self, enable, policy, family, rich_rule=None):
        table = "nat"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX, isSNAT=True)

        add_del = { True: "add", False: "delete" }[enable]

        expr_fragments = []
        if rich_rule:
            expr_fragments.append(self._rich_rule_destination_fragment(rich_rule.destination))
            expr_fragments.append(self._rich_rule_source_fragment(rich_rule.source))
            chain_suffix = self._rich_rule_chain_suffix(rich_rule)
        else:
            chain_suffix = "allow"

        rule = {"family": family,
                "table": TABLE_NAME,
                "chain": "nat_%s_%s" % (_policy, chain_suffix),
                "expr": expr_fragments +
                        [{"match": {"left": {"meta": {"key": "oifname"}},
                                    "op": "!=",
                                    "right": "lo"}},
                         {"masquerade": None}]}
        rule.update(self._rich_rule_priority_fragment(rich_rule))
        return [{add_del: {"rule": rule}}]

    def build_policy_masquerade_rules(self, enable, policy, rich_rule=None):
        # nat tables needs to use ip/ip6 family
        rules = []
        if rich_rule and (rich_rule.family and rich_rule.family == "ipv6"
           or rich_rule.source and check_address("ipv6", rich_rule.source.addr)):
            rules.extend(self._build_policy_masquerade_nat_rules(enable, policy, "ip6", rich_rule))
        elif rich_rule and (rich_rule.family and rich_rule.family == "ipv4"
           or rich_rule.source and check_address("ipv4", rich_rule.source.addr)):
            rules.extend(self._build_policy_masquerade_nat_rules(enable, policy, "ip", rich_rule))
        else:
            rules.extend(self._build_policy_masquerade_nat_rules(enable, policy, "ip", rich_rule))

        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
        add_del = { True: "add", False: "delete" }[enable]

        expr_fragments = []
        if rich_rule:
            expr_fragments.append(self._rich_rule_destination_fragment(rich_rule.destination))
            expr_fragments.append(self._rich_rule_source_fragment(rich_rule.source))
            chain_suffix = self._rich_rule_chain_suffix(rich_rule)
        else:
            chain_suffix = "allow"

        rule = {"family": "inet",
                "table": TABLE_NAME,
                "chain": "filter_%s_%s" % (_policy, chain_suffix),
                "expr": expr_fragments +
                        [{"match": {"left": {"ct": {"key": "state"}},
                                    "op": "in",
                                    "right": {"set": ["new", "untracked"]}}},
                         {"accept": None}]}
        rule.update(self._rich_rule_priority_fragment(rich_rule))
        rules.append({add_del: {"rule": rule}})

        return rules

    def _build_policy_forward_port_nat_rules(self, enable, policy, port, protocol,
                                           toaddr, toport, family,
                                           rich_rule=None):
        table = "nat"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
        add_del = { True: "add", False: "delete" }[enable]

        expr_fragments = []
        if rich_rule:
            expr_fragments.append(self._rich_rule_destination_fragment(rich_rule.destination))
            expr_fragments.append(self._rich_rule_source_fragment(rich_rule.source))
            chain_suffix = self._rich_rule_chain_suffix(rich_rule)
        else:
            chain_suffix = "allow"

        expr_fragments.append({"match": {"left": {"payload": {"protocol": protocol,
                                                              "field": "dport"}},
                                         "op": "==",
                                         "right": self._port_fragment(port)}})

        if toaddr:
            if check_single_address("ipv6", toaddr):
                toaddr = normalizeIP6(toaddr)
            if toport and toport != "":
                expr_fragments.append({"dnat": {"addr": toaddr, "port": self._port_fragment(toport)}})
            else:
                expr_fragments.append({"dnat": {"addr": toaddr}})
        else:
            expr_fragments.append({"redirect": {"port": self._port_fragment(toport)}})

        rule = {"family": family,
                "table": TABLE_NAME,
                "chain": "nat_%s_%s" % (_policy, chain_suffix),
                "expr": expr_fragments}
        rule.update(self._rich_rule_priority_fragment(rich_rule))
        return [{add_del: {"rule": rule}}]

    def build_policy_forward_port_rules(self, enable, policy, port,
                                      protocol, toport, toaddr, rich_rule=None):
        rules = []
        if rich_rule and (rich_rule.family and rich_rule.family == "ipv6"
           or toaddr and check_single_address("ipv6", toaddr)):
            rules.extend(self._build_policy_forward_port_nat_rules(enable, policy,
                                port, protocol, toaddr, toport, "ip6", rich_rule))
        elif rich_rule and (rich_rule.family and rich_rule.family == "ipv4"
           or toaddr and check_single_address("ipv4", toaddr)):
            rules.extend(self._build_policy_forward_port_nat_rules(enable, policy,
                                port, protocol, toaddr, toport, "ip", rich_rule))
        else:
            if toaddr and check_single_address("ipv6", toaddr):
                rules.extend(self._build_policy_forward_port_nat_rules(enable, policy,
                                    port, protocol, toaddr, toport, "ip6", rich_rule))
            else:
                rules.extend(self._build_policy_forward_port_nat_rules(enable, policy,
                                    port, protocol, toaddr, toport, "ip", rich_rule))

        return rules

    def _icmp_types_to_nft_fragments(self, ipv, icmp_type):
        if icmp_type in ICMP_TYPES_FRAGMENTS[ipv]:
            return ICMP_TYPES_FRAGMENTS[ipv][icmp_type]
        else:
            raise FirewallError(INVALID_ICMPTYPE,
                                "ICMP type '%s' not supported by %s for %s" % (icmp_type, self.name, ipv))

    def build_policy_icmp_block_rules(self, enable, policy, ict, rich_rule=None):
        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
        add_del = { True: "add", False: "delete" }[enable]

        if rich_rule and rich_rule.ipvs:
            ipvs = rich_rule.ipvs
        elif ict.destination:
            ipvs = []
            if "ipv4" in ict.destination:
                ipvs.append("ipv4")
            if "ipv6" in ict.destination:
                ipvs.append("ipv6")
        else:
            ipvs = ["ipv4", "ipv6"]

        rules = []
        for ipv in ipvs:
            if self._fw.policy.query_icmp_block_inversion(policy):
                final_chain = "%s_%s_allow" % (table, _policy)
                target_fragment = {"accept": None}
            else:
                final_chain = "%s_%s_deny" % (table, _policy)
                target_fragment = self._reject_fragment()

            expr_fragments = []
            if rich_rule:
                expr_fragments.append(self._rich_rule_family_fragment(rich_rule.family))
                expr_fragments.append(self._rich_rule_destination_fragment(rich_rule.destination))
                expr_fragments.append(self._rich_rule_source_fragment(rich_rule.source))
            expr_fragments.extend(self._icmp_types_to_nft_fragments(ipv, ict.name))

            if rich_rule:
                rules.append(self._rich_rule_log(policy, rich_rule, enable, table, expr_fragments))
                rules.append(self._rich_rule_audit(policy, rich_rule, enable, table, expr_fragments))
                if rich_rule.action:
                    rules.append(self._rich_rule_action(policy, rich_rule, enable, table, expr_fragments))
                else:
                    chain_suffix = self._rich_rule_chain_suffix(rich_rule)
                    rule = {"family": "inet",
                            "table": TABLE_NAME,
                            "chain": "%s_%s_%s" % (table, _policy, chain_suffix),
                            "expr": expr_fragments + [self._reject_fragment()]}
                    rule.update(self._rich_rule_priority_fragment(rich_rule))
                    rules.append({add_del: {"rule": rule}})
            else:
                if self._fw.get_log_denied() != "off" and not self._fw.policy.query_icmp_block_inversion(policy):
                    rules.append({add_del: {"rule": {"family": "inet",
                                                     "table": TABLE_NAME,
                                                     "chain": final_chain,
                                                     "expr": (expr_fragments +
                                                              [self._pkttype_match_fragment(self._fw.get_log_denied()),
                                                               {"log": {"prefix": "\"%s_%s_ICMP_BLOCK: \"" % (table, policy)}}])}}})
                rules.append({add_del: {"rule": {"family": "inet",
                                                 "table": TABLE_NAME,
                                                 "chain": final_chain,
                                                 "expr": expr_fragments + [target_fragment]}}})

        return rules

    def build_policy_icmp_block_inversion_rules(self, enable, policy):
        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
        rules = []
        add_del = { True: "add", False: "delete" }[enable]

        if self._fw.policy.query_icmp_block_inversion(policy):
            target_fragment = self._reject_fragment()
        else:
            target_fragment = {"accept": None}

        # WARN: The "index" used here must be kept in sync with
        # build_policy_chain_rules()
        #
        rules.append({add_del: {"rule": {"family": "inet",
                                         "table": TABLE_NAME,
                                         "chain": "%s_%s" % (table, _policy),
                                         "index": 4,
                                         "expr": [self._icmp_match_fragment(),
                                                  target_fragment]}}})

        if self._fw.get_log_denied() != "off" and self._fw.policy.query_icmp_block_inversion(policy):
            rules.append({add_del: {"rule": {"family": "inet",
                                             "table": TABLE_NAME,
                                             "chain": "%s_%s" % (table, _policy),
                                             "index": 4,
                                             "expr": [self._icmp_match_fragment(),
                                                      self._pkttype_match_fragment(self._fw.get_log_denied()),
                                                      {"log": {"prefix": "%s_%s_ICMP_BLOCK: " % (table, policy)}}]}}})
        return rules

    def build_rpfilter_rules(self, log_denied=False):
        rules = []
        expr_fragments = [{"match": {"left": {"meta": {"key": "nfproto"}},
                                     "op": "==",
                                     "right": "ipv6"}},
                          {"match": {"left": {"fib": {"flags": ["saddr", "iif", "mark"],
                                                      "result": "oif"}},
                                     "op": "==",
                                     "right": False}}]
        if log_denied != "off":
            expr_fragments.append({"log": {"prefix": "rpfilter_DROP: "}})
        expr_fragments.append({"drop": None})

        rules.append({"insert": {"rule": {"family": "inet",
                                          "table": TABLE_NAME,
                                          "chain": "filter_PREROUTING",
                                          "expr": expr_fragments}}})
        # RHBZ#1058505, RHBZ#1575431 (bug in kernel 4.16-4.17)
        rules.append({"insert": {"rule": {"family": "inet",
                                          "table": TABLE_NAME,
                                          "chain": "filter_PREROUTING",
                                          "expr": [{"match": {"left": {"payload": {"protocol": "icmpv6",
                                                                                   "field": "type"}},
                                                              "op": "==",
                                                              "right": {"set": ["nd-router-advert", "nd-neighbor-solicit"]}}},
                                                   {"accept": None}]}}})
        return rules

    def build_rfc3964_ipv4_rules(self):
        daddr_set = ["::0.0.0.0/96", # IPv4 compatible
                     "::ffff:0.0.0.0/96", # IPv4 mapped
                     "2002:0000::/24", # 0.0.0.0/8 (the system has no address assigned yet)
                     "2002:0a00::/24", # 10.0.0.0/8 (private)
                     "2002:7f00::/24", # 127.0.0.0/8 (loopback)
                     "2002:ac10::/28", # 172.16.0.0/12 (private)
                     "2002:c0a8::/32", # 192.168.0.0/16 (private)
                     "2002:a9fe::/32", # 169.254.0.0/16 (IANA Assigned DHCP link-local)
                     "2002:e000::/19", # 224.0.0.0/4 (multicast), 240.0.0.0/4 (reserved and broadcast)
                     ]
        daddr_set = [{"prefix": {"addr": x.split("/")[0], "len": int(x.split("/")[1])}} for x in daddr_set]

        expr_fragments = [{"match": {"left": {"payload": {"protocol": "ip6",
                                                          "field": "daddr"}},
                                     "op": "==",
                                     "right": {"set": daddr_set}}}]
        if self._fw._log_denied in ["unicast", "all"]:
            expr_fragments.append({"log": {"prefix": "RFC3964_IPv4_REJECT: "}})
        expr_fragments.append(self._reject_types_fragment("addr-unreach"))

        rules = []
        # WARN: index must be kept in sync with build_default_rules()
        rules.append({"add": {"rule": {"family": "inet",
                                       "table": TABLE_NAME,
                                       "chain": "filter_OUTPUT",
                                       "index": 1,
                                       "expr": expr_fragments}}})
        rules.append({"add": {"rule": {"family": "inet",
                                       "table": TABLE_NAME,
                                       "chain": "filter_FORWARD",
                                       "index": 2,
                                       "expr": expr_fragments}}})
        return rules

    def build_policy_rich_source_destination_rules(self, enable, policy, rich_rule):
        table = "filter"

        expr_fragments = []
        expr_fragments.append(self._rich_rule_family_fragment(rich_rule.family))
        expr_fragments.append(self._rich_rule_destination_fragment(rich_rule.destination))
        expr_fragments.append(self._rich_rule_source_fragment(rich_rule.source))

        rules = []
        rules.append(self._rich_rule_log(policy, rich_rule, enable, table, expr_fragments))
        rules.append(self._rich_rule_audit(policy, rich_rule, enable, table, expr_fragments))
        rules.append(self._rich_rule_action(policy, rich_rule, enable, table, expr_fragments))

        return rules

    def is_ipv_supported(self, ipv):
        if ipv in ["ipv4", "ipv6", "eb"]:
            return True
        return False

    def _set_type_list(self, ipv, type):
        ipv_addr = {
            "ipv4" : "ipv4_addr",
            "ipv6" : "ipv6_addr",
        }
        types = {
            "hash:ip" : ipv_addr[ipv],
            "hash:ip,port" : [ipv_addr[ipv], "inet_proto", "inet_service"],
            "hash:ip,port,ip" : [ipv_addr[ipv], "inet_proto", "inet_service", ipv_addr[ipv]],
            "hash:ip,port,net" : [ipv_addr[ipv], "inet_proto", "inet_service", ipv_addr[ipv]],
            "hash:ip,mark" : [ipv_addr[ipv], "mark"],

            "hash:net" : ipv_addr[ipv],
            "hash:net,net" : [ipv_addr[ipv], ipv_addr[ipv]],
            "hash:net,port" : [ipv_addr[ipv], "inet_proto", "inet_service"],
            "hash:net,port,net" : [ipv_addr[ipv], "inet_proto", "inet_service", ipv_addr[ipv]],
            "hash:net,iface" : [ipv_addr[ipv], "ifname"],

            "hash:mac" : "ether_addr",
        }
        if type in types:
            return types[type]
        else:
            raise FirewallError(INVALID_TYPE,
                                "ipset type name '%s' is not valid" % type)

    def build_set_create_rules(self, name, type, options=None):
        if options and "family" in options and options["family"] == "inet6":
            ipv = "ipv6"
        else:
            ipv = "ipv4"

        set_dict = {"table": TABLE_NAME,
                    "name": name,
                    "type": self._set_type_list(ipv, type)}

        # Some types need the interval flag
        for t in type.split(":")[1].split(","):
            if t in ["ip", "net", "port"]:
                set_dict["flags"] = ["interval"]
                break

        if options:
            if "timeout" in options:
                set_dict["timeout"] = options["timeout"]
            if "maxelem" in options:
                set_dict["size"] = options["maxelem"]

        rules = []
        for family in ["inet", "ip", "ip6"]:
            rule_dict = {"family": family}
            rule_dict.update(set_dict)
            rules.append({"add": {"set": rule_dict}})

        return rules

    def set_create(self, name, type, options=None):
        rules = self.build_set_create_rules(name, type, options)
        self.set_rules(rules, self._fw.get_log_denied())

    def set_destroy(self, name):
        for family in ["inet", "ip", "ip6"]:
            rule = {"delete": {"set": {"family": family,
                                       "table": TABLE_NAME,
                                       "name": name}}}
            self.set_rule(rule, self._fw.get_log_denied())

    def _set_match_fragment(self, name, match_dest, invert=False):
        type_format = self._fw.ipset.get_ipset(name).type.split(":")[1].split(",")

        fragments = []
        for i in range(len(type_format)):
            if type_format[i] == "port":
                fragments.append({"meta": {"key": "l4proto"}})
                fragments.append({"payload": {"protocol": "th",
                                              "field": "dport" if match_dest else "sport"}})
            elif type_format[i] in ["ip", "net", "mac"]:
                fragments.append({"payload": {"protocol": self._set_get_family(name),
                                              "field": "daddr" if match_dest else "saddr"}})
            elif type_format[i] == "iface":
                fragments.append({"meta": {"key": "iifname" if match_dest else "oifname"}})
            elif type_format[i] == "mark":
                fragments.append({"meta": {"key": "mark"}})
            else:
                raise FirewallError("Unsupported ipset type for match fragment: %s" % (type_format[i]))

        return {"match": {"left": {"concat": fragments} if len(type_format) > 1 else fragments[0],
                          "op": "!=" if invert else "==",
                          "right": "@" + name}}

    def _set_entry_fragment(self, name, entry):
        # convert something like
        #    1.2.3.4,sctp:8080 (type hash:ip,port)
        # to
        #    ["1.2.3.4", "sctp", "8080"]
        obj = self._fw.ipset.get_ipset(name)
        type_format = obj.type.split(":")[1].split(",")
        entry_tokens = entry.split(",")
        if len(type_format) != len(entry_tokens):
            raise FirewallError(INVALID_ENTRY,
                                "Number of values does not match ipset type.")
        fragment = []
        for i in range(len(type_format)):
            if type_format[i] == "port":
                try:
                    index = entry_tokens[i].index(":")
                except ValueError:
                    # no protocol means default tcp
                    fragment.append("tcp")
                    port_str = entry_tokens[i]
                else:
                    fragment.append(entry_tokens[i][:index])
                    port_str = entry_tokens[i][index+1:]

                try:
                    index = port_str.index("-")
                except ValueError:
                    fragment.append(port_str)
                else:
                    fragment.append({"range": [port_str[:index], port_str[index+1:]]})

            elif type_format[i] in ["ip", "net"]:
                if '-' in entry_tokens[i]:
                    fragment.append({"range": entry_tokens[i].split('-') })
                else:
                    try:
                        index = entry_tokens[i].index("/")
                    except ValueError:
                        addr = entry_tokens[i]
                        if "family" in obj.options and obj.options["family"] == "inet6":
                            addr = normalizeIP6(addr)
                        fragment.append(addr)
                    else:
                        addr = entry_tokens[i][:index]
                        if "family" in obj.options and obj.options["family"] == "inet6":
                            addr = normalizeIP6(addr)
                        fragment.append({"prefix": {"addr": addr,
                                                    "len": int(entry_tokens[i][index+1:])}})
            else:
                fragment.append(entry_tokens[i])
        return [{"concat": fragment}] if len(type_format) > 1 else fragment

    def build_set_add_rules(self, name, entry):
        rules = []
        element = self._set_entry_fragment(name, entry)
        for family in ["inet", "ip", "ip6"]:
            rules.append({"add": {"element": {"family": family,
                                              "table": TABLE_NAME,
                                              "name": name,
                                              "elem": element}}})
        return rules

    def set_add(self, name, entry):
        rules = self.build_set_add_rules(name, entry)
        self.set_rules(rules, self._fw.get_log_denied())

    def set_delete(self, name, entry):
        element = self._set_entry_fragment(name, entry)
        for family in ["inet", "ip", "ip6"]:
            rule = {"delete": {"element": {"family": family,
                                           "table": TABLE_NAME,
                                           "name": name,
                                           "elem": element}}}
            self.set_rule(rule, self._fw.get_log_denied())

    def build_set_flush_rules(self, name):
        rules = []
        for family in ["inet", "ip", "ip6"]:
            rule = {"flush": {"set": {"family": family,
                                      "table": TABLE_NAME,
                                      "name": name}}}
            rules.append(rule)
        return rules

    def set_flush(self, name):
        rules = self.build_set_flush_rules(name)
        self.set_rules(rules, self._fw.get_log_denied())

    def _set_get_family(self, name):
        ipset = self._fw.ipset.get_ipset(name)

        if ipset.type == "hash:mac":
            family = "ether"
        elif ipset.options and "family" in ipset.options \
             and ipset.options["family"] == "inet6":
            family = "ip6"
        else:
            family = "ip"

        return family

    def set_restore(self, set_name, type_name, entries,
                    create_options=None, entry_options=None):
        rules = []
        rules.extend(self.build_set_create_rules(set_name, type_name, create_options))
        rules.extend(self.build_set_flush_rules(set_name))

        # avoid large memory usage by chunking the entries
        chunk = 0
        for entry in entries:
            rules.extend(self.build_set_add_rules(set_name, entry))
            chunk += 1
            if chunk >= 1000:
                self.set_rules(rules, self._fw.get_log_denied())
                rules.clear()
                chunk = 0
        else:
            self.set_rules(rules, self._fw.get_log_denied())
core/helper.py000064400000001444150351351720007332 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""The helper maxnamelen"""

HELPER_MAXNAMELEN = 32
core/fw_ifcfg.py000064400000005002150351351720007617 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""Functions to search for and change ifcfg files"""

__all__ = [ "search_ifcfg_of_interface", "ifcfg_set_zone_of_interface" ]

import os
import os.path

from firewall import config
from firewall.core.logger import log
from firewall.core.io.ifcfg import ifcfg

def search_ifcfg_of_interface(interface):
    """search ifcfg file for the interface in config.IFCFGDIR"""

    # Return quickly if config.IFCFGDIR does not exist
    if not os.path.exists(config.IFCFGDIR):
        return None

    for filename in sorted(os.listdir(config.IFCFGDIR)):
        if not filename.startswith("ifcfg-"):
            continue
        for ignored in [ ".bak", ".orig", ".rpmnew", ".rpmorig", ".rpmsave",
                         "-range" ]:
            if filename.endswith(ignored):
                continue
        if "." in filename:
            continue
        ifcfg_file = ifcfg("%s/%s" % (config.IFCFGDIR, filename))
        ifcfg_file.read()
        if ifcfg_file.get("DEVICE") == interface:
            return ifcfg_file

    # Wasn't found above, so assume filename matches the device we want
    filename = "%s/ifcfg-%s" % (config.IFCFGDIR, interface)
    if os.path.exists(filename):
        ifcfg_file = ifcfg(filename)
        ifcfg_file.read()
        return ifcfg_file

    return None

def ifcfg_set_zone_of_interface(zone, interface):
    """Set zone (ZONE=<zone>) in the ifcfg file that uses the interface
    (DEVICE=<interface>)"""

    if zone is None:
        zone = ""

    ifcfg_file = search_ifcfg_of_interface(interface)
    if ifcfg_file is not None and ifcfg_file.get("ZONE") != zone and not \
       (ifcfg_file.get("ZONE") is None and zone == ""):
        log.debug1("Setting ZONE=%s in '%s'" % (zone, ifcfg_file.filename))
        ifcfg_file.set("ZONE", zone)
        ifcfg_file.write()
core/fw_service.py000064400000003147150351351720010211 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "FirewallService" ]

from firewall import errors
from firewall.errors import FirewallError

class FirewallService(object):
    def __init__(self, fw):
        self._fw = fw
        self._services = { }

    def __repr__(self):
        return '%s(%r)' % (self.__class__, self._services)

    def cleanup(self):
        self._services.clear()

    # zones

    def get_services(self):
        return sorted(self._services.keys())

    def check_service(self, service):
        if service not in self._services:
            raise FirewallError(errors.INVALID_SERVICE, service)

    def get_service(self, service):
        self.check_service(service)
        return self._services[service]

    def add_service(self, obj):
        self._services[obj.name] = obj

    def remove_service(self, service):
        self.check_service(service)
        del self._services[service]
core/io/__init__.py000064400000003074150351351720010222 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2012 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

# fix xmlplus to be compatible with the python xml sax parser and python 3
# by adding __contains__ to xml.sax.xmlreader.AttributesImpl
import xml
if "_xmlplus" in xml.__file__:
    from xml.sax.xmlreader import AttributesImpl
    if not hasattr(AttributesImpl, "__contains__"):
        # this is missing:
        def __AttributesImpl__contains__(self, name):
            return name in getattr(self, "_attrs")
        # add it using the name __contains__
        setattr(AttributesImpl, "__contains__", __AttributesImpl__contains__)
    from xml.sax.saxutils import XMLGenerator
    if not hasattr(XMLGenerator, "_write"):
        # this is missing:
        def __XMLGenerator_write(self, text):
            getattr(self, "_out").write(text)
        # add it using the name _write
        setattr(XMLGenerator, "_write", __XMLGenerator_write)
core/io/helper.py000064400000020263150351351720007741 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "Helper", "helper_reader", "helper_writer" ]

import xml.sax as sax
import os
import io
import shutil

from firewall import config
from firewall.functions import u2b_if_py2
from firewall.core.io.io_object import PY2, IO_Object, \
    IO_Object_ContentHandler, IO_Object_XMLGenerator, check_port, \
    check_tcpudp
from firewall.core.logger import log
from firewall import errors
from firewall.errors import FirewallError

class Helper(IO_Object):
    IMPORT_EXPORT_STRUCTURE = (
        ( "version",  "" ),                   # s
        ( "short", "" ),                      # s
        ( "description", "" ),                # s
        ( "family", "", ),                    # s
        ( "module", "", ),                    # s
        ( "ports", [ ( "", "" ), ], ),        # a(ss)
        )
    DBUS_SIGNATURE = '(sssssa(ss))'
    ADDITIONAL_ALNUM_CHARS = [ "-", "." ]
    PARSER_REQUIRED_ELEMENT_ATTRS = {
        "short": None,
        "description": None,
        "helper": [ "module" ],
        }
    PARSER_OPTIONAL_ELEMENT_ATTRS = {
        "helper": [ "name", "version", "family" ],
        "port": [ "port", "protocol" ],
        }

    def __init__(self):
        super(Helper, self).__init__()
        self.version = ""
        self.short = ""
        self.description = ""
        self.module = ""
        self.family = ""
        self.ports = [ ]

    def cleanup(self):
        self.version = ""
        self.short = ""
        self.description = ""
        self.module = ""
        self.family = ""
        del self.ports[:]

    def encode_strings(self):
        """ HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support."""
        self.version = u2b_if_py2(self.version)
        self.short = u2b_if_py2(self.short)
        self.description = u2b_if_py2(self.description)
        self.module = u2b_if_py2(self.module)
        self.family = u2b_if_py2(self.family)
        self.ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr) in self.ports]

    def check_ipv(self, ipv):
        ipvs = [ 'ipv4', 'ipv6' ]
        if ipv not in ipvs:
            raise FirewallError(errors.INVALID_IPV,
                                "'%s' not in '%s'" % (ipv, ipvs))

    def _check_config(self, config, item, all_config):
        if item == "ports":
            for port in config:
                check_port(port[0])
                check_tcpudp(port[1])
        elif item == "module":
            if not config.startswith("nf_conntrack_"):
                raise FirewallError(
                    errors.INVALID_MODULE,
                    "'%s' does not start with 'nf_conntrack_'" % config)
            if len(config.replace("nf_conntrack_", "")) < 1:
                raise FirewallError(errors.INVALID_MODULE,
                                    "Module name '%s' too short" % config)

# PARSER

class helper_ContentHandler(IO_Object_ContentHandler):
    def startElement(self, name, attrs):
        IO_Object_ContentHandler.startElement(self, name, attrs)
        self.item.parser_check_element_attrs(name, attrs)
        if name == "helper":
            if "version" in attrs:
                self.item.version = attrs["version"]
            if "family" in attrs:
                self.item.check_ipv(attrs["family"])
                self.item.family = attrs["family"]
            if "module" in attrs:
                if not attrs["module"].startswith("nf_conntrack_"):
                    raise FirewallError(
                        errors.INVALID_MODULE,
                        "'%s' does not start with 'nf_conntrack_'" % \
                        attrs["module"])
                if len(attrs["module"].replace("nf_conntrack_", "")) < 1:
                    raise FirewallError(
                        errors.INVALID_MODULE,
                        "Module name '%s' too short" % attrs["module"])
                self.item.module = attrs["module"]
        elif name == "short":
            pass
        elif name == "description":
            pass
        elif name == "port":
            check_port(attrs["port"])
            check_tcpudp(attrs["protocol"])
            entry = (attrs["port"], attrs["protocol"])
            if entry not in self.item.ports:
                self.item.ports.append(entry)
            else:
                log.warning("Port '%s/%s' already set, ignoring.",
                            attrs["port"], attrs["protocol"])

def helper_reader(filename, path):
    helper = Helper()
    if not filename.endswith(".xml"):
        raise FirewallError(errors.INVALID_NAME,
                            "'%s' is missing .xml suffix" % filename)
    helper.name = filename[:-4]
    helper.check_name(helper.name)
    helper.filename = filename
    helper.path = path
    helper.builtin = False if path.startswith(config.ETC_FIREWALLD) else True
    helper.default = helper.builtin
    handler = helper_ContentHandler(helper)
    parser = sax.make_parser()
    parser.setContentHandler(handler)
    name = "%s/%s" % (path, filename)
    with open(name, "rb") as f:
        source = sax.InputSource(None)
        source.setByteStream(f)
        try:
            parser.parse(source)
        except sax.SAXParseException as msg:
            raise FirewallError(errors.INVALID_HELPER,
                                "not a valid helper file: %s" % \
                                msg.getException())
    del handler
    del parser
    if PY2:
        helper.encode_strings()
    return helper

def helper_writer(helper, path=None):
    _path = path if path else helper.path

    if helper.filename:
        name = "%s/%s" % (_path, helper.filename)
    else:
        name = "%s/%s.xml" % (_path, helper.name)

    if os.path.exists(name):
        try:
            shutil.copy2(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)

    dirpath = os.path.dirname(name)
    if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath):
        if not os.path.exists(config.ETC_FIREWALLD):
            os.mkdir(config.ETC_FIREWALLD, 0o750)
        os.mkdir(dirpath, 0o750)

    f = io.open(name, mode='wt', encoding='UTF-8')
    handler = IO_Object_XMLGenerator(f)
    handler.startDocument()

    # start helper element
    attrs = {}
    attrs["module"] = helper.module
    if helper.version and helper.version != "":
        attrs["version"] = helper.version
    if helper.family and helper.family != "":
        attrs["family"] = helper.family
    handler.startElement("helper", attrs)
    handler.ignorableWhitespace("\n")

    # short
    if helper.short and helper.short != "":
        handler.ignorableWhitespace("  ")
        handler.startElement("short", { })
        handler.characters(helper.short)
        handler.endElement("short")
        handler.ignorableWhitespace("\n")

    # description
    if helper.description and helper.description != "":
        handler.ignorableWhitespace("  ")
        handler.startElement("description", { })
        handler.characters(helper.description)
        handler.endElement("description")
        handler.ignorableWhitespace("\n")

    # ports
    for port in helper.ports:
        handler.ignorableWhitespace("  ")
        handler.simpleElement("port", { "port": port[0], "protocol": port[1] })
        handler.ignorableWhitespace("\n")

    # end helper element
    handler.endElement('helper')
    handler.ignorableWhitespace("\n")
    handler.endDocument()
    f.close()
    del handler
core/io/direct.py000064400000036740150351351720007743 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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 xml.sax as sax
import os
import io
import shutil

from firewall import config
from firewall.fw_types import LastUpdatedOrderedDict
from firewall.functions import splitArgs, joinArgs, u2b_if_py2
from firewall.core.io.io_object import IO_Object, IO_Object_ContentHandler, \
    IO_Object_XMLGenerator
from firewall.core.logger import log
from firewall.core import ipXtables
from firewall.core import ebtables
from firewall import errors
from firewall.errors import FirewallError


class direct_ContentHandler(IO_Object_ContentHandler):
    def __init__(self, item):
        IO_Object_ContentHandler.__init__(self, item)
        self.direct = False

    def startElement(self, name, attrs):
        IO_Object_ContentHandler.startElement(self, name, attrs)
        self.item.parser_check_element_attrs(name, attrs)

        if name == "direct":
            if self.direct:
                raise FirewallError(errors.PARSE_ERROR,
                                    "More than one direct tag.")
            self.direct = True

        elif name == "chain":
            if not self.direct:
                log.error("Parse Error: chain outside of direct")
                return
            ipv = attrs["ipv"]
            table = attrs["table"]
            chain = attrs["chain"]
            self.item.add_chain(u2b_if_py2(ipv), u2b_if_py2(table),
                                u2b_if_py2(chain))

        elif name == "rule":
            if not self.direct:
                log.error("Parse Error: rule outside of direct")
                return
            ipv = attrs["ipv"]
            if ipv not in [ "ipv4", "ipv6", "eb" ]:
                raise FirewallError(errors.INVALID_IPV,
                                    "'%s' not from {'ipv4'|'ipv6'|'eb'}" % ipv)
            table = attrs["table"]
            chain = attrs["chain"]
            try:
                priority = int(attrs["priority"])
            except ValueError:
                log.error("Parse Error: %s is not a valid priority" %
                          attrs["priority"])
                return
            self._rule = [ u2b_if_py2(ipv), u2b_if_py2(table),
                           u2b_if_py2(chain), priority ]

        elif name == "passthrough":
            if not self.direct:
                log.error("Parse Error: command outside of direct")
                return
            ipv = attrs["ipv"]
            self._passthrough = [ u2b_if_py2(ipv) ]

        else:
            log.error('Unknown XML element %s' % name)
            return

    def endElement(self, name):
        IO_Object_ContentHandler.endElement(self, name)

        if name == "rule":
            if self._element:
                # add arguments
                self._rule.append([ u2b_if_py2(x)
                                    for x in splitArgs(self._element) ])
                self.item.add_rule(*self._rule)
            else:
                log.error("Error: rule does not have any arguments, ignoring.")
            self._rule = None
        elif name == "passthrough":
            if self._element:
                # add arguments
                self._passthrough.append([ u2b_if_py2(x)
                                           for x in splitArgs(self._element) ])
                self.item.add_passthrough(*self._passthrough)
            else:
                log.error("Error: passthrough does not have any arguments, " +
                          "ignoring.")
            self._passthrough = None

class Direct(IO_Object):
    """ Direct class """

    IMPORT_EXPORT_STRUCTURE = (
        # chain: [ ipv, table, [ chain ] ]
        ( "chains", [ ( "", "", "" ), ], ),                   # a(sss)
        # rule: [ ipv, table, chain, [ priority, [ arg ] ] ]
        ( "rules", [ ( "", "", "", 0, [ "" ] ), ], ),         # a(sssias)
        # passthrough: [ ipv, [ [ arg ] ] ]
        ( "passthroughs", [ ( "", [ "" ]), ], ),              # a(sas)
        )
    DBUS_SIGNATURE = '(a(sss)a(sssias)a(sas))'
    PARSER_REQUIRED_ELEMENT_ATTRS = {
        "direct": None,
        "chain": [ "ipv", "table", "chain" ],
        "rule": [ "ipv", "table", "chain", "priority" ],
        "passthrough": [ "ipv" ]
        }
    PARSER_OPTIONAL_ELEMENT_ATTRS = {
        }

    def __init__(self, filename):
        super(Direct, self).__init__()
        self.filename = filename
        self.chains = LastUpdatedOrderedDict()
        self.rules = LastUpdatedOrderedDict()
        self.passthroughs = LastUpdatedOrderedDict()

    def _check_config(self, conf, item, all_conf):
        pass
        # check arg lists

    def export_config(self):
        ret = [ ]
        x = [ ]
        for key in self.chains:
            for chain in self.chains[key]:
                x.append(tuple(list(key) + list([chain])))
        ret.append(x)
        x = [ ]
        for key in self.rules:
            for rule in self.rules[key]:
                x.append(tuple((key[0], key[1], key[2], rule[0],
                                list(rule[1]))))
        ret.append(x)
        x = [ ]
        for key in self.passthroughs:
            for rule in self.passthroughs[key]:
                x.append(tuple((key, list(rule))))
        ret.append(x)
        return tuple(ret)

    def import_config(self, conf):
        self.cleanup()
        self.check_config(conf)
        for i,(element,dummy) in enumerate(self.IMPORT_EXPORT_STRUCTURE):
            if element == "chains":
                for x in conf[i]:
                    self.add_chain(*x)
            if element == "rules":
                for x in conf[i]:
                    self.add_rule(*x)
            if element == "passthroughs":
                for x in conf[i]:
                    self.add_passthrough(*x)

    def cleanup(self):
        self.chains.clear()
        self.rules.clear()
        self.passthroughs.clear()

    def output(self):
        print("chains")
        for key in self.chains:
            print("  (%s, %s): %s" % (key[0], key[1],
                                      ",".join(self.chains[key])))
        print("rules")
        for key in self.rules:
            print("  (%s, %s, %s):" % (key[0], key[1], key[2]))
            for (priority,args) in self.rules[key]:
                print("    (%d, ('%s'))" % (priority, "','".join(args)))
        print("passthroughs")
        for key in self.passthroughs:
            print("  %s:" % (key))
            for args in self.passthroughs[key]:
                print("    ('%s')" % ("','".join(args)))

    def _check_ipv(self, ipv):
        ipvs = ['ipv4', 'ipv6', 'eb']
        if ipv not in ipvs:
            raise FirewallError(errors.INVALID_IPV,
                                "'%s' not in '%s'" % (ipv, ipvs))

    def _check_ipv_table(self, ipv, table):
        self._check_ipv(ipv)

        tables = ipXtables.BUILT_IN_CHAINS.keys() if ipv in ['ipv4', 'ipv6'] \
                                         else ebtables.BUILT_IN_CHAINS.keys()
        if table not in tables:
            raise FirewallError(errors.INVALID_TABLE,
                                "'%s' not in '%s'" % (table, tables))

    # chains

    def add_chain(self, ipv, table, chain):
        self._check_ipv_table(ipv, table)
        key = (ipv, table)
        if key not in self.chains:
            self.chains[key] = [ ]
        if chain not in self.chains[key]:
            self.chains[key].append(chain)
        else:
            log.warning("Chain '%s' for table '%s' with ipv '%s' " % \
                        (chain, table, ipv) + "already in list, ignoring")

    def remove_chain(self, ipv, table, chain):
        self._check_ipv_table(ipv, table)
        key = (ipv, table)
        if key in self.chains and chain in self.chains[key]:
            self.chains[key].remove(chain)
            if len(self.chains[key]) == 0:
                del self.chains[key]
        else:
            raise ValueError( \
                "Chain '%s' with table '%s' with ipv '%s' not in list" % \
                (chain, table, ipv))

    def query_chain(self, ipv, table, chain):
        self._check_ipv_table(ipv, table)
        key = (ipv, table)
        return (key in self.chains and chain in self.chains[key])

    def get_chains(self, ipv, table):
        self._check_ipv_table(ipv, table)
        key = (ipv, table)
        if key in self.chains:
            return self.chains[key]
        else:
            raise ValueError("No chains for table '%s' with ipv '%s'" % \
                             (table, ipv))

    def get_all_chains(self):
        return self.chains

    # rules

    def add_rule(self, ipv, table, chain, priority, args):
        self._check_ipv_table(ipv, table)
        key = (ipv, table, chain)
        if key not in self.rules:
            self.rules[key] = LastUpdatedOrderedDict()
        value = (priority, tuple(args))
        if value not in self.rules[key]:
            self.rules[key][value] = priority
        else:
            log.warning("Rule '%s' for table '%s' and chain '%s' " % \
                        ("',".join(args), table, chain) +
                        "with ipv '%s' and priority %d " % (ipv, priority) +
                        "already in list, ignoring")

    def remove_rule(self, ipv, table, chain, priority, args):
        self._check_ipv_table(ipv, table)
        key = (ipv, table, chain)
        value = (priority, tuple(args))
        if key in self.rules and value in self.rules[key]:
            del self.rules[key][value]
            if len(self.rules[key]) == 0:
                del self.rules[key]
        else:
            raise ValueError("Rule '%s' for table '%s' and chain '%s' " % \
                ("',".join(args), table, chain) + \
                "with ipv '%s' and priority %d not in list" % (ipv, priority))

    def remove_rules(self, ipv, table, chain):
        self._check_ipv_table(ipv, table)
        key = (ipv, table, chain)
        if key in self.rules:
            for value in self.rules[key].keys():
                del self.rules[key][value]
            if len(self.rules[key]) == 0:
                del self.rules[key]

    def query_rule(self, ipv, table, chain, priority, args):
        self._check_ipv_table(ipv, table)
        key = (ipv, table, chain)
        value = (priority, tuple(args))
        return (key in self.rules and value in self.rules[key])

    def get_rules(self, ipv, table, chain):
        self._check_ipv_table(ipv, table)
        key = (ipv, table, chain)
        if key in self.rules:
            return self.rules[key]
        else:
            raise ValueError("No rules for table '%s' and chain '%s' " %\
                             (table, chain) + "with ipv '%s'" % (ipv))

    def get_all_rules(self):
        return self.rules

#    # passthrough
#
    def add_passthrough(self, ipv, args):
        self._check_ipv(ipv)
        if ipv not in self.passthroughs:
            self.passthroughs[ipv] = [ ]
        if args not in self.passthroughs[ipv]:
            self.passthroughs[ipv].append(args)
        else:
            log.warning("Passthrough '%s' for ipv '%s'" % \
                        ("',".join(args), ipv) + "already in list, ignoring")

    def remove_passthrough(self, ipv, args):
        self._check_ipv(ipv)
        if ipv in self.passthroughs and args in self.passthroughs[ipv]:
            self.passthroughs[ipv].remove(args)
            if len(self.passthroughs[ipv]) == 0:
                del self.passthroughs[ipv]
        else:
            raise ValueError("Passthrough '%s' for ipv '%s'" % \
                             ("',".join(args), ipv) + "not in list")

    def query_passthrough(self, ipv, args):
        self._check_ipv(ipv)
        return ipv in self.passthroughs and args in self.passthroughs[ipv]

    def get_passthroughs(self, ipv):
        self._check_ipv(ipv)
        if ipv in self.passthroughs:
            return self.passthroughs[ipv]
        else:
            raise ValueError("No passthroughs for ipv '%s'" % (ipv))

    def get_all_passthroughs(self):
        return self.passthroughs

    # read

    def read(self):
        self.cleanup()
        if not self.filename.endswith(".xml"):
            raise FirewallError(errors.INVALID_NAME,
                                "'%s' is missing .xml suffix" % self.filename)
        handler = direct_ContentHandler(self)
        parser = sax.make_parser()
        parser.setContentHandler(handler)
        with open(self.filename, "rb") as f:
            source = sax.InputSource(None)
            source.setByteStream(f)
            try:
                parser.parse(source)
            except sax.SAXParseException as msg:
                raise FirewallError(errors.INVALID_TYPE,
                                    "Not a valid file: %s" % \
                                    msg.getException())

    def write(self):
        if os.path.exists(self.filename):
            try:
                shutil.copy2(self.filename, "%s.old" % self.filename)
            except Exception as msg:
                raise IOError("Backup of '%s' failed: %s" % (self.filename, msg))

        if not os.path.exists(config.ETC_FIREWALLD):
            os.mkdir(config.ETC_FIREWALLD, 0o750)

        f = io.open(self.filename, mode='wt', encoding='UTF-8')
        handler = IO_Object_XMLGenerator(f)
        handler.startDocument()

        # start whitelist element
        handler.startElement("direct", { })
        handler.ignorableWhitespace("\n")

        # chains
        for key in self.chains:
            (ipv, table) = key
            for chain in self.chains[key]:
                handler.ignorableWhitespace("  ")
                handler.simpleElement("chain", { "ipv": ipv, "table": table,
                                                 "chain": chain })
                handler.ignorableWhitespace("\n")

        # rules
        for key in self.rules:
            (ipv, table, chain) = key
            for (priority, args) in self.rules[key]:
                if len(args) < 1:
                    continue
                handler.ignorableWhitespace("  ")
                handler.startElement("rule", { "ipv": ipv, "table": table,
                                               "chain": chain,
                                               "priority": "%d" % priority })
                handler.ignorableWhitespace(sax.saxutils.escape(joinArgs(args)))
                handler.endElement("rule")
                handler.ignorableWhitespace("\n")

        # passthroughs
        for ipv in self.passthroughs:
            for args in self.passthroughs[ipv]:
                if len(args) < 1:
                    continue
                handler.ignorableWhitespace("  ")
                handler.startElement("passthrough", { "ipv": ipv })
                handler.ignorableWhitespace(sax.saxutils.escape(joinArgs(args)))
                handler.endElement("passthrough")
                handler.ignorableWhitespace("\n")

        # end zone element
        handler.endElement("direct")
        handler.ignorableWhitespace("\n")
        handler.endDocument()
        f.close()
        del handler
core/io/ifcfg.py000064400000014345150351351720007544 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""ifcfg file parser"""

__all__ = [ "ifcfg" ]

import os.path
import io
import tempfile
import shutil

from firewall.core.logger import log
from firewall.functions import b2u, u2b, PY2

class ifcfg(object):
    def __init__(self, filename):
        self._config = { }
        self._deleted = [ ]
        self.filename = filename
        self.clear()

    def clear(self):
        self._config = { }
        self._deleted = [ ]

    def cleanup(self):
        self._config.clear()

    def get(self, key):
        return self._config.get(key.strip())

    def set(self, key, value):
        _key = b2u(key.strip())
        self._config[_key] = b2u(value.strip())
        if _key in self._deleted:
            self._deleted.remove(_key)

    def __str__(self):
        s = ""
        for (key, value) in self._config.items():
            if s:
                s += '\n'
            s += '%s=%s' % (key, value)
        return u2b(s) if PY2 else s

    # load self.filename
    def read(self):
        self.clear()
        try:
            f = open(self.filename, "r")
        except Exception as msg:
            log.error("Failed to load '%s': %s", self.filename, msg)
            raise

        for line in f:
            if not line:
                break
            line = line.strip()
            if len(line) < 1 or line[0] in ['#', ';']:
                continue
            # get key/value pair
            pair = [ x.strip() for x in line.split("=", 1) ]
            if len(pair) != 2:
                continue
            if len(pair[1]) >= 2 and \
               pair[1].startswith('"') and pair[1].endswith('"'):
                pair[1] = pair[1][1:-1]
            if pair[1] == '':
                continue
            elif self._config.get(pair[0]) is not None:
                log.warning("%s: Duplicate option definition: '%s'", self.filename, line.strip())
                continue
            self._config[pair[0]] = pair[1]
        f.close()

    def write(self):
        if len(self._config) < 1:
            # no changes: nothing to do
            return

        # handled keys
        done = [ ]

        try:
            temp_file = tempfile.NamedTemporaryFile(
                mode='wt',
                prefix="%s." % os.path.basename(self.filename),
                dir=os.path.dirname(self.filename), delete=False)
        except Exception as msg:
            log.error("Failed to open temporary file: %s" % msg)
            raise

        modified = False
        empty = False
        try:
            f = io.open(self.filename, mode='rt', encoding='UTF-8')
        except Exception as msg:
            if os.path.exists(self.filename):
                log.error("Failed to open '%s': %s" % (self.filename, msg))
                raise
            else:
                f = None
        else:
            for line in f:
                if not line:
                    break
                # remove newline
                line = line.strip("\n")

                if len(line) < 1:
                    if not empty:
                        temp_file.write(u"\n")
                        empty = True
                elif line[0] == '#':
                    empty = False
                    temp_file.write(line)
                    temp_file.write(u"\n")
                else:
                    p = line.split("=", 1)
                    if len(p) != 2:
                        empty = False
                        temp_file.write(line+u"\n")
                        continue
                    key = p[0].strip()
                    value = p[1].strip()
                    if len(value) >= 2 and \
                       value.startswith('"') and value.endswith('"'):
                        value = value[1:-1]
                    # check for modified key/value pairs
                    if key not in done:
                        if key in self._config and self._config[key] != value:
                            empty = False
                            temp_file.write(u'%s=%s\n' % (key,
                                                          self._config[key]))
                            modified = True
                        elif key in self._deleted:
                            modified = True
                        else:
                            empty = False
                            temp_file.write(line+u"\n")
                        done.append(key)
                    else:
                        modified = True

        # write remaining key/value pairs
        if len(self._config) > 0:
            for (key, value) in self._config.items():
                if key in done:
                    continue
                if not empty:
                    empty = True
                temp_file.write(u'%s=%s\n' % (key, value))
                modified = True

        if f:
            f.close()
        temp_file.close()

        if not modified: # not modified: remove tempfile
            os.remove(temp_file.name)
            return
        # make backup
        if os.path.exists(self.filename):
            try:
                shutil.copy2(self.filename, "%s.bak" % self.filename)
            except Exception as msg:
                os.remove(temp_file.name)
                raise IOError("Backup of '%s' failed: %s" % (self.filename, msg))

        # copy tempfile
        try:
            shutil.move(temp_file.name, self.filename)
        except Exception as msg:
            os.remove(temp_file.name)
            raise IOError("Failed to create '%s': %s" % (self.filename, msg))
        else:
            os.chmod(self.filename, 0o600)
core/io/icmptype.py000064400000015244150351351720010317 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "IcmpType", "icmptype_reader", "icmptype_writer" ]

import xml.sax as sax
import os
import io
import shutil

from firewall import config
from firewall.functions import u2b_if_py2
from firewall.core.io.io_object import PY2, IO_Object, \
    IO_Object_ContentHandler, IO_Object_XMLGenerator
from firewall.core.logger import log
from firewall import errors
from firewall.errors import FirewallError

class IcmpType(IO_Object):
    IMPORT_EXPORT_STRUCTURE = (
        ( "version",  "" ),          # s
        ( "short", "" ),             # s
        ( "description", "" ),       # s
        ( "destination", [ "", ], ), # as
        )
    DBUS_SIGNATURE = '(sssas)'
    ADDITIONAL_ALNUM_CHARS = [ "_", "-" ]
    PARSER_REQUIRED_ELEMENT_ATTRS = {
        "short": None,
        "description": None,
        "icmptype": None,
        }
    PARSER_OPTIONAL_ELEMENT_ATTRS = {
        "icmptype": [ "name", "version" ],
        "destination": [ "ipv4", "ipv6" ],
        }

    def __init__(self):
        super(IcmpType, self).__init__()
        self.version = ""
        self.short = ""
        self.description = ""
        self.destination = [ ]

    def cleanup(self):
        self.version = ""
        self.short = ""
        self.description = ""
        del self.destination[:]

    def encode_strings(self):
        """ HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support."""
        self.version = u2b_if_py2(self.version)
        self.short = u2b_if_py2(self.short)
        self.description = u2b_if_py2(self.description)
        self.destination = [u2b_if_py2(m) for m in self.destination]

    def _check_config(self, config, item, all_config):
        if item == "destination":
            for destination in config:
                if destination not in [ "ipv4", "ipv6" ]:
                    raise FirewallError(errors.INVALID_DESTINATION,
                                        "'%s' not from {'ipv4'|'ipv6'}" % \
                                        destination)

# PARSER

class icmptype_ContentHandler(IO_Object_ContentHandler):
    def startElement(self, name, attrs):
        IO_Object_ContentHandler.startElement(self, name, attrs)
        self.item.parser_check_element_attrs(name, attrs)

        if name == "icmptype":
            if "name" in attrs:
                log.warning("Ignoring deprecated attribute name='%s'" %
                            attrs["name"])
            if "version" in attrs:
                self.item.version = attrs["version"]
        elif name == "short":
            pass
        elif name == "description":
            pass
        elif name == "destination":
            for x in [ "ipv4", "ipv6" ]:
                if x in attrs and \
                        attrs[x].lower() in [ "yes", "true" ]:
                    self.item.destination.append(str(x))

def icmptype_reader(filename, path):
    icmptype = IcmpType()
    if not filename.endswith(".xml"):
        raise FirewallError(errors.INVALID_NAME,
                            "%s is missing .xml suffix" % filename)
    icmptype.name = filename[:-4]
    icmptype.check_name(icmptype.name)
    icmptype.filename = filename
    icmptype.path = path
    icmptype.builtin = False if path.startswith(config.ETC_FIREWALLD) else True
    icmptype.default = icmptype.builtin
    handler = icmptype_ContentHandler(icmptype)
    parser = sax.make_parser()
    parser.setContentHandler(handler)
    name = "%s/%s" % (path, filename)
    with open(name, "rb") as f:
        source = sax.InputSource(None)
        source.setByteStream(f)
        try:
            parser.parse(source)
        except sax.SAXParseException as msg:
            raise FirewallError(errors.INVALID_ICMPTYPE,
                                "not a valid icmptype file: %s" % \
                                msg.getException())
    del handler
    del parser
    if PY2:
        icmptype.encode_strings()
    return icmptype

def icmptype_writer(icmptype, path=None):
    _path = path if path else icmptype.path

    if icmptype.filename:
        name = "%s/%s" % (_path, icmptype.filename)
    else:
        name = "%s/%s.xml" % (_path, icmptype.name)

    if os.path.exists(name):
        try:
            shutil.copy2(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)

    dirpath = os.path.dirname(name)
    if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath):
        if not os.path.exists(config.ETC_FIREWALLD):
            os.mkdir(config.ETC_FIREWALLD, 0o750)
        os.mkdir(dirpath, 0o750)

    f = io.open(name, mode='wt', encoding='UTF-8')
    handler = IO_Object_XMLGenerator(f)
    handler.startDocument()

    # start icmptype element
    attrs = {}
    if icmptype.version and icmptype.version != "":
        attrs["version"] = icmptype.version
    handler.startElement("icmptype", attrs)
    handler.ignorableWhitespace("\n")

    # short
    if icmptype.short and icmptype.short != "":
        handler.ignorableWhitespace("  ")
        handler.startElement("short", { })
        handler.characters(icmptype.short)
        handler.endElement("short")
        handler.ignorableWhitespace("\n")

    # description
    if icmptype.description and icmptype.description != "":
        handler.ignorableWhitespace("  ")
        handler.startElement("description", { })
        handler.characters(icmptype.description)
        handler.endElement("description")
        handler.ignorableWhitespace("\n")

    # destination
    if icmptype.destination:
        handler.ignorableWhitespace("  ")
        attrs = { }
        for x in icmptype.destination:
            attrs[x] = "yes"
        handler.simpleElement("destination", attrs)
        handler.ignorableWhitespace("\n")

    # end icmptype element
    handler.endElement('icmptype')
    handler.ignorableWhitespace("\n")
    handler.endDocument()
    f.close()
    del handler
core/io/__pycache__/functions.cpython-36.opt-1.pyc000064400000005256150351351720015722 0ustar003

��gy�@s�ddlZddlmZddlmZddlmZddlmZddl	m
Z
ddlmZddl
mZdd	lmZdd
lmZddlmZddlmZdd
lmZdd�ZdS)�N)�config)�
FirewallError)�FirewallConfig)�zone_reader)�service_reader)�ipset_reader)�icmptype_reader)�
helper_reader)�
policy_reader)�Direct)�LockdownWhitelist)�firewalld_confc	-Cs|t|�}t|jtjtjgd�t|jtjtj	gd�t
|jtjtj
gd�t|jtjtjgd�t|jtjtjgd�t|jtjtjgd�d�}�x
|j�D�]�}x�||dD]�}tjj|�s�q�x�ttj|��D]�}|j d�r�yD||d||�}|d
k�r�||_!|j"|j#��||d|�Wq�t$k
�rT}zt$|j%d	||j&f��WYdd}~Xq�t'k
�r�}zt'd	||f��WYdd}~Xq�Xq�Wq�Wq�Wtjj(tj)��r:y$t*tj)�}|j+�|j,|j-��Wnpt$k
�r}zt$|j%d	tj)|j&f��WYdd}~Xn6t'k
�r8}zt'd	tj)|f��WYdd}~XnXtjj(tj.��r�y$t/tj.�}|j+�|j,|j-��Wnpt$k
�r�}zt$|j%d	tj.|j&f��WYdd}~Xn6t'k
�r�}zt'd	tj.|f��WYdd}~XnXtjj(tj0��rxyt1tj0�}|j+�Wnpt$k
�rB}zt$|j%d	tj0|j&f��WYdd}~Xn6t'k
�rv}zt'd	tj0|f��WYdd}~XnXdS)N)�reader�add�dirs)Zipset�helperZicmptypeZservice�zone�policyrz.xmlrrrrz'%s': %s)rr)2rrZ	add_ipsetrZFIREWALLD_IPSETSZETC_FIREWALLD_IPSETSr	Z
add_helperZFIREWALLD_HELPERSZETC_FIREWALLD_HELPERSrZadd_icmptypeZFIREWALLD_ICMPTYPESZETC_FIREWALLD_ICMPTYPESrZadd_serviceZFIREWALLD_SERVICESZETC_FIREWALLD_SERVICESrZadd_zoneZFIREWALLD_ZONESZETC_FIREWALLD_ZONESr
Zadd_policy_objectZFIREWALLD_POLICIESZETC_FIREWALLD_POLICIES�keys�os�path�isdir�sorted�listdir�endswith�	fw_configZcheck_config_dictZexport_config_dictr�code�msg�	Exception�isfileZFIREWALLD_DIRECTr�read�check_configZ
export_configZLOCKDOWN_WHITELISTrZFIREWALLD_CONFr
)	�fwrZreadersrZ_dir�file�obj�errorr�r&�/usr/lib/python3.6/functions.pyr!&sz

&.
($
($
(r!)rZfirewallrZfirewall.errorsrZfirewall.core.fw_configrZfirewall.core.io.zonerZfirewall.core.io.servicerZfirewall.core.io.ipsetrZfirewall.core.io.icmptyperZfirewall.core.io.helperr	Zfirewall.core.io.policyr
Zfirewall.core.io.directrZ#firewall.core.io.lockdown_whitelistrZfirewall.core.io.firewalld_confr
r!r&r&r&r'�<module>score/io/__pycache__/io_object.cpython-36.pyc000064400000027540150351351720014710 0ustar003

��g5�@sdZddddddddgZd	d
ljZd	d
ljjZd	d
lZd	d
lZd	dlm	Z	d	dl
mZd	d
lm
Z
d	dl
mZd	dlmZejdkZGdd�de�ZGdd�de�ZGdd�de�ZGdd�de�ZGdd�dejj�ZGdd�dej�Zdd�Zdd�Zdd�Z dd�Z!d
S)z5Generic io_object handler, io specific check methods.�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator�
check_port�check_tcpudp�check_protocol�
check_address�N)�OrderedDict)�	functions)�b2u)�errors)�
FirewallError�3c@s|eZdZdZfZdZgZiZiZdd�Z	dd�Z
dd�Zd	d
�Zdd�Z
d
d�Zdd�Zdd�Zdd�Zdd�Zdd�ZdS)rz; Abstract IO_Object as base for icmptype, service and zone z()cCs"d|_d|_d|_d|_d|_dS)N�F)�filename�path�name�defaultZbuiltin)�self�r�/usr/lib/python3.6/io_object.py�__init__2s
zIO_Object.__init__cCs6g}x(|jD]}|jtjt||d���qWt|�S)Nr	)�IMPORT_EXPORT_STRUCTURE�append�copy�deepcopy�getattr�tuple)r�ret�xrrr�
export_config9szIO_Object.export_configcCsXi}tdd�|jD��}x:|D]2}t||�s<tt||�t�rtjt||��||<qW|S)NcSsg|]}|d|df�qS)r	�r)�.0r rrr�
<listcomp>Asz0IO_Object.export_config_dict.<locals>.<listcomp>)�dictrr�
isinstance�boolrr)r�conf�type_formats�keyrrr�export_config_dict?s
zIO_Object.export_config_dictcCs�|j|�x�t|j�D]~\}\}}t||t�r~g}t�}x,||D] }||krD|j|�|j|�qDW~t||t	j
|��qt||t	j
||��qWdS)N)�check_config�	enumeraterr&�list�setr�add�setattrrr)rr(�i�elementZdummyZ_confZ_setr rrr�
import_configGs

zIO_Object.import_configc	Cs~|j|�xn|D]f}t||�s0ttjdj|���t||t�r`t||tt	j
tj||����qt||tj||��qWdS)Nz-Internal error. '{}' is not a valid attribute)
�check_config_dict�hasattrrr
Z
UNKNOWN_ERROR�formatr&r.r1r
�fromkeysrr)rr(r*rrr�import_config_dictWs


"zIO_Object.import_config_dictcCszt|t�s(ttjd|td�t|�f��t|�dkr@ttjd��x4|D],}|j�rF||j	krFttjd||f��qFWdS)Nz'%s' not of type %s, but %srr"zname can't be emptyz'%s' is not allowed in '%s')
r&�strrr
�INVALID_TYPE�type�lenZINVALID_NAME�isalnum�ADDITIONAL_ALNUM_CHARS)rr�charrrr�
check_namecs


zIO_Object.check_namecCsjt|�t|j�kr0ttjdt|�t|j�f��i}x&t|j�D]\}\}}||||<q@W|j|�dS)Nz structure size mismatch %d != %d)r=rrr
r;r-r5)rr(Z	conf_dictr2r �yrrrr,pszIO_Object.check_configcCsrtdd�|jD��}xX|D]P}|dd�|jD�krDttjdj|���|j||||�|j||||�qWdS)NcSsg|]}|d|df�qS)r	r"r)r#r rrrr$|sz/IO_Object.check_config_dict.<locals>.<listcomp>cSsg|]\}}|�qSrr)r#r rBrrrr$~szoption '{}' is not valid)r%rrr
ZINVALID_OPTIONr7�_check_config_structure�
_check_config)rr(r)r*rrrr5{s
zIO_Object.check_config_dictcCsdS)Nr)rZdummy1Zdummy2Zdummy3rrrrD�szIO_Object._check_configc	Cs`t|t|��s,ttjd|t|�t|�f��t|t�rrt|�dkrRttjd|��x|D]}|j||d�qXWn�t|t�r�t|�t|�kr�ttjd|t|�f��x�t	|�D]\}}|j|||�q�Wn�t|t
��r\t|j��d\}}xn|j�D]b\}}t|t|���s,ttjd|t|�t|�f��t|t|��s�ttjd|t|�t|�f��q�WdS)Nz'%s' not of type %s, but %sr"zlen('%s') != 1r	zlen('%s') != %d)r&r<rr
r;r.r=rCrr-r%�items)	rr(Z	structurer r2�valueZskeyZsvaluer*rrrrC�s8



z!IO_Object._check_config_structurecCs�|j�}d}||jkrdd}|j|dk	rdx:|j|D],}||krL|j|�q4ttjd||f��q4W||jkr�d}x$|j|D]}||kr~|j|�q~W|s�ttjd|��x |D]}ttjd||f��q�WdS)NFTzMissing attribute %s for %szUnexpected element %sz%s: Unexpected attribute %s)ZgetNames�PARSER_REQUIRED_ELEMENT_ATTRS�removerr
ZPARSE_ERROR�PARSER_OPTIONAL_ELEMENT_ATTRS)rr�attrsZ_attrs�foundr rrr�parser_check_element_attrs�s,



z$IO_Object.parser_check_element_attrsN)�__name__�
__module__�__qualname__�__doc__rZDBUS_SIGNATUREr?rGrIrr!r+r4r9rAr,r5rDrCrLrrrrr)s"
!cs$eZdZ�fdd�Zdd�Z�ZS)�UnexpectedElementErrorcstt|�j�||_dS)N)�superrQrr)rr)�	__class__rrr�szUnexpectedElementError.__init__cCs
d|jS)NzUnexpected element '%s')r)rrrr�__str__�szUnexpectedElementError.__str__)rMrNrOrrT�
__classcell__rr)rSrrQ�srQcs$eZdZ�fdd�Zdd�Z�ZS)�MissingAttributeErrorcstt|�j�||_||_dS)N)rRrVrr�	attribute)rrrW)rSrrr�szMissingAttributeError.__init__cCsd|j|jfS)Nz$Element '%s': missing '%s' attribute)rrW)rrrrrT�szMissingAttributeError.__str__)rMrNrOrrTrUrr)rSrrV�srVcs$eZdZ�fdd�Zdd�Z�ZS)�UnexpectedAttributeErrorcstt|�j�||_||_dS)N)rRrXrrrW)rrrW)rSrrr�sz!UnexpectedAttributeError.__init__cCsd|j|jfS)Nz'Element '%s': unexpected attribute '%s')rrW)rrrrrT�sz UnexpectedAttributeError.__str__)rMrNrOrrTrUrr)rSrrX�srXc@s4eZdZdd�Zdd�Zdd�Zdd�Zd	d
�ZdS)rcCs||_d|_dS)Nr)�item�_element)rrYrrrr�sz!IO_Object_ContentHandler.__init__cCs
d|_dS)Nr)rZ)rrrr�
startDocument�sz&IO_Object_ContentHandler.startDocumentcCs
d|_dS)Nr)rZ)rrrJrrr�startElement�sz%IO_Object_ContentHandler.startElementcCs*|dkr|j|j_n|dkr&|j|j_dS)N�short�description)rZrYr]r^)rrrrr�
endElement�sz#IO_Object_ContentHandler.endElementcCs|j|jdd�7_dS)N�
� )rZ�replace)r�contentrrr�
characters�sz#IO_Object_ContentHandler.charactersN)rMrNrOrr[r\r_rdrrrrr�s
c@s<eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
S)rcCsNtjjj|�|j|_|j|_ig|_|jd|_	g|_
d|_d|_d|_
dS)Nr"zutf-8F���)�sax�handler�ContentHandlerr�write�_write�flushZ_flushZ_ns_contextsZ_current_contextZ_undeclared_ns_mapsZ	_encodingZ_pending_start_elementZ_short_empty_elements)r�outrrrr�szIO_Object_XMLGenerator.__init__cCs*trdd�|j�D�}tjj|||�dS)a saxutils.XMLGenerator.startElement() expects name and attrs to be
            unicode and bad things happen if any of them is (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        cSsi|]\}}t|�t|��qSr)r)r#rrFrrr�
<dictcomp>sz7IO_Object_XMLGenerator.startElement.<locals>.<dictcomp>N)rrE�saxutils�XMLGeneratorr\)rrrJrrrr\sz#IO_Object_XMLGenerator.startElementcCs�trX|jdt|��x4|j�D](\}}|jdt|�tjt|��f�q W|jd�nF|jd|�x,|j�D] \}}|jd|tj|�f�qpW|jd�dS)z* slightly modified startElement()
        �<z %s=%sz/>N)rrjrrErnZ	quoteattr)rrrJrFrrr�
simpleElementsz$IO_Object_XMLGenerator.simpleElementcCstjj|t|��dS)z� saxutils.XMLGenerator.endElement() expects name to be
            unicode and bad things happen if it's (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        N)rnror_r)rrrrrr_sz!IO_Object_XMLGenerator.endElementcCstjj|t|��dS)z� saxutils.XMLGenerator.characters() expects content to be
            unicode and bad things happen if it's (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        N)rnrordr)rrcrrrrd%sz!IO_Object_XMLGenerator.characterscCstjj|t|��dS)a saxutils.XMLGenerator.ignorableWhitespace() expects content to be
            unicode and bad things happen if it's (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        N)rnro�ignorableWhitespacer)rrcrrrrr-sz*IO_Object_XMLGenerator.ignorableWhitespaceN)	rMrNrOrr\rqr_rdrrrrrrr�s
cCs�tj|�}|dkr$ttjd|��n`|dkr>ttjd|��nF|dkrXttjd|��n,t|�dkr�|d|dkr�ttjd|��dS)	N�zport number in '%s' is too bigr"z'%s' is invalid port rangezport range '%s' is ambiguousr	���re)rZgetPortRangerr
ZINVALID_PORTr=)ZportZ
port_rangerrrr5s
cCs|dkrttjd|��dS)N�tcp�udp�sctp�dccpz)'%s' not from {'tcp'|'udp'|'sctp'|'dccp'})rurvrwrx)rr
�INVALID_PROTOCOL)�protocolrrrrDscCstj|�sttj|��dS)N)rZ
checkProtocolrr
ry)rzrrrrJs
cCs$tj||�s ttjd||f��dS)Nz'%s' is not valid %s address)rrrr
ZINVALID_ADDR)ZipvZaddrrrrrNs)"rP�__all__Zxml.saxrfZxml.sax.saxutilsrnr�sys�collectionsr
ZfirewallrZfirewall.functionsrr
Zfirewall.errorsr�versionr�objectr�	ExceptionrQrVrXrgrhrrorrrrrrrrr�<module>s0

		Ccore/io/__pycache__/zone.cpython-36.opt-1.pyc000064400000031307150351351720014661 0ustar003

��g�M�@sdddgZddljZddlZddlZddlZddlmZddlm	Z	m
Z
mZmZm
Z
mZmZddlmZmZddlmZmZmZmZdd	lmZmZmZmZdd
lmZddlm Z ddlm!Z!dd
l"m#Z#Gdd�de�Z$Gdd�de�Z%ddd�Z&ddd�Z'dS)�Zone�zone_reader�zone_writer�N)�config)�checkIPnMask�
checkIP6nMask�checkInterface�uniqify�max_zone_name_len�
u2b_if_py2�	check_mac)�DEFAULT_ZONE_TARGET�ZONE_TARGETS)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator)�common_startElement�common_endElement�common_check_config�
common_writer)�rich)�log)�errors)�
FirewallErrorcsfeZdZdZd@dAdBdCdDd	dgfd
dEgfddgfdFd
dGgfddgfddgfddgfddgfddHgfdIdJfZdddgZddddgddgdgdgdddgdgddddgddgddddddgdgdd�Zddddgd gd!d"gd#d$gd%d&d'd#d(gd%d'd(gd)d*gd+gd,gd-�	Zed.d/��Z	�fd0d1�Z
d2d3�Zd4d5�Z�fd6d7�Z
�fd8d9�Zd:d;�Z�fd<d=�Zd>d?�Z�ZS)Krz Zone class �version��short�description�UNUSEDF�target�services�ports�icmp_blocks�
masquerade�
forward_ports�
interfaces�sources�	rules_str�	protocols�source_ports�icmp_block_inversion�forward�_�-�/N�name�port�protocol�value�set)rr�zone�servicer1z
icmp-blockz	icmp-typer,zforward-port�	interface�rule�source�destinationr2zsource-portrZauditZaccept�rejectZdropZmark�limitzicmp-block-inversion�	immutableZenabledzto-portzto-addr�familyZpriority�address�mac�invert�ipset�prefix�level�typeZburst)	r5r$zforward-portr8r9r:rr;r<cCs8x&ttj�D]\}\}}||kr|SqWttjd��dS)Nz
index_of())�	enumerater�IMPORT_EXPORT_STRUCTURErrZ
UNKNOWN_ERROR)�element�iZelZdummy�rJ�/usr/lib/python3.6/zone.py�index_ofdsz
Zone.index_ofcs�tt|�j�d|_d|_d|_d|_t|_g|_	g|_
g|_g|_d|_
d|_g|_g|_g|_g|_d|_g|_g|_d|_d|_d|_dS)NrF)�superr�__init__rrrrr
r r!r"r)r#r,r$r%r*r&r'�	fw_config�rulesr(r+�combined�applied)�self)�	__class__rJrKrNks,z
Zone.__init__cCs�d|_d|_d|_d|_t|_|jdd�=|jdd�=|jdd�=|j	dd�=d|_
d|_|jdd�=|j
dd�=|jdd�=|jdd�=d|_|jdd�=|jdd�=d|_d|_d|_dS)NrF)rrrrr
r r!r"r)r#r,r$r%r*r&r'rOrPr(r+rQrR)rSrJrJrK�cleanup�s*zZone.cleanupcCs�t|j�|_t|j�|_t|j�|_t|j�|_dd�|jD�|_dd�|jD�|_dd�|jD�|_dd�|jD�|_dd�|j	D�|_	dd�|j
D�|_
dd�|jD�|_d	d�|jD�|_d
d�|j
D�|_
dd�|jD�|_dS)
z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSsg|]}t|��qSrJ)r)�.0�srJrJrK�
<listcomp>�sz'Zone.encode_strings.<locals>.<listcomp>cSs g|]\}}t|�t|�f�qSrJ)r)rV�po�prrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrZrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrIrJrJrKrX�scSs0g|](\}}}}t|�t|�t|�t|�f�qSrJ)r)rVZp1Zp2Zp3Zp4rJrJrKrX�scSs g|]\}}t|�t|�f�qSrJ)r)rVrYrZrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrIrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrWrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrWrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrWrJrJrKrX�sN)rrrrr r!r"r)r#r%r*r&r'rPr()rSrJrJrK�encode_strings�szZone.encode_stringscsN|dkr8dd�|D�|_tt|�j|dd�|jD��ntt|�j||�dS)Nr(cSsg|]}tj|d��qS))Zrule_str)rZ	Rich_Rule)rVrWrJrJrKrX�sz$Zone.__setattr__.<locals>.<listcomp>cSsg|]}t|��qSrJ)�str)rVrWrJrJrKrX�s)rPrMr�__setattr__)rSr0r3)rTrJrKr]�s zZone.__setattr__cstt|�j�}|d=|S)Nr)rMr�export_config_dict)rSZconf)rTrJrKr^�szZone.export_config_dictcCsLt||||�|dkr.|tkr*ttj|���n|dkr�xl|D]d}t|�sTttj|��|jr<xD|jj�D]6}||j	krvqf||jj
|�jkrfttjdj||���qfWq<Wn�|dk�rHx�|D]�}t
|�r�t|�r�t|�r�|jd�r�ttj|��|jr�xL|jj�D]>}||j	k�r�q||jj
|�jk�rttjdj||����qWq�WdS)Nr r&z)interface '{}' already bound to zone '{}'r'zipset:z&source '{}' already bound to zone '{}')rrrr�INVALID_TARGETrZINVALID_INTERFACErOZ	get_zonesr0Zget_zoner&�formatrrr�
startswith�INVALID_ADDRr')rSr�itemZ
all_configr7r5r9rJrJrK�
_check_config�s6



zZone._check_configcs�tt|�j|�|jd�r,ttjd|��n�|jd�rHttjd|��n�|jd�dkrhttjd|��nnd|kr�|d|j	d��}n|}t
|�t�kr�ttjd|t
|�t�|jf��|j
r�||j
j�kr�ttjd��dS)Nr/z'%s' can't start with '/'z'%s' can't end with '/'�zmore than one '/' in '%s'z'Zone of '%s' has %d chars, max is %d %sz+Zones can't have the same name as a policy.)rMr�
check_namerarr�INVALID_NAME�endswith�count�find�lenr
rQrOZget_policy_objectsZ
NAME_CONFLICT)rSr0Zchecked_name)rTrJrKrf�s,

zZone.check_namec
Cs�d|_d|_d|_d|_d|_x$|jD]}||jkr&|jj|�q&Wx$|jD]}||jkrL|jj|�qLWx$|jD]}||jkrr|jj|�qrWx$|j	D]}||j	kr�|j	j|�q�Wx$|j
D]}||j
kr�|j
j|�q�Wx$|jD]}||jkr�|jj|�q�W|j�rd|_|j
�rd|_
x(|jD]}||jk�r&|jj|��q&Wx(|jD]}||jk�rP|jj|��qPWx,|jD]"}	|jj|	�|jjt|	���qzW|j�r�d|_dS)NTr)rQ�filenamerrrr&�appendr'r!r"r)r#r,r$r%r*rPr(r\r+)
rSr5r7r9r6r1�protoZicmpr,r8rJrJrK�combine�sL





zZone.combine)rr)rr)rr)rF)r r)rr)r$F)rrrr)rr)r+F)r,F)�__name__�
__module__�__qualname__�__doc__rGZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRS�staticmethodrLrNrUr[r]r^rdrfro�
__classcell__rJrJ)rTrKr(sx


c@s$eZdZdd�Zdd�Zdd�ZdS)�zone_ContentHandlercCs"tj||�d|_d|_d|_dS)NF)rrN�_rule�_rule_errorZ	_limit_ok)rSrcrJrJrKrN szzone_ContentHandler.__init__c	Cs�tj|||�|jrdS|jj||�t|||�r6dS|dkr�d|krVtjd|d�d|krj|d|j_d|kr�tjd|d�d|kr�|d}|t	kr�t
tj|��|dkr�|t
kr�||j_�n�|d	kr�|jjr�tjd
�nd|j_�n�|dk�rh|j�rtjd
�d|_dSd|k�r.tjd�d|_dS|d|jjk�rT|jjj|d�ntjd|d��n8|dk�rf|j�r |jj�r�tjdt|j��d|_dSd}d|k�r�|dj�d$k�r�d}d}}}d|k�r�|d}d|k�r�|d}d|k�r|d}tj||||d�|j_dSd|k�rBd|k�rBtjd�dSd|k�rdd|k�rdtjd�dSd|k�r~tjd|d�d|k�r�tjd�dSd|k�r�t|d��r�t|d��r�t|d��r�t
tj|d��d|k�r$d|d}||jjk�r|jjj|�ntjd |d�d|k�r�|d}||jjk�rT|jjj|�ntjd |d�n:|d!k�r�|jj�r�tjd"�nd|j_ntjd#|�dSdS)%Nr5r0z'Ignoring deprecated attribute name='%s'rr=z,Ignoring deprecated attribute immutable='%s'r rr,zForward already set, ignoring.Tr7z$Invalid rule: interface use in rule.z Invalid interface: Name missing.z%Interface '%s' already set, ignoring.r9z:Invalid rule: More than one source in rule '%s', ignoring.FrA�yes�truer?r@rB)rAz$Invalid source: No address no ipset.z"Invalid source: Address and ipset.r>z)Ignoring deprecated attribute family='%s'z+Invalid source: Invertion not allowed here.zipset:%sz"Source '%s' already set, ignoring.zicmp-block-inversionz+Icmp-Block-Inversion already set, ignoring.zUnknown XML element '%s')ryrz)r�startElementrxrcZparser_check_element_attrsrrZwarningrrrrr_r
r r,rwr&rmr9r\�lowerrZRich_Sourcerrrrbr'r+)	rSr0�attrsr rAZaddrr@rB�entryrJrJrKr{&s�

























z zone_ContentHandler.startElementcCstj||�t||�dS)N)r�
endElementr)rSr0rJrJrKr�szzone_ContentHandler.endElementN)rprqrrrNr{rrJrJrJrKrvsprvFc
Cst�}|jd�s ttjd|��|dd	�|_|s>|j|j�||_||_|j	t
j�rZdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}	zttjd|	j���WYdd}	~	XnXWdQRX~~t�r|j�|S)
Nz.xmlz'%s' is missing .xml suffix�FTz%s/%s�rbznot a valid zone file: %s���)rrhrrrgr0rfrl�pathrar�
ETC_FIREWALLDZbuiltin�defaultrv�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_ZONEZgetExceptionrr[)
rlr�Z
no_check_namer5�handler�parserr0�fr9�msgrJrJrKr�s:




(cCs\|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�i}|j�r|jd	k�r|j|d
<|jtk�r*|j|d<|jd|�|jd
�t||�x8t|j�D]*}	|jd�|jdd|	i�|jd
��qVWx\t|j�D]N}
|jd�d|
k�r�|jdd|
dd�i�n|jdd|
i�|jd
��q�W|j�r
|jd�|jdi�|jd
�|j�r2|jd�|jdi�|jd
�|jd�|jd
�|j �|j!�~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingrrr r5�
z  r7r0zipset:r9rB�r?zicmp-block-inversionr,)"r�rlr0�os�exists�shutilZcopy2�	Exceptionr�error�dirnamerarr��mkdir�ior�rZ
startDocumentrr r
r{ZignorableWhitespacerr	r&Z
simpleElementr'r+r,rZendDocument�close)r5r��_pathr0r��dirpathr�r�r}r7r9rJrJrKr�s` 












)F)N)(�__all__Zxml.saxr�r�r�r�ZfirewallrZfirewall.functionsrrrr	r
rrZfirewall.core.baser
rZfirewall.core.io.io_objectrrrrZfirewall.core.io.policyrrrrZ
firewall.corerZfirewall.core.loggerrrZfirewall.errorsrrrvrrrJrJrJrK�<module>s$

$x|
core/io/__pycache__/icmptype.cpython-36.pyc000064400000011635150351351720014603 0ustar003

��g��@s�dddgZddljZddlZddlZddlZddlmZddlm	Z	ddl
mZmZm
Z
mZddlmZdd	lmZdd
lmZGdd�de�ZGdd
�d
e
�Zdd�Zddd�ZdS)�IcmpType�icmptype_reader�icmptype_writer�N)�config)�
u2b_if_py2)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator)�log)�errors)�
FirewallErrorcspeZdZdddddgffZdZddgZd	d	d	d
�Zddgdd
gd�Z�fdd�Zdd�Z	dd�Z
dd�Z�ZS)r�version��short�description�destinationz(sssas)�_�-N)rr�icmptype�name�ipv4�ipv6)rrcs*tt|�j�d|_d|_d|_g|_dS)Nr)�superr�__init__rrrr)�self)�	__class__��/usr/lib/python3.6/icmptype.pyr8s
zIcmpType.__init__cCs"d|_d|_d|_|jdd�=dS)Nr)rrrr)rrrr�cleanup?szIcmpType.cleanupcCs:t|j�|_t|j�|_t|j�|_dd�|jD�|_dS)z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSsg|]}t|��qSr)r)�.0�mrrr�
<listcomp>Lsz+IcmpType.encode_strings.<locals>.<listcomp>N)rrrrr)rrrr�encode_stringsEszIcmpType.encode_stringscCs2|dkr.x$|D]}|dkrttjd|��qWdS)Nrrrz'%s' not from {'ipv4'|'ipv6'})rr)r
rZINVALID_DESTINATION)rr�itemZ
all_configrrrr�
_check_configNs
zIcmpType._check_config)rr)rr)rr)
�__name__�
__module__�__qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrrr#r%�
__classcell__rr)rrr%s	c@seZdZdd�ZdS)�icmptype_ContentHandlercCs�tj|||�|jj||�|dkrTd|kr>tjd|d�d|kr�|d|j_nT|dkr^nJ|dkrhn@|dkr�x6dD].}||krv||j�d
krv|jjj	t
|��qvWdS)Nrrz'Ignoring deprecated attribute name='%s'rrrrrr�yes�true)rr)r+r,)r	�startElementr$Zparser_check_element_attrsrZwarningr�lowerr�append�str)rr�attrs�xrrrr-Ys"
z$icmptype_ContentHandler.startElementN)r&r'r(r-rrrrr*Xsr*c	Cst�}|jd�s ttjd|��|dd	�|_|j|j�||_||_|j	t
j�rVdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}zttjd|j���WYdd}~XnXWdQRX~~t�r|j�|S)
Nz.xmlz%s is missing .xml suffix�FTz%s/%s�rbznot a valid icmptype file: %s���)r�endswithr
rZINVALID_NAMErZ
check_name�filename�path�
startswithr�
ETC_FIREWALLDZbuiltin�defaultr*�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_ICMPTYPEZgetExceptionrr#)	r7r8r�handler�parserr�f�source�msgrrrrms8




(c
Cs.|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�i}|j�r|jd	k�r|j|d
<|jd|�|jd�|j�rt|jd	k�rt|jd
�|jdi�|j|j�|jd�|jd�|j�r�|jd	k�r�|jd
�|jdi�|j|j�|jd�|jd�|j�r|jd
�i}x|jD]}	d||	<�q�W|jd|�|jd�|jd�|jd�|j�|j�~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingrrr�
z  rrr+r)r8r7r�os�exists�shutilZcopy2�	Exceptionr�error�dirnamer9rr:�mkdir�ior=r
Z
startDocumentrr-ZignorableWhitespacerZ
charactersZ
endElementrrZ
simpleElementZendDocument�close)
rr8�_pathrrC�dirpathrAr?r1r2rrrr�s\ 











)N)�__all__Zxml.saxr<rGrNrIZfirewallrZfirewall.functionsrZfirewall.core.io.io_objectrrr	r
Zfirewall.core.loggerrrZfirewall.errorsr
rr*rrrrrr�<module>s

3core/io/__pycache__/firewalld_conf.cpython-36.opt-1.pyc000064400000016616150351351720016672 0ustar003

��g�5�
@s~ddlZddlZddlZddlZddlmZddlmZddl	m
Z
mZmZddddd	d
ddd
ddddg
Z
Gdd�de�ZdS)�N)�config)�log)�b2u�u2b�PY2�DefaultZone�MinimalMark�
CleanupOnExit�CleanupModulesOnExit�Lockdown�
IPv6_rpfilter�IndividualCalls�	LogDenied�AutomaticHelpers�FirewallBackend�FlushAllOnReload�RFC3964_IPv4�AllowZoneDriftingc@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dS)�firewalld_confcCsi|_g|_||_|j�dS)N)�_config�_deleted�filename�clear)�selfr�r�$/usr/lib/python3.6/firewalld_conf.py�__init__&szfirewalld_conf.__init__cCsi|_g|_dS)N)rr)rrrrr,szfirewalld_conf.clearcCs|jj�g|_dS)N)rrr)rrrr�cleanup0s
zfirewalld_conf.cleanupcCs|jj|j��S)N)r�get�strip)r�keyrrrr4szfirewalld_conf.getcCs8t|j��}t|j��|j|<||jkr4|jj|�dS)N)rrrr�remove)rr �valueZ_keyrrr�set7s
zfirewalld_conf.setcCsHd}x2|jj�D]$\}}|r$|d7}|d||f7}qWtrDt|�S|S)N��
z%s=%s)r�itemsrr)r�sr r"rrr�__str__=szfirewalld_conf.__str__cCs�|j�yt|jd�}W�n8tk
�rR}�ztjd|j|�|jdtj�|jdt	tj
��|jdtjrpdnd�|jdtjr�dnd�|jd	tj
r�dnd�|jd
tjr�dnd�|jdtjr�dnd�|jdtj�|jd
tj�|jdtj�|jdtj�r
dnd�|jdtj�r"dnd�|jdtj�r:dnd��WYdd}~XnX�x�|D]�}|�shP|j�}t|�dk�s\|dd.k�r��q\dd�|jd�D�}t|�dk�r�tjd|j���q\nr|dtk�r�tjd|j���q\nN|ddk�rtjd|j���q\n*|jj|d�dk	�r:tjd|j���q\|d|j|d<�q\W|j�|jd��s�tjdtj�|jdt	tj��|jd�}yt|�WnPttfk
�r�|dk	�r�tj d |�r�|ndtj
�|jdt	tj
��YnX|jd�}|�s|j!�d/k�rJ|dk	�r2tj d#|�r(|ndtj�|jdtj�rDdnd�|jd�}|�sj|j!�d0k�r�|dk	�r�tj d$|�r�|ndtj�|jdtj�r�dnd�|jd	�}|�s�|j!�d1k�r|dk	�r�tj d%|�r�|ndtj
�|jd	tj
�r�dnd�|jd
�}|�s"|j!�d2k�r^|dk	�rFtj d&|�r<|ndtj�|jd
tj�rXdnd�|jd�}|�s~|j!�d3k�r�|dk	�r�tj d'|�r�|ndtj�|jdtj�r�dnd�|jd�}|�s�|tj"k�r|dk	�r�tj d(|tj�|jdt	tj��|jd
�}|�s&|j!�tj#k�r\|dk	�rJtj d)|�r@|ndtj�|jd
t	tj��|jd�}|�s~|j!�tj$k�r�|dk	�r�tj d*|�r�|ndtj�|jdt	tj��|jd�}|�s�|j!�d4k�r
|dk	�r�tj d+|�r�|ndtj�|jdt	tj��|jd�}|�s*|j!�d5k�r`|dk	�rNtj d,|�rD|ndtj�|jdt	tj��|jd�}|�s�|j!�d6k�r�|dk	�r�tj d-|�r�|ndtj�|jdt	tj��dS)7N�rzFailed to load '%s': %srrr	�yes�nor
rrr
rrrrrr�r�#�;cSsg|]}|j��qSr)r)�.0�xrrr�
<listcomp>bsz'firewalld_conf.read.<locals>.<listcomp>�=�zInvalid option definition: '%s'zInvalid option: '%s'r$zMissing value: '%s'z!Duplicate option definition: '%s'z0DefaultZone is not set, using default value '%s'z7MinimalMark '%s' is not valid, using default value '%d'�false�truez7CleanupOnExit '%s' is not valid, using default value %sz>CleanupModulesOnExit '%s' is not valid, using default value %sz2Lockdown '%s' is not valid, using default value %sz7IPv6_rpfilter '%s' is not valid, using default value %sz9IndividualCalls '%s' is not valid, using default value %sz3LogDenied '%s' is invalid, using default value '%s'z:AutomaticHelpers '%s' is not valid, using default value %sz9FirewallBackend '%s' is not valid, using default value %sz:FlushAllOnReload '%s' is not valid, using default value %sz6RFC3964_IPv4 '%s' is not valid, using default value %sz;AllowZoneDrifting '%s' is not valid, using default value %s)r-r.)r+r4r*r5)r+r4r*r5)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)%r�openr�	Exceptionr�errorr#rZ
FALLBACK_ZONE�strZFALLBACK_MINIMAL_MARKZFALLBACK_CLEANUP_ON_EXITZ FALLBACK_CLEANUP_MODULES_ON_EXITZFALLBACK_LOCKDOWNZFALLBACK_IPV6_RPFILTERZFALLBACK_INDIVIDUAL_CALLSZFALLBACK_LOG_DENIEDZFALLBACK_AUTOMATIC_HELPERSZFALLBACK_FIREWALL_BACKENDZFALLBACK_FLUSH_ALL_ON_RELOADZFALLBACK_RFC3964_IPV4ZFALLBACK_ALLOW_ZONE_DRIFTINGr�len�split�
valid_keysrr�close�int�
ValueError�	TypeErrorZwarning�lowerZLOG_DENIED_VALUESZAUTOMATIC_HELPERS_VALUESZFIREWALL_BACKEND_VALUES)r�f�msg�lineZpairr"rrr�readFs
























zfirewalld_conf.readc:Cs�t|j�dkrdSg}tjjtj�s2tjtjd�y.tj	ddtjj
|j�tjj|j�dd�}Wn2t
k
r�}ztjd|��WYdd}~XnXd}d}ytj|jdd	d
�}WnPt
k
�r}z0tjj|j�r�tjd|j|f��nd}WYdd}~X�n6X�x0|D�]&}|�sP|jd�}t|�dk�rH|�s2|jd�d
}n�|ddk�rpd}|j|�|jd�n�|jd�}t|�dk�r�d}|j|d��q|dj�}	|dj�}
|	|k�r.|	|jk�r�|j|	|
k�r�d}|jd|	|j|	f�d
}n$|	|jk�rd
}nd}|j|d�|j|	�nd
}�qWt|j�dk�r�x^|jj�D]P\}	}
|	|k�rj�qT|	dk�rx�qT|�s�|jd�d
}|jd|	|
f�d
}�qTW|�r�|j�|j�|�s�tj|j�dStjj|j��r@ytj|jd|j�WnBt
k
�r>}z$tj|j�td|j|f��WYdd}~XnXytj|j|j�WnBt
k
�r�}z$tj|j�td|j|f��WYdd}~XnXtj|jd�dS)Nr,i�Zwtz%s.F)�mode�prefix�dir�deletez!Failed to open temporary file: %sZrtzUTF-8)rF�encodingzFailed to open '%s': %sr%Trr-r2r3z%s=%s
rrz%s.oldzBackup of '%s' failed: %szFailed to create '%s': %si�)rr) r:r�os�path�existsrZ
ETC_FIREWALLD�mkdir�tempfileZNamedTemporaryFile�basenamer�dirnamer7rr8�ior6r�writer;r�appendr&r=r!�name�shutilZcopy2�IOErrorZmove�chmod)r�doneZ	temp_filerCZmodified�emptyrBrD�pr r"rrrrS�s�









$$zfirewalld_conf.writeN)�__name__�
__module__�__qualname__rrrrr#r(rErSrrrrr%s	r)Zos.pathrKrRrOrVZfirewallrZfirewall.core.loggerrZfirewall.functionsrrrr<�objectrrrrr�<module>score/io/__pycache__/icmptype.cpython-36.opt-1.pyc000064400000011635150351351720015542 0ustar003

��g��@s�dddgZddljZddlZddlZddlZddlmZddlm	Z	ddl
mZmZm
Z
mZddlmZdd	lmZdd
lmZGdd�de�ZGdd
�d
e
�Zdd�Zddd�ZdS)�IcmpType�icmptype_reader�icmptype_writer�N)�config)�
u2b_if_py2)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator)�log)�errors)�
FirewallErrorcspeZdZdddddgffZdZddgZd	d	d	d
�Zddgdd
gd�Z�fdd�Zdd�Z	dd�Z
dd�Z�ZS)r�version��short�description�destinationz(sssas)�_�-N)rr�icmptype�name�ipv4�ipv6)rrcs*tt|�j�d|_d|_d|_g|_dS)Nr)�superr�__init__rrrr)�self)�	__class__��/usr/lib/python3.6/icmptype.pyr8s
zIcmpType.__init__cCs"d|_d|_d|_|jdd�=dS)Nr)rrrr)rrrr�cleanup?szIcmpType.cleanupcCs:t|j�|_t|j�|_t|j�|_dd�|jD�|_dS)z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSsg|]}t|��qSr)r)�.0�mrrr�
<listcomp>Lsz+IcmpType.encode_strings.<locals>.<listcomp>N)rrrrr)rrrr�encode_stringsEszIcmpType.encode_stringscCs2|dkr.x$|D]}|dkrttjd|��qWdS)Nrrrz'%s' not from {'ipv4'|'ipv6'})rr)r
rZINVALID_DESTINATION)rr�itemZ
all_configrrrr�
_check_configNs
zIcmpType._check_config)rr)rr)rr)
�__name__�
__module__�__qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrrr#r%�
__classcell__rr)rrr%s	c@seZdZdd�ZdS)�icmptype_ContentHandlercCs�tj|||�|jj||�|dkrTd|kr>tjd|d�d|kr�|d|j_nT|dkr^nJ|dkrhn@|dkr�x6dD].}||krv||j�d
krv|jjj	t
|��qvWdS)Nrrz'Ignoring deprecated attribute name='%s'rrrrrr�yes�true)rr)r+r,)r	�startElementr$Zparser_check_element_attrsrZwarningr�lowerr�append�str)rr�attrs�xrrrr-Ys"
z$icmptype_ContentHandler.startElementN)r&r'r(r-rrrrr*Xsr*c	Cst�}|jd�s ttjd|��|dd	�|_|j|j�||_||_|j	t
j�rVdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}zttjd|j���WYdd}~XnXWdQRX~~t�r|j�|S)
Nz.xmlz%s is missing .xml suffix�FTz%s/%s�rbznot a valid icmptype file: %s���)r�endswithr
rZINVALID_NAMErZ
check_name�filename�path�
startswithr�
ETC_FIREWALLDZbuiltin�defaultr*�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_ICMPTYPEZgetExceptionrr#)	r7r8r�handler�parserr�f�source�msgrrrrms8




(c
Cs.|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�i}|j�r|jd	k�r|j|d
<|jd|�|jd�|j�rt|jd	k�rt|jd
�|jdi�|j|j�|jd�|jd�|j�r�|jd	k�r�|jd
�|jdi�|j|j�|jd�|jd�|j�r|jd
�i}x|jD]}	d||	<�q�W|jd|�|jd�|jd�|jd�|j�|j�~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingrrr�
z  rrr+r)r8r7r�os�exists�shutilZcopy2�	Exceptionr�error�dirnamer9rr:�mkdir�ior=r
Z
startDocumentrr-ZignorableWhitespacerZ
charactersZ
endElementrrZ
simpleElementZendDocument�close)
rr8�_pathrrC�dirpathrAr?r1r2rrrr�s\ 











)N)�__all__Zxml.saxr<rGrNrIZfirewallrZfirewall.functionsrZfirewall.core.io.io_objectrrr	r
Zfirewall.core.loggerrrZfirewall.errorsr
rr*rrrrrr�<module>s

3core/io/__pycache__/service.cpython-36.opt-1.pyc000064400000020377150351351720015353 0ustar003

��g�2�@s�dddgZddljZddlZddlZddlZddlmZddlm	Z	ddl
mZmZm
Z
mZmZmZmZmZddlmZdd	lmZdd
lmZGdd�de�ZGdd
�d
e
�Zdd�Zddd�ZdS)�Service�service_reader�service_writer�N)�config)�
u2b_if_py2)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator�
check_port�check_tcpudp�check_protocol�
check_address)�log)�errors)�
FirewallErrorcs�eZdZd d!d"dd#gfddgfdddifddgfd	d$gfd
dgfddgff
Zdd
gZdddd�Zddgddgdgdgddgddgdgdgd�Z�fdd�Zdd�Zdd�Z	dd�Z
�ZS)%r�version��short�description�ports�modules�destination�	protocols�source_ports�includes�helpers�_�-N)rr�service�name�port�protocol�value�ipv4�ipv6r)rr!r"�modulerzsource-port�include�helpercsNtt|�j�d|_d|_d|_g|_g|_g|_i|_	g|_
g|_g|_dS)Nr)
�superr�__init__rrrrrrrrrr)�self)�	__class__��/usr/lib/python3.6/service.pyr*DszService.__init__cCshd|_d|_d|_|jdd�=|jdd�=|jdd�=|jj�|jdd�=|j	dd�=|j
dd�=dS)Nr)rrrrrrr�clearrrr)r+r-r-r.�cleanupQs
zService.cleanupcCs�t|j�|_t|j�|_t|j�|_dd�|jD�|_dd�|jD�|_dd�|jj�D�|_dd�|jD�|_dd�|j	D�|_	dd�|j
D�|_
d	d�|jD�|_d
S)z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSs g|]\}}t|�t|�f�qSr-)r)�.0�po�prr-r-r.�
<listcomp>dsz*Service.encode_strings.<locals>.<listcomp>cSsg|]}t|��qSr-)r)r1�mr-r-r.r4escSsi|]\}}t|�t|��qSr-)r)r1�k�vr-r-r.�
<dictcomp>fsz*Service.encode_strings.<locals>.<dictcomp>cSsg|]}t|��qSr-)r)r1r3r-r-r.r4gscSs g|]\}}t|�t|�f�qSr-)r)r1r2r3r-r-r.r4hscSsg|]}t|��qSr-)r)r1�sr-r-r.r4jscSsg|]}t|��qSr-)r)r1r9r-r-r.r4ksN)rrrrrrr�itemsrrrr)r+r-r-r.�encode_strings]szService.encode_stringscCs:|dkrJx>|D]6}|ddkr8t|d�t|d�qt|d�qWn�|dkrjx�|D]}t|�qXWn�|dkr�x�|D]}t|d�t|d�qxWn�|dkr�x�|D]*}|dkr�ttjd
|��t|||�q�Wn^|dk�r6xR|D]J}|jd��r|jdd�}d
|k�r|jd
d�}t	|�dkr�ttj
|��q�WdS)Nrrr�rrrr$r%z'%s' not in {'ipv4'|'ipv6'}r�
nf_conntrack_rr�)r$r%)rrr
rrZINVALID_DESTINATIONr�
startswith�replace�lenZINVALID_MODULE)r+r�itemZ
all_configr!�protorr&r-r-r.�
_check_configms8






zService._check_config)rr)rr)rr)rr)rr)�__name__�
__module__�__qualname__ZIMPORT_EXPORT_STRUCTUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSr*r0r;rD�
__classcell__r-r-)r,r.r&s4


c@seZdZdd�ZdS)�service_ContentHandlercCs0tj|||�|jj||�|dkrTd|kr<tjd|d�d|krP|d|j_�n�|dkr`�n�|dkrl�n�|dk�r$|ddkr�t|d�t|d	�|d|d	f}||jj	kr�|jj	j
|�ntjd
|d|d	�nBt|d	�|d	|jjk�r|jjj
|d	�ntjd|d	��n|d	k�rtt|d�|d|jjk�r`|jjj
|d�ntjd|d��n�|d
k�r�t|d�t|d	�|d|d	f}||jj
k�r�|jj
j
|�ntjd|d|d	��nN|dk�r>xRdD]J}||k�r�t|||�||jjk�r&tjd|�n|||jj|<�q�Wn�|dk�r�|d}|jd��r~|jdd�}d|k�r~|jdd�}||jjk�r�|jjj
|�ntjd|�n�|dk�r�|d|jjk�r�|jjj
|d�ntjd|d�n@|dk�r,|d|jjk�r|jjj
|d�ntjd|d�dS)Nrr z'Ignoring deprecated attribute name='%s'rrrr!rr"z#Port '%s/%s' already set, ignoring.z$Protocol '%s' already set, ignoring.r#zsource-portz)SourcePort '%s/%s' already set, ignoring.rr$r%z2Destination address for '%s' already set, ignoringr&r=rrz"Module '%s' already set, ignoring.r'z#Include '%s' already set, ignoring.r(z"Helper '%s' already set, ignoring.)r$r%)r	�startElementrBZparser_check_element_attrsrZwarningrrrr�appendr
rrrrr?r@rrr)r+r �attrs�entry�xr&r-r-r.rJ�s�










z#service_ContentHandler.startElementN)rErFrGrJr-r-r-r.rI�srIc	Cst�}|jd�s ttjd|��|dd	�|_|j|j�||_||_|j	t
j�rVdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}zttjd|j���WYdd}~XnXWdQRX~~t�r|j�|S)
Nz.xmlz'%s' is missing .xml suffix�FTz%s/%s�rbznot a valid service file: %s���)r�endswithrrZINVALID_NAMEr Z
check_name�filename�pathr?r�
ETC_FIREWALLDZbuiltin�defaultrI�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_SERVICEZgetExceptionrr;)	rSrTr�handler�parserr �f�source�msgr-r-r.r�s8




(cCsr|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�i}|j�r|jd	k�r|j|d
<|jd|�|jd�|j�rt|jd	k�rt|jd
�|jdi�|j|j�|jd�|jd�|j�r�|jd	k�r�|jd
�|jdi�|j|j�|jd�|jd�x>|jD]4}	|jd
�|jd|	d|	dd��|jd��q�Wx4|jD]*}
|jd
�|jdd|
i�|jd��qWx>|jD]4}	|jd
�|jd|	d|	dd��|jd��q<Wx4|jD]*}|jd
�|jdd|i�|jd��q|Wt|j �dk�r�|jd
�|jd|j �|jd�x4|j!D]*}|jd
�|jdd|i�|jd��q�Wx4|j"D]*}
|jd
�|jdd|
i�|jd��qW|jd�|jd�|j#�|j$�~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingrrr�
z  rrr!rr<)r!r"r"r#zsource-portr&r rr'r()%rTrSr �os�exists�shutilZcopy2�	Exceptionr�error�dirnamer?rrU�mkdir�iorXr
Z
startDocumentrrJZignorableWhitespacerZ
charactersZ
endElementrrZ
simpleElementrrrrArrrZendDocument�close)rrT�_pathr r^�dirpathr\rZrLr!r"r&r'r(r-r-r.rs� 

















)N)�__all__Zxml.saxrWrbrirdZfirewallrZfirewall.functionsrZfirewall.core.io.io_objectrrr	r
rrr
rZfirewall.core.loggerrrZfirewall.errorsrrrIrrr-r-r-r.�<module>s

(mQcore/io/__pycache__/helper.cpython-36.opt-1.pyc000064400000013451150351351720015165 0ustar003

��g� �@s�dddgZddljZddlZddlZddlZddlmZddlm	Z	ddl
mZmZm
Z
mZmZmZddlmZdd	lmZdd
lmZGdd�de�ZGdd
�d
e
�Zdd�Zddd�ZdS)�Helper�
helper_reader�
helper_writer�N)�config)�
u2b_if_py2)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator�
check_port�check_tcpudp)�log)�errors)�
FirewallErrorcs�eZdZddddddd gffZdZd	d
gZdddgd�Zd
ddgddgd�Z�fdd�Zdd�Z	dd�Z
dd�Zdd�Z�Z
S)!r�version��short�description�family�module�portsz(sssssa(ss))�-�.N)rr�helper�name�port�protocol)rrcs6tt|�j�d|_d|_d|_d|_d|_g|_dS)Nr)	�superr�__init__rrrrrr)�self)�	__class__��/usr/lib/python3.6/helper.pyr;szHelper.__init__cCs.d|_d|_d|_d|_d|_|jdd�=dS)Nr)rrrrrr)rr!r!r"�cleanupDszHelper.cleanupcCsRt|j�|_t|j�|_t|j�|_t|j�|_t|j�|_dd�|jD�|_dS)z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSs g|]\}}t|�t|�f�qSr!)r)�.0ZpoZprr!r!r"�
<listcomp>Usz)Helper.encode_strings.<locals>.<listcomp>N)rrrrrrr)rr!r!r"�encode_stringsLszHelper.encode_stringscCs(ddg}||kr$ttjd||f��dS)NZipv4Zipv6z'%s' not in '%s')rrZINVALID_IPV)rZipvZipvsr!r!r"�	check_ipvWszHelper.check_ipvcCsz|dkr0xl|D]}t|d�t|d�qWnF|dkrv|jd�sRttjd|��t|jdd��dkrvttjd|��dS)	Nrr�r�
nf_conntrack_z('%s' does not start with 'nf_conntrack_'rzModule name '%s' too short)rr�
startswithrr�INVALID_MODULE�len�replace)rr�itemZ
all_configrr!r!r"�
_check_config]s


zHelper._check_config)rr)rr)rr)rr)rr)rr)�__name__�
__module__�__qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr#r&r'r/�
__classcell__r!r!)r r"r&s$
	c@seZdZdd�ZdS)�helper_ContentHandlercCs>tj|||�|jj||�|dkr�d|kr8|d|j_d|kr\|jj|d�|d|j_d|kr�|djd�s�tt	j
d|d��t|djdd��dkr�tt	j
d	|d��|d|j_
nz|d
kr�np|dkr�nf|dk�r:t|d�t|d
�|d|d
f}||jjk�r$|jjj|�ntjd|d|d
�dS)Nrrrrr)z('%s' does not start with 'nf_conntrack_'rr(zModule name '%s' too shortrrrrz#Port '%s/%s' already set, ignoring.)r	�startElementr.Zparser_check_element_attrsrr'rr*rrr+r,r-rrrr�appendr
Zwarning)rr�attrs�entryr!r!r"r5ns>
z"helper_ContentHandler.startElementN)r0r1r2r5r!r!r!r"r4msr4c	Cst�}|jd�s ttjd|��|dd	�|_|j|j�||_||_|j	t
j�rVdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}zttjd|j���WYdd}~XnXWdQRX~~t�r|j�|S)
Nz.xmlz'%s' is missing .xml suffix�FTz%s/%s�rbznot a valid helper file: %s���)r�endswithrrZINVALID_NAMErZ
check_name�filename�pathr*r�
ETC_FIREWALLDZbuiltin�defaultr4�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_HELPERZgetExceptionrr&)	r=r>r�handler�parserr�f�source�msgr!r!r"r�s8




(c
CsP|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�i}|j|d	<|j�r|jd
k�r|j|d<|j�r<|jd
k�r<|j|d<|jd
|�|jd�|j�r�|jd
k�r�|jd�|jdi�|j|j�|jd�|jd�|j�r�|jd
k�r�|jd�|jdi�|j|j�|jd�|jd�x>|jD]4}	|jd�|jd|	d|	dd��|jd��q�W|jd
�|jd�|j�|j�~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingrrrrr�
z  rrrrr()rr) r>r=r�os�exists�shutilZcopy2�	Exceptionr
�error�dirnamer*rr?�mkdir�iorBr
Z
startDocumentrrrr5ZignorableWhitespacerZ
charactersZ
endElementrrZ
simpleElementZendDocument�close)
rr>�_pathrrH�dirpathrFrDr7rr!r!r"r�s\ 












)N)�__all__Zxml.saxrArLrSrNZfirewallrZfirewall.functionsrZfirewall.core.io.io_objectrrr	r
rrZfirewall.core.loggerr
rZfirewall.errorsrrr4rrr!r!r!r"�<module>s

 G#core/io/__pycache__/lockdown_whitelist.cpython-36.opt-1.pyc000064400000022550150351351720017622 0ustar003

��g�1�@s�ddljZddlZddlZddlZddlmZddlmZm	Z	m
Z
mZddlm
Z
ddlmZmZmZmZmZmZddlmZddlmZGdd	�d	e
�ZGd
d�de	�ZdS)�N)�config)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator)�log)�uniqify�	checkUser�checkUid�checkCommand�checkContext�
u2b_if_py2)�errors)�
FirewallErrorc@seZdZdd�Zdd�ZdS)�!lockdown_whitelist_ContentHandlercCstj||�d|_dS)NF)r�__init__�	whitelist)�self�item�r�(/usr/lib/python3.6/lockdown_whitelist.pyr%sz*lockdown_whitelist_ContentHandler.__init__cCsVtj|||�|jj||�|dkr@|jr6ttjd��d|_�n|dkrr|js\tj	d�dS|d}|jj
|�n�|dkr�|js�tj	d�dSd	|kr�yt|d	�}Wn&tk
r�tj	d
|d	�dSX|jj
|�nd|kr�|jj|d�n\|dk�r@|j�stj	d�dSd
|k�r.tj	d�dS|jj|d
�ntj	d|�dSdS)NrzMore than one whitelist.T�commandz)Parse Error: command outside of whitelist�name�userz&Parse Error: user outside of whitelist�idz"Parse Error: %s is not a valid uid�selinuxz)Parse Error: selinux outside of whitelist�contextzParse Error: no contextzUnknown XML element %s)r�startElementrZparser_check_element_attrsrrrZPARSE_ERRORr�error�add_command�int�
ValueError�add_uid�add_user�add_context)rrZattrsr�uidrrrr)sJ






z.lockdown_whitelist_ContentHandler.startElementN)�__name__�
__module__�__qualname__rrrrrrr$srcs4eZdZdZddgfddgfddgfddgffZdZd	gZd
dgd
dgd
�ZdddgiZ�fdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�Zd<d=�Zd>d?�Z d@dA�Z!dBdC�Z"�Z#S)D�LockdownWhitelistz LockdownWhitelist class �commands��contexts�users�uidsrz
(asasasai)�_Nrr)rrrrrrcs6tt|�j�||_d|_g|_g|_g|_g|_dS)N)	�superr)r�filename�parserr*r,r-r.)rr1)�	__class__rrrnszLockdownWhitelist.__init__cCs�|d
kr.x�|D]}|j||dd�|�qWnv|dkrLt|�s�ttj|��nX|dkrjt|�s�ttj|��n:|dkr�t|�s�ttj|��n|d	kr�t	|�s�ttj
|��dS)Nr*r,r-r.�rrrr%)r*r,r-r.���)�
_check_configrrr�INVALID_COMMANDr�INVALID_CONTEXTr	�INVALID_USERr
�INVALID_UID)rrrZ
all_config�xrrrr6ys
zLockdownWhitelist._check_configcCs4|jdd�=|jdd�=|jdd�=|jdd�=dS)N)r*r,r-r.)rrrr�cleanup�szLockdownWhitelist.cleanupcCs:dd�|jD�|_dd�|jD�|_dd�|jD�|_dS)z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSsg|]}t|��qSr)r
)�.0r;rrr�
<listcomp>�sz4LockdownWhitelist.encode_strings.<locals>.<listcomp>cSsg|]}t|��qSr)r
)r=r;rrrr>�scSsg|]}t|��qSr)r
)r=r;rrrr>�sN)r*r,r-)rrrr�encode_strings�sz LockdownWhitelist.encode_stringscCs@t|�sttj|��||jkr,|jj|�nttjd|��dS)Nz!Command "%s" already in whitelist)rrrr7r*�append�ALREADY_ENABLED)rrrrrr�s
zLockdownWhitelist.add_commandcCs,||jkr|jj|�nttjd|��dS)NzCommand "%s" not in whitelist.)r*�removerr�NOT_ENABLED)rrrrr�remove_command�s
z LockdownWhitelist.remove_commandcCs
||jkS)N)r*)rrrrr�has_command�szLockdownWhitelist.has_commandcCsBx<|jD]2}|jd�r.|j|dd��r:dSq||krdSqWdS)N�*r4TFr5)r*�endswith�
startswith)rrZ_commandrrr�
match_command�s
zLockdownWhitelist.match_commandcCs|jS)N)r*)rrrr�get_commands�szLockdownWhitelist.get_commandscCsDt|�sttjt|���||jkr0|jj|�nttjd|��dS)NzUid "%s" already in whitelist)r
rrr:�strr.r@rA)rr%rrrr"�s
zLockdownWhitelist.add_uidcCs,||jkr|jj|�nttjd|��dS)NzUid "%s" not in whitelist.)r.rBrrrC)rr%rrr�
remove_uid�s
zLockdownWhitelist.remove_uidcCs
||jkS)N)r.)rr%rrr�has_uid�szLockdownWhitelist.has_uidcCs
||jkS)N)r.)rr%rrr�	match_uid�szLockdownWhitelist.match_uidcCs|jS)N)r.)rrrr�get_uids�szLockdownWhitelist.get_uidscCs@t|�sttj|��||jkr,|jj|�nttjd|��dS)NzUser "%s" already in whitelist)r	rrr9r-r@rA)rrrrrr#�s
zLockdownWhitelist.add_usercCs,||jkr|jj|�nttjd|��dS)NzUser "%s" not in whitelist.)r-rBrrrC)rrrrr�remove_user�s
zLockdownWhitelist.remove_usercCs
||jkS)N)r-)rrrrr�has_user�szLockdownWhitelist.has_usercCs
||jkS)N)r-)rrrrr�
match_user�szLockdownWhitelist.match_usercCs|jS)N)r-)rrrr�	get_users�szLockdownWhitelist.get_userscCs@t|�sttj|��||jkr,|jj|�nttjd|��dS)Nz!Context "%s" already in whitelist)rrrr8r,r@rA)rrrrrr$"s
zLockdownWhitelist.add_contextcCs,||jkr|jj|�nttjd|��dS)NzContext "%s" not in whitelist.)r,rBrrrC)rrrrr�remove_context,s
z LockdownWhitelist.remove_contextcCs
||jkS)N)r,)rrrrr�has_context3szLockdownWhitelist.has_contextcCs
||jkS)N)r,)rrrrr�
match_context6szLockdownWhitelist.match_contextcCs|jS)N)r,)rrrr�get_contexts9szLockdownWhitelist.get_contextscCs�|j�|jjd�s&ttjd|j��t|�}tj�}|j	|�y|j
|j�Wn8tjk
r�}zttjd|j
���WYdd}~XnX~~tr�|j�dS)Nz.xmlz'%s' is missing .xml suffixzNot a valid file: %s)r<r1rGrrZINVALID_NAMEr�saxZmake_parserZsetContentHandler�parseZSAXParseExceptionZINVALID_TYPEZgetExceptionrr?)r�handlerr2�msgrrr�read>s"
zLockdownWhitelist.readcCs�tjj|j�r\ytj|jd|j�Wn4tk
rZ}ztd|j|f��WYdd}~XnXtjjtj	�sxtj
tj	d�tj|jddd�}t
|�}|j�|jdi�|jd�x6t|j�D](}|jd	�|jd
d|i�|jd�q�Wx:t|j�D],}|jd	�|jdd
t|�i�|jd�q�Wx8t|j�D]*}|jd	�|jdd|i�|jd��q0Wx8t|j�D]*}|jd	�|jdd|i�|jd��qjW|jd�|jd�|j�|j�~dS)Nz%s.oldzBackup of '%s' failed: %si�ZwtzUTF-8)�mode�encodingr�
z  rrrrrr)�os�path�existsr1�shutilZcopy2�	Exception�IOErrorrZ
ETC_FIREWALLD�mkdir�io�openrZ
startDocumentrZignorableWhitespacerr*Z
simpleElementr.rKr-r,Z
endElementZendDocument�close)rr[�frZrr%rrrrr�writeQsB$






zLockdownWhitelist.write)$r&r'r(�__doc__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr6r<r?rrDrErIrJr"rLrMrNrOr#rPrQrRrSr$rTrUrVrWr\rk�
__classcell__rr)r3rr)WsL

	


1
r))Zxml.saxrXr`rgrcZfirewallrZfirewall.core.io.io_objectrrrrZfirewall.core.loggerrZfirewall.functionsrr	r
rrr
rZfirewall.errorsrrr)rrrr�<module>s
 3core/io/__pycache__/policy.cpython-36.pyc000064400000051212150351351720014243 0ustar003

��gϢ�@s dddgZddljZddlZddlZddlZddlmZddlm	Z	m
Z
ddlmZmZm
Z
ddlmZmZmZdd	lmZmZmZmZmZmZdd
lmZddlmZddlmZdd
lmZdd�Z dd�Z!dd�Z"dd�Z#dd�Z$Gdd�de�Z%Gdd�de�Z&ddd�Z'ddd�Z(dS) �Policy�
policy_reader�
policy_writer�N)�config)�checkIP�checkIP6)�uniqify�max_policy_name_len�portStr)�DEFAULT_POLICY_TARGET�POLICY_TARGETS�DEFAULT_POLICY_PRIORITY)�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator�
check_port�check_tcpudp�check_protocol)�rich)�log)�errors)�
FirewallErrorc	Cs�|dkr�n�|dkr�n�|dkr�|jr`|jjrJtjdt|j��d|_dStj|d�|j_dS|d|jj	kr�|jj	j
|d�ntjd|d��n|dk�rN|jr�|jjr�tjdt|j��d|_dStj|d|d	�|j_dSt|d�t
|d	�t|dd
�|d	f}||jjk�r4|jjj
|�ntjd|d|d	��nN|d	k�r�|j�r�|jj�r�tjdt|j��d|_dStj|d�|j_nBt|d�|d|jjk�r�|jjj
|d�ntjd
|d��n�|dk�rh|j�r.|jj�rtjdt|j��d|_dStj|d�|j_dS|d|jjk�rT|jjj
|d�ntjd|d��n4|dk�r�|j�r�|jj�r�tjdt|j��d|_dStj|d�|j_dStjd|d��n�|dk�r2|j�r|jj�rtjdt|j��d|_dStj�|j_n|jj�r&tjd�nd|j_�nj|dk�r�d}d|k�rR|d}d}d|k�rh|d}|j�r�|jj�r�tjdt|j��d|_dStj|d|d	||�|j_dSt|d�t
|d	�|�r�t|�|�r
t|��r
t|��r
ttjd|��t|dd
�|d	t|d
�t|�f}||jjk�rL|jjj
|�n6tjd|d|d	|�rld|nd|�r|d|nd��n|dk�r@|j�r�|jj�r�tjdt|j��d|_dStj|d|d	�|j_dSt|d�t
|d	�t|dd
�|d	f}||jj k�r&|jj j
|�ntjd|d|d	��n\|dk�r�|j�sftjd�d|_dS|jj!�r�tjd t|j��dSd!}d}d"|k�r�|d"}d}d#|k�r�|d#}d$|k�r�|d$j"�dLk�r�d}tj#|||�|j_!�n�|dMk�r�|j�stjd+�d|_dS|jj$�r0tjd,�d|_dS|d'k�rHtj%�|j_$nh|d(k�rxd}	d-|k�rh|d-}	tj&|	�|j_$n8|d)k�r�tj'�|j_$n |d*k�r�|d.}
tj(|
�|j_$|jj$|_)�n�|d/k�r^|j�s�tjd0�dS|jj�r�tjd1�dSd}d2|k�r*|d2}|dNk�r*tjd;�d|_dSd<|k�r<|d<nd}tj*||�|j_|jj|_)�n>|d=k�r�|j�s~tjd>�dS|jj+�r�tjd?t|j��d|_dStj,�|j_+|jj+|_)n�|d@k�r,d}
dA}dB|k�r|dB}
|
dOk�rtjdE|dB�d|_dSdF|k�rt-|dF�}tj.|
|dG�|_np|dHk�r�|j)�sRtjdI�d|_dS|j)j/�rxtjdJt|j��d|_dS|d}tj0||j1dK��|j)_/nd!SdS)PN�short�description�servicez;Invalid rule: More than one element in rule '%s', ignoring.T�namez#Service '%s' already set, ignoring.�port�protocol�-z#Port '%s/%s' already set, ignoring.�valuez$Protocol '%s' already set, ignoring.z
icmp-blockz&icmp-block '%s' already set, ignoring.z	icmp-typez-Invalid rule: icmp-block '%s' outside of rule�
masqueradez!Masquerade already set, ignoring.zforward-port�zto-portzto-addrz#to-addr '%s' is not a valid addressz-Forward port %s/%s%s%s already set, ignoring.z >%sz @%szsource-portz*Source port '%s/%s' already set, ignoring.�destinationz)Invalid rule: Destination outside of rulez?Invalid rule: More than one destination in rule '%s', ignoring.F�address�ipset�invert�yes�true�accept�reject�drop�markz$Invalid rule: Action outside of rulez"Invalid rule: More than one action�type�setrz!Invalid rule: Log outside of rulezInvalid rule: More than one log�level�emerg�alert�crit�error�warning�notice�info�debugzInvalid rule: Invalid log level�prefix�auditz#Invalid rule: Audit outside of rulez9Invalid rule: More than one audit in rule '%s', ignoring.�ruler�family�ipv4�ipv6z&Invalid rule: Rule family "%s" invalid�priority)r:r=�limitz4Invalid rule: Limit outside of action, log and auditz9Invalid rule: More than one limit in rule '%s', ignoring.�burst)r&r')r(r)r*r+)r/r0r1r2r3r4r5r6)r;r<)2�_rule�elementrr3�str�_rule_errorr�Rich_Service�item�services�append�	Rich_Portrrr
�ports�
Rich_Protocolr�	protocols�Rich_IcmpBlock�icmp_blocks�
Rich_IcmpType�Rich_Masquerader �Rich_ForwardPortrrrr�INVALID_ADDR�
forward_ports�Rich_SourcePort�source_portsr"�lowerZRich_Destination�action�Rich_Accept�Rich_Reject�	Rich_Drop�	Rich_Mark�	_limit_okZRich_Logr8Z
Rich_Audit�int�	Rich_Ruler>Z
Rich_Limit�get)�objr�attrs�entry�to_portZto_addrr%r#r$Z_typeZ_setr.r7r:r=r�rc�/usr/lib/python3.6/policy.py�common_startElements�


















































recCs�|dkr�|js�y|jj�Wn6tk
rR}ztjd|t|j��WYdd}~XnLXt|j�|jjkr�|jj	j
|j�|jjj
t|j��ntjdt|j��d|_d|_n|dkr�d|_dS)Nr9z%s: %sz Rule '%s' already set, ignoring.Fr(r)r*r+rr8)r(r)r*r+rr8)rCr@Zcheck�	Exceptionrr3rBrE�	rules_str�rulesrGr[)r_r�ercrcrd�common_endElements&rjcCs�t|t�rdnd}|dkrT|jrT|jj�}x$|D]}||kr0ttjd|��q0W�n�|dkr�x$|D]}t|d�t|d�qbW�nb|dkr�x|D]}t	|�q�W�n@|d	kr�|jr�|jj
�}	x$|D]}
|
|	kr�ttjd
|
��q�W�n�|dk�r�x�|D]�}t|d�t|d�|d�r>|d
�r>ttjd|��|d�rTt|d�|d
r�t
|d
�r�t|d
�r�ttjd|d
��q�W�nT|dk�r�x&|D]}t|d�t|d��q�W�n|dk�r�x|D�]}tj|d�}
|j�r�|
j�r�t|
jtj��st|
jtj��r�|jj
�}	|
jj|	k�rLttjd
|
jj��nH|
j�r�|jj|
jj�}|j�r�|
j|jk�r�ttjd|
j|
jjf��nL|j�r�t|
jtj��r�|jj�}|
jj|k�r�ttjdj||j|
jj����q�WdS)NrZZonerFz '%s' not among existing servicesrIr�rKrMz"'%s' not among existing icmp typesrR��z$'%s' is missing to-port AND to-addr z#to-addr '%s' is not a valid addressrTrg�
rich_rules)�rule_strz3rich rule family '%s' conflicts with icmp type '%s'z){} '{}': '{}' not among existing services)rgrn)�
isinstancer�	fw_configZget_servicesrrZINVALID_SERVICErrrZ
get_icmptypesZINVALID_ICMPTYPE�INVALID_FORWARDrrrQrr]rArLrNrr:Zget_icmptyper"rD�format)r_rrE�
all_configZobj_typeZexisting_servicesrr�protoZexisting_icmptypesZicmptype�fwd_portr9Zobj_richZictrcrcrd�common_check_config2s�












 

rwcCs0d|ji}|j}|dk	r ||d<|jd|�dS)Nrr?r>)rr?�
simpleElement)�handlerr>�dr?rcrcrd�_handler_add_rich_limitxs

r{cCs�|jrF|jdkrF|jd�|jdi�|j|j�|jd�|jd�|jr�|jdkr�|jd�|jdi�|j|j�|jd�|jd�x6t|j�D](}|jd�|jdd|i�|jd�q�Wx@t|j	�D]2}|jd�|jd|d	|d
d��|jd�q�Wx8t|j
�D]*}|jd�|jdd
|i�|jd��qWx8t|j�D]*}|jd�|jdd|i�|jd��qLW|j�r�|jd�|jdi�|jd�x�t|j
�D]�}|jd�|d	|d
d�}|d�r�|ddk�r�|d|d<|d�r|ddk�r|d|d<|jd|�|jd��q�WxBt|j�D]4}|jd�|jd|d	|d
d��|jd��q>W�xT|jD�]H}i}|j�r�|j|d<|jd	k�r�t|j�|d<|jd�|jd|�|jd�|j�rVi}|jj�r�|jj|d<|jj�r|jj|d<|jj�r$|jj|d<|jj�r6d|d<|jd�|jd|�|jd�|j�r�i}|jj�rx|jj|d<|jj�r�|jj|d<|jj�r�d|d<|jd�|jd |�|jd�|j�rxd}	i}t|j�tjk�r�d}	|jj|d<�nbt|j�tjk�r(d}	|jj|d<|jj |d<�n0t|j�tj!k�rNd}	|jj"|d
<�n
t|j�tj#k�rfd}	n�t|j�tj$k�r�d}	|jj|d<n�t|j�tj%k�r�d!}	|jj|d<n�t|j�tj&k�rd}	|jj|d<|jj |d<|jj'dk�r�|jj'|d<|jj(dk�rX|jj(|d<nFt|j�tj)k�rBd}	|jj|d<|jj |d<nt*t+j,d"t|j���|jd�|j|	|�|jd�|j-�ri}|j-j.�r�|j-j.|d#<|j-j/�r�|j-j/|d$<|j-j0�r�|jd�|jd%|�|jd&�t1||j-j0�|jd'�|jd%�n|jd�|jd%|�|jd�|j2�r�i}|j2j0�rx|jd�|jd(i�|jd&�t1||j2j0�|jd'�|jd(�n|jd�|jd(|�|jd�|j3�r�d}
i}t|j3�tj4k�r�d)}
n|t|j3�tj5k�r�d*}
|j3j�r<|j3j|d+<nNt|j3�tj6k�rd,}
n6t|j3�tj7k�r*d-}
|j3j8|d.<nt-j9d/t|j3��|j3j0�r�|jd�|j|
|�|jd&�t1||j3j0�|jd'�|j|
�n|jd�|j|
|�|jd�|jd�|jd�|jd��q�WdS)0Nr!z  r�
rrrrrrk)rrrrz
icmp-blockr rlzto-portrmzto-addrzforward-portzsource-portr:r=r9r#�macr$�Truer%z    �sourcer"z	icmp-typez"Unknown element '%s' in obj_writerr7r.rz
      z
    r8r(r)r,r*r+r-zUnknown action '%s'):r�ignorableWhitespace�startElementZ
characters�
endElementrrrFrxrIrKrMr rRrTrhr:r=rBr�addrr}r$r%r"rAr,rrDrrHrrrJrrOrLrNrPrb�
to_addressrSrrZINVALID_OBJECTrr7r.r>r{r8rVrWrXrYrZr-r3)r_ryrrrZicmpZforwardr`r9rArVrcrcrd�
common_writer�s\




















































r�csPeZdZd7ZdZeZdgZd8d9d:d;d	dgfd
d<gfddgfd=dd>gfddgfddgfdd?gfd@ddgfddgffZdddgZ	dddgdgddgdgdgdddgddddgddgddddddgdgdgdgd�Z
ddgdd gd!dgd"d#d$d!d%gd"d$d%gd&d'gd(gd)gd*�Z�fd+d,�Zd-d.�Z
�fd/d0�Z�fd1d2�Zd3d4�Z�fd5d6�Z�ZS)Ari�i�r�versionr!rr�targetrFrIrMr FrRrnrKrTr=�
ingress_zones�egress_zones�_r�/Nrrrrr-)rr�policyrrz
icmp-blockz	icmp-typer zforward-portr9rr"rzsource-portrr8r(r)r*r+r>zingress-zonezegress-zonezto-portzto-addrr:r#r}r%r$r7r.r,r?)r�zforward-portr9rr"rr)r>cs�tt|�j�d|_d|_d|_t|_g|_g|_	g|_
g|_d|_g|_
g|_d|_g|_g|_d|_|j|_d|_g|_g|_dS)Nr!F)�superr�__init__r�rrrr�rFrIrKrMr rRrTrqrhrg�applied�priority_defaultr=Zderived_from_zoner�r�)�self)�	__class__rcrdr��s(zPolicy.__init__cCs�d|_d|_d|_t|_|jdd�=|jdd�=|jdd�=|jdd�=d|_	|j
dd�=|jdd�=d|_|j
dd�=|jdd�=d|_|j|_|jdd�=|jdd�=dS)Nr!F)r�rrrr�rFrIrKrMr rRrTrqrhrgr�r�r=r�r�)r�rcrcrd�cleanup�s$zPolicy.cleanupcs"|dkr|jSttt|�|�SdS)Nrn)rg�getattrr�r)r�r)r�rcrd�__getattr__�szPolicy.__getattr__csB|dkr,dd�|D�|_dd�|jD�|_ntt|�j||�dS)NrncSsg|]}tj|d��qS))ro)rr])�.0�srcrcrd�
<listcomp>�sz&Policy.__setattr__.<locals>.<listcomp>cSsg|]}t|��qSrc)rB)r�r�rcrcrdr��s)rhrgr�r�__setattr__)r�rr)r�rcrdr��szPolicy.__setattr__c
Cst||||�|dkr2|tkr.ttjd|���n�|dkrz||jksX||jksX||jkrvttjd||j|j|jf���n�|dk�rhddg}|j	r�||j	j
�7}x�|D]�}||kr�ttjd	|��|dkr�tddg�t|�@�s�|dk�rt|�t|g��rttjd
|��|dkr�|dk�r8d|k�r8d|dk�sT|dkr�d|kr�d|dkr�ttjd��q�W�n�|dk�r|�rd|k�r�d|dk�r�ttjd
��nxd|k�rd|dk�r�ttjd��xR|dD]F}|dk�rސq�|j	j
|�}|j	�r�d|j	j|�k�r�ttjd���q�W�n�|dk�r4�x�|D�]}tj|d�}|j�r�t|jtj��r�d|k�r|d|dk�r|ttjd
��nxd|k�r,d|dk�r�ttjd��xR|dD]F}|dk�r��q�|j	j
|�}|j	�r�d|j	j|�k�r�ttjd���q�W�q,|j�r�t|jtj��r�d|k�r,d|dk�r@|jj�r�ttjd��nt|d�r,|jj�s`ttjd��d|dk�r,x�|dD]8}|j	j
|�}|j	�rxd|j	j|�k�rxttjd���qxWnv|j�r,t|jtj��r,d|k�r,xR|dD]F}|dk�r�q�|j	j
|�}|j	�r�d|j	j|�k�r�ttjd���q�W�q,Wn�|dk�rx�|D]�}	d|k�rnd|dk�rnttjd��n�d|k�rDd|dk�r�|	d�rttjd��nt|d�rD|	d�s�ttjd��d|dk�rDxD|dD]8}|j	j
|�}|j	�r�d|j	j|�k�r�ttjd���q�W�qDWdS)Nr�z'%s' is invalid targetr=zQ%d is invalid priority. Must be in range [%d, %d]. The following are reserved: %sr�r��ANY�HOSTz'%s' not among existing zonesz>'%s' may only contain one of: many regular zones, ANY, or HOSTzF'HOST' can only appear in either ingress or egress zones, but not bothr z.'masquerade' is invalid for egress zone 'HOST'z/'masquerade' is invalid for ingress zone 'HOST'Z
interfaceszR'masquerade' cannot be used in a policy if an ingress zone has assigned interfacesrn)rozAA 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'zC'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zonezS'forward-port' cannot be used in a policy if an egress zone has assigned interfaceszR'mark' action cannot be used in a policy if an egress zone has assigned interfacesrRz1'forward-port' is invalid for ingress zone 'HOST'rm)r�r�)r�r�)r�r�)r�r�)rwrrr�INVALID_TARGET�priority_reserved�priority_max�priority_minZINVALID_PRIORITYrq�	get_zonesZINVALID_ZONEr-Zget_zoneZget_zone_config_dictrr]rArprOrPr�rrrVrZ)
r�rrErtZexisting_zones�zoneZz_objr9r_rvrcrcrd�
_check_config�s�






"
















zPolicy._check_configcs�tt|�j|�|jd�r,ttjd|��n�|jd�rHttjd|��n�|jd�dkrhttjd|��njd|kr�|d|j	d��}n|}t
|�t�kr�ttjd|t
|�t�f��|jr�||jj
�kr�ttjd��dS)Nr�z'%s' can't start with '/'z'%s' can't end with '/'rkzmore than one '/' in '%s'z&Policy of '%s' has %d chars, max is %dz,Policies can't have the same name as a zone.)r�r�
check_name�
startswithrr�INVALID_NAME�endswith�count�find�lenr	rqr�Z
NAME_CONFLICT)r�rZchecked_name)r�rcrdr�,s*

zPolicy.check_namei���)r�r!)rr!)rr!)r�r!)r!r!)r F)r!r!r!r!)r!r!)r=r)�__name__�
__module__�__qualname__r�r�r
r�r�ZIMPORT_EXPORT_STRUCTUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSr�r�r�r�r�r��
__classcell__rcrc)r�rdrZsr


^c@s$eZdZdd�Zdd�Zdd�ZdS)�policy_ContentHandlercCs"tj||�d|_d|_d|_dS)NF)rr�r@rCr[)r�rErcrcrdr�Hszpolicy_ContentHandler.__init__cCstj|||�|jrdS|jj||�t|||�r6dS|dkr�d|krR|d|j_d|krjt|d�|j_d|kr�|d}|t	kr�t
tj|��|r�||j_
�n^|dkr�|d|jjkr�|jjj|d�ntjd|d��n|dk�r |d|jjk�r|jjj|d�ntjd	|d�n�|d
k�r�|j�sFtjd�d|_dS|jj�rltjd
t|j��d|_dSd}d|k�r�|dj�dk�r�d}d}}}d|k�r�|d}d|k�r�|d}d|k�r�|d}tj||||d�|j_dStjd|�dSdS)Nr�r�r=r�zingress-zonerz(Ingress zone '%s' already set, ignoring.zegress-zonez'Egress zone '%s' already set, ignoring.rz$Invalid rule: Source outside of ruleTz:Invalid rule: More than one source in rule '%s', ignoring.Fr%r&r'r#r}r$)r%zUnknown XML element '%s')r&r')rr�rCrEZparser_check_element_attrsrer�r\r=rrrr�r�r�rGrr3r�r@rrBrUrZRich_Source)r�rr`r�r%r�r}r$rcrcrdr�Nsf








z"policy_ContentHandler.startElementcCstj||�t||�dS)N)rr�rj)r�rrcrcrdr��sz policy_ContentHandler.endElementN)r�r�r�r�r�r�rcrcrcrdr�Gs@r�Fc
Cst�}|jd�s ttjd|��|dd	�|_|s>|j|j�||_||_|j	t
j�rZdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}	zttjd|	j���WYdd}	~	XnXWdQRX~~|S)
Nz.xmlz'%s' is missing .xml suffix�FTz%s/%s�rbznot a valid policy file: %s���)rr�rrr�rr��filename�pathr�r�
ETC_FIREWALLDZbuiltin�defaultr��saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_POLICYZgetException)
r�r�Z
no_check_namer�ry�parserr�fr�msgrcrcrdr�s6




(c
Cs�|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�i}|j�r|jd	k�r|j|d
<|j|jk�r0t|j�|d<|j|d<|jd
|�|jd�t||�x8t|j�D]*}	|jd�|jdd|	i�|jd��qfWx8t|j�D]*}	|jd�|jdd|	i�|jd��q�W|jd
�|jd�|j �|j!�~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingr!r�r=r�r�r|z  zingress-zonerzegress-zone)"r�r�r�os�exists�shutilZcopy2rfrr2�dirnamer�rr��mkdir�ior�rZ
startDocumentr�r=r�rBr�r�r�r�rr�rxr�r�ZendDocument�close)
r�r��_pathrr��dirpathr�ryr`r�rcrcrdr�sN 







)F)N))�__all__Zxml.saxr�r�r�r�ZfirewallrZfirewall.functionsrrrr	r
Zfirewall.core.baserrr
Zfirewall.core.io.io_objectrrrrrrZ
firewall.corerZfirewall.core.loggerrrZfirewall.errorsrrerjrwr{r�rr�rrrcrcrcrd�<module>s4

 F[nL
core/io/__pycache__/firewalld_conf.cpython-36.pyc000064400000016616150351351720015733 0ustar003

��g�5�
@s~ddlZddlZddlZddlZddlmZddlmZddl	m
Z
mZmZddddd	d
ddd
ddddg
Z
Gdd�de�ZdS)�N)�config)�log)�b2u�u2b�PY2�DefaultZone�MinimalMark�
CleanupOnExit�CleanupModulesOnExit�Lockdown�
IPv6_rpfilter�IndividualCalls�	LogDenied�AutomaticHelpers�FirewallBackend�FlushAllOnReload�RFC3964_IPv4�AllowZoneDriftingc@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dS)�firewalld_confcCsi|_g|_||_|j�dS)N)�_config�_deleted�filename�clear)�selfr�r�$/usr/lib/python3.6/firewalld_conf.py�__init__&szfirewalld_conf.__init__cCsi|_g|_dS)N)rr)rrrrr,szfirewalld_conf.clearcCs|jj�g|_dS)N)rrr)rrrr�cleanup0s
zfirewalld_conf.cleanupcCs|jj|j��S)N)r�get�strip)r�keyrrrr4szfirewalld_conf.getcCs8t|j��}t|j��|j|<||jkr4|jj|�dS)N)rrrr�remove)rr �valueZ_keyrrr�set7s
zfirewalld_conf.setcCsHd}x2|jj�D]$\}}|r$|d7}|d||f7}qWtrDt|�S|S)N��
z%s=%s)r�itemsrr)r�sr r"rrr�__str__=szfirewalld_conf.__str__cCs�|j�yt|jd�}W�n8tk
�rR}�ztjd|j|�|jdtj�|jdt	tj
��|jdtjrpdnd�|jdtjr�dnd�|jd	tj
r�dnd�|jd
tjr�dnd�|jdtjr�dnd�|jdtj�|jd
tj�|jdtj�|jdtj�r
dnd�|jdtj�r"dnd�|jdtj�r:dnd��WYdd}~XnX�x�|D]�}|�shP|j�}t|�dk�s\|dd.k�r��q\dd�|jd�D�}t|�dk�r�tjd|j���q\nr|dtk�r�tjd|j���q\nN|ddk�rtjd|j���q\n*|jj|d�dk	�r:tjd|j���q\|d|j|d<�q\W|j�|jd��s�tjdtj�|jdt	tj��|jd�}yt|�WnPttfk
�r�|dk	�r�tj d |�r�|ndtj
�|jdt	tj
��YnX|jd�}|�s|j!�d/k�rJ|dk	�r2tj d#|�r(|ndtj�|jdtj�rDdnd�|jd�}|�sj|j!�d0k�r�|dk	�r�tj d$|�r�|ndtj�|jdtj�r�dnd�|jd	�}|�s�|j!�d1k�r|dk	�r�tj d%|�r�|ndtj
�|jd	tj
�r�dnd�|jd
�}|�s"|j!�d2k�r^|dk	�rFtj d&|�r<|ndtj�|jd
tj�rXdnd�|jd�}|�s~|j!�d3k�r�|dk	�r�tj d'|�r�|ndtj�|jdtj�r�dnd�|jd�}|�s�|tj"k�r|dk	�r�tj d(|tj�|jdt	tj��|jd
�}|�s&|j!�tj#k�r\|dk	�rJtj d)|�r@|ndtj�|jd
t	tj��|jd�}|�s~|j!�tj$k�r�|dk	�r�tj d*|�r�|ndtj�|jdt	tj��|jd�}|�s�|j!�d4k�r
|dk	�r�tj d+|�r�|ndtj�|jdt	tj��|jd�}|�s*|j!�d5k�r`|dk	�rNtj d,|�rD|ndtj�|jdt	tj��|jd�}|�s�|j!�d6k�r�|dk	�r�tj d-|�r�|ndtj�|jdt	tj��dS)7N�rzFailed to load '%s': %srrr	�yes�nor
rrr
rrrrrr�r�#�;cSsg|]}|j��qSr)r)�.0�xrrr�
<listcomp>bsz'firewalld_conf.read.<locals>.<listcomp>�=�zInvalid option definition: '%s'zInvalid option: '%s'r$zMissing value: '%s'z!Duplicate option definition: '%s'z0DefaultZone is not set, using default value '%s'z7MinimalMark '%s' is not valid, using default value '%d'�false�truez7CleanupOnExit '%s' is not valid, using default value %sz>CleanupModulesOnExit '%s' is not valid, using default value %sz2Lockdown '%s' is not valid, using default value %sz7IPv6_rpfilter '%s' is not valid, using default value %sz9IndividualCalls '%s' is not valid, using default value %sz3LogDenied '%s' is invalid, using default value '%s'z:AutomaticHelpers '%s' is not valid, using default value %sz9FirewallBackend '%s' is not valid, using default value %sz:FlushAllOnReload '%s' is not valid, using default value %sz6RFC3964_IPv4 '%s' is not valid, using default value %sz;AllowZoneDrifting '%s' is not valid, using default value %s)r-r.)r+r4r*r5)r+r4r*r5)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)%r�openr�	Exceptionr�errorr#rZ
FALLBACK_ZONE�strZFALLBACK_MINIMAL_MARKZFALLBACK_CLEANUP_ON_EXITZ FALLBACK_CLEANUP_MODULES_ON_EXITZFALLBACK_LOCKDOWNZFALLBACK_IPV6_RPFILTERZFALLBACK_INDIVIDUAL_CALLSZFALLBACK_LOG_DENIEDZFALLBACK_AUTOMATIC_HELPERSZFALLBACK_FIREWALL_BACKENDZFALLBACK_FLUSH_ALL_ON_RELOADZFALLBACK_RFC3964_IPV4ZFALLBACK_ALLOW_ZONE_DRIFTINGr�len�split�
valid_keysrr�close�int�
ValueError�	TypeErrorZwarning�lowerZLOG_DENIED_VALUESZAUTOMATIC_HELPERS_VALUESZFIREWALL_BACKEND_VALUES)r�f�msg�lineZpairr"rrr�readFs
























zfirewalld_conf.readc:Cs�t|j�dkrdSg}tjjtj�s2tjtjd�y.tj	ddtjj
|j�tjj|j�dd�}Wn2t
k
r�}ztjd|��WYdd}~XnXd}d}ytj|jdd	d
�}WnPt
k
�r}z0tjj|j�r�tjd|j|f��nd}WYdd}~X�n6X�x0|D�]&}|�sP|jd�}t|�dk�rH|�s2|jd�d
}n�|ddk�rpd}|j|�|jd�n�|jd�}t|�dk�r�d}|j|d��q|dj�}	|dj�}
|	|k�r.|	|jk�r�|j|	|
k�r�d}|jd|	|j|	f�d
}n$|	|jk�rd
}nd}|j|d�|j|	�nd
}�qWt|j�dk�r�x^|jj�D]P\}	}
|	|k�rj�qT|	dk�rx�qT|�s�|jd�d
}|jd|	|
f�d
}�qTW|�r�|j�|j�|�s�tj|j�dStjj|j��r@ytj|jd|j�WnBt
k
�r>}z$tj|j�td|j|f��WYdd}~XnXytj|j|j�WnBt
k
�r�}z$tj|j�td|j|f��WYdd}~XnXtj|jd�dS)Nr,i�Zwtz%s.F)�mode�prefix�dir�deletez!Failed to open temporary file: %sZrtzUTF-8)rF�encodingzFailed to open '%s': %sr%Trr-r2r3z%s=%s
rrz%s.oldzBackup of '%s' failed: %szFailed to create '%s': %si�)rr) r:r�os�path�existsrZ
ETC_FIREWALLD�mkdir�tempfileZNamedTemporaryFile�basenamer�dirnamer7rr8�ior6r�writer;r�appendr&r=r!�name�shutilZcopy2�IOErrorZmove�chmod)r�doneZ	temp_filerCZmodified�emptyrBrD�pr r"rrrrS�s�









$$zfirewalld_conf.writeN)�__name__�
__module__�__qualname__rrrrr#r(rErSrrrrr%s	r)Zos.pathrKrRrOrVZfirewallrZfirewall.core.loggerrZfirewall.functionsrrrr<�objectrrrrr�<module>score/io/__pycache__/helper.cpython-36.pyc000064400000013451150351351720014226 0ustar003

��g� �@s�dddgZddljZddlZddlZddlZddlmZddlm	Z	ddl
mZmZm
Z
mZmZmZddlmZdd	lmZdd
lmZGdd�de�ZGdd
�d
e
�Zdd�Zddd�ZdS)�Helper�
helper_reader�
helper_writer�N)�config)�
u2b_if_py2)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator�
check_port�check_tcpudp)�log)�errors)�
FirewallErrorcs�eZdZddddddd gffZdZd	d
gZdddgd�Zd
ddgddgd�Z�fdd�Zdd�Z	dd�Z
dd�Zdd�Z�Z
S)!r�version��short�description�family�module�portsz(sssssa(ss))�-�.N)rr�helper�name�port�protocol)rrcs6tt|�j�d|_d|_d|_d|_d|_g|_dS)Nr)	�superr�__init__rrrrrr)�self)�	__class__��/usr/lib/python3.6/helper.pyr;szHelper.__init__cCs.d|_d|_d|_d|_d|_|jdd�=dS)Nr)rrrrrr)rr!r!r"�cleanupDszHelper.cleanupcCsRt|j�|_t|j�|_t|j�|_t|j�|_t|j�|_dd�|jD�|_dS)z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSs g|]\}}t|�t|�f�qSr!)r)�.0ZpoZprr!r!r"�
<listcomp>Usz)Helper.encode_strings.<locals>.<listcomp>N)rrrrrrr)rr!r!r"�encode_stringsLszHelper.encode_stringscCs(ddg}||kr$ttjd||f��dS)NZipv4Zipv6z'%s' not in '%s')rrZINVALID_IPV)rZipvZipvsr!r!r"�	check_ipvWszHelper.check_ipvcCsz|dkr0xl|D]}t|d�t|d�qWnF|dkrv|jd�sRttjd|��t|jdd��dkrvttjd|��dS)	Nrr�r�
nf_conntrack_z('%s' does not start with 'nf_conntrack_'rzModule name '%s' too short)rr�
startswithrr�INVALID_MODULE�len�replace)rr�itemZ
all_configrr!r!r"�
_check_config]s


zHelper._check_config)rr)rr)rr)rr)rr)rr)�__name__�
__module__�__qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr#r&r'r/�
__classcell__r!r!)r r"r&s$
	c@seZdZdd�ZdS)�helper_ContentHandlercCs>tj|||�|jj||�|dkr�d|kr8|d|j_d|kr\|jj|d�|d|j_d|kr�|djd�s�tt	j
d|d��t|djdd��dkr�tt	j
d	|d��|d|j_
nz|d
kr�np|dkr�nf|dk�r:t|d�t|d
�|d|d
f}||jjk�r$|jjj|�ntjd|d|d
�dS)Nrrrrr)z('%s' does not start with 'nf_conntrack_'rr(zModule name '%s' too shortrrrrz#Port '%s/%s' already set, ignoring.)r	�startElementr.Zparser_check_element_attrsrr'rr*rrr+r,r-rrrr�appendr
Zwarning)rr�attrs�entryr!r!r"r5ns>
z"helper_ContentHandler.startElementN)r0r1r2r5r!r!r!r"r4msr4c	Cst�}|jd�s ttjd|��|dd	�|_|j|j�||_||_|j	t
j�rVdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}zttjd|j���WYdd}~XnXWdQRX~~t�r|j�|S)
Nz.xmlz'%s' is missing .xml suffix�FTz%s/%s�rbznot a valid helper file: %s���)r�endswithrrZINVALID_NAMErZ
check_name�filename�pathr*r�
ETC_FIREWALLDZbuiltin�defaultr4�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_HELPERZgetExceptionrr&)	r=r>r�handler�parserr�f�source�msgr!r!r"r�s8




(c
CsP|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�i}|j|d	<|j�r|jd
k�r|j|d<|j�r<|jd
k�r<|j|d<|jd
|�|jd�|j�r�|jd
k�r�|jd�|jdi�|j|j�|jd�|jd�|j�r�|jd
k�r�|jd�|jdi�|j|j�|jd�|jd�x>|jD]4}	|jd�|jd|	d|	dd��|jd��q�W|jd
�|jd�|j�|j�~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingrrrrr�
z  rrrrr()rr) r>r=r�os�exists�shutilZcopy2�	Exceptionr
�error�dirnamer*rr?�mkdir�iorBr
Z
startDocumentrrrr5ZignorableWhitespacerZ
charactersZ
endElementrrZ
simpleElementZendDocument�close)
rr>�_pathrrH�dirpathrFrDr7rr!r!r"r�s\ 












)N)�__all__Zxml.saxrArLrSrNZfirewallrZfirewall.functionsrZfirewall.core.io.io_objectrrr	r
rrZfirewall.core.loggerr
rZfirewall.errorsrrr4rrr!r!r!r"�<module>s

 G#core/io/__pycache__/ifcfg.cpython-36.opt-1.pyc000064400000007721150351351720014767 0ustar003

��g��@s^dZdgZddlZddlZddlZddlZddlmZddl	m
Z
mZmZGdd�de
�ZdS)zifcfg file parser�ifcfg�N)�log)�b2u�u2b�PY2c@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dS)rcCsi|_g|_||_|j�dS)N)�_config�_deleted�filename�clear)�selfr	�r�/usr/lib/python3.6/ifcfg.py�__init__#szifcfg.__init__cCsi|_g|_dS)N)rr)rrrr
r
)szifcfg.clearcCs|jj�dS)N)rr
)rrrr
�cleanup-sz
ifcfg.cleanupcCs|jj|j��S)N)r�get�strip)r�keyrrr
r0sz	ifcfg.getcCs8t|j��}t|j��|j|<||jkr4|jj|�dS)N)rrrr�remove)rr�valueZ_keyrrr
�set3s
z	ifcfg.setcCsHd}x2|jj�D]$\}}|r$|d7}|d||f7}qWtrDt|�S|S)N��
z%s=%s)r�itemsrr)r�srrrrr
�__str__9sz
ifcfg.__str__cCsB|j�yt|jd�}Wn4tk
rL}ztjd|j|��WYdd}~XnXx�|D]�}|s^P|j�}t|�dksT|ddkr�qTdd�|jd	d�D�}t|�d
kr�qTt|d�d
kr�|dj	d�r�|dj
d�r�|ddd�|d<|ddkr�qTn,|jj|d�dk	�r tj
d
|j|j��qT|d|j|d<qTW|j�dS)N�rzFailed to load '%s': %s�r�#�;cSsg|]}|j��qSr)r)�.0�xrrr
�
<listcomp>Qszifcfg.read.<locals>.<listcomp>�=��"rz%%s: Duplicate option definition: '%s')rr���)r
�openr	�	Exceptionr�errorr�len�split�
startswith�endswithrrZwarning�close)r�f�msg�lineZpairrrr
�readBs2
z
ifcfg.readc:Cs�t|j�dkrdSg}y.tjddtjj|j�tjj|j�dd�}Wn2t	k
rv}zt
jd|��WYdd}~XnXd}d}ytj
|jddd	�}WnNt	k
r�}z0tjj|j�r�t
jd
|j|f��nd}WYdd}~X�ndX�x^|D�]T}|s�P|jd�}t|�dk�r(|�sD|jd�d}q�|d
dk�rPd}|j|�|jd�q�|jdd�}t|�dk�r~d}|j|d�q�|d
j�}	|dj�}
t|
�dk�r�|
jd��r�|
jd��r�|
dd�}
|	|k�r@|	|jk�r|j|	|
k�rd}|jd|	|j|	f�d}n$|	|jk�r"d}nd}|j|d�|j|	�q�d}q�Wt|j�d
k�r�xF|jj�D]8\}	}
|	|k�rz�qd|�s�d}|jd|	|
f�d}�qdW|�r�|j�|j�|�s�tj|j�dStjj|j��r8ytj|jd|j�WnBt	k
�r6}z$tj|j�td|j|f��WYdd}~XnXytj|j|j�WnBt	k
�r�}z$tj|j�td|j|f��WYdd}~XnXtj|jd�dS)NrZwtz%s.F)�mode�prefix�dir�deletez!Failed to open temporary file: %sZrtzUTF-8)r2�encodingzFailed to open '%s': %srTrrr"r#r$z%s=%s
z%s.bakzBackup of '%s' failed: %szFailed to create '%s': %si�r%)r)r�tempfileZNamedTemporaryFile�os�path�basenamer	�dirnamer'rr(�ior&�existsr�writer*r+r,r�appendrr-r�name�shutilZcopy2�IOErrorZmove�chmod)r�doneZ	temp_filer/Zmodified�emptyr.r0�prrrrr
r>_s�





$$zifcfg.writeN)�__name__�
__module__�__qualname__rr
rrrrr1r>rrrr
r"s	)�__doc__�__all__Zos.pathr8r<r7rAZfirewall.core.loggerrZfirewall.functionsrrr�objectrrrrr
�<module>score/io/__pycache__/ipset.cpython-36.pyc000064400000025614150351351720014077 0ustar003

��g�R�@sdZdddgZddljZddlZddlZddlZddlmZddl	m
Z
mZmZm
Z
mZmZmZmZmZddlmZmZmZmZdd	lmZmZdd
lmZmZmZmZddl m!Z!ddlm"Z"dd
l#m$Z$Gdd�de�Z%Gdd�de�Z&dd�Z'ddd�Z(dS)z$ipset io XML handler, reader, writer�IPSet�ipset_reader�ipset_writer�N)�config)	�checkIP�checkIP6�checkIPnMask�
checkIP6nMask�
u2b_if_py2�	check_mac�
check_port�checkInterface�
checkProtocol)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator)�IPSET_TYPES�IPSET_CREATE_OPTIONS)�check_icmp_name�check_icmp_type�check_icmpv6_name�check_icmpv6_type)�log)�errors)�
FirewallErrorcs�eZdZddd d!dddifddgffZdZd	d
ddgZd
d
dgdgd
d�Zdgdgd�Z�fdd�Zdd�Z	dd�Z
edd��Zdd�Z
�fdd�Z�ZS)"r�version��short�description�type�options�entriesz
(ssssa{ss}as)�_�-�:�.N�name)rr�ipset�option�entry�value)r(r)cs<tt|�j�d|_d|_d|_d|_g|_i|_d|_	dS)NrF)
�superr�__init__rrrr r"r!�applied)�self)�	__class__��/usr/lib/python3.6/ipset.pyr-CszIPSet.__init__cCs8d|_d|_d|_d|_|jdd�=|jj�d|_dS)NrF)rrrr r"r!�clearr.)r/r1r1r2�cleanupMs
z
IPSet.cleanupcCs\t|j�|_t|j�|_t|j�|_t|j�|_dd�|jj�D�|_dd�|jD�|_dS)z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSsi|]\}}t|�t|��qSr1)r
)�.0�k�vr1r1r2�
<dictcomp>^sz(IPSet.encode_strings.<locals>.<dictcomp>cSsg|]}t|��qSr1)r
)r5�er1r1r2�
<listcomp>`sz(IPSet.encode_strings.<locals>.<listcomp>N)r
rrrr r!�itemsr")r/r1r1r2�encode_stringsVszIPSet.encode_stringsc
Csd}d|kr|ddkrd}|jd�s6ttjd|��|dd�jd�}|jd�}t|�t|�ksnt|�d	kr�ttjd
||f���xztt|��D�]h}||}||}|dk�r�d|ko�|dk�rh|d	kr�ttjd
|||f��|jd�}	t|	�dk�rttjd||||f��x�|	D]J}
|dk�r2t|
��sH|dk�rt	|
��rttjd|
|||f���qWnh|dk�r�|dk�r�ttjd||||f��|dk�r�t
}nt}nt	}||��s�ttjd||||f��q�|dk�r@d|k�r�|jd�}	t|	�dk�rttjd||||f��|dk�r0t|	d��sJ|dk�rft	|	d��rfttjd|	d|||f��|dk�r�t
|	d	��s�|dk�r>t|	d	��r>ttjd|	d	|||f��n�|jd��r�|dk�o�|dk�o�|dk�s�ttjd||||f��|dk�rt
|��s&|dk�r�t|��r�ttjd||||f��q�|dk�rvt
|��s`|dk�r�ttjd||f��q�|dk�r�d|k�r�|jd�}	t|	�dk�r�ttjd|��|	ddk�r|dk�r�ttjd||f��t|	d	��r�t|	d	��r�ttjd|	d	|f��n�|	dd1k�r~|dk�rDttjd||f��t|	d	��r�t|	d	��r�ttjd!|	d	|f��n^|	dd2k�r�t|	d��r�ttjd&|	d|f��n&t|	d	��s�ttjd'|	d	|f��nt|��s�ttjd(||f��q�|d)k�r�|jd*��rPyt|d+�}Wn*tk
�rLttjd,||f��YnXn8yt|�}Wn*tk
�r�ttjd,||f��YnX|dk�s�|d-k�r�ttjd,||f��q�|d.k�r�t|��s�t|�d/k�r�ttjd0||f��q�ttjd|��q�WdS)3NZipv4�family�inet6Zipv6zhash:zipset type '%s' not usable��,�z)entry '%s' does not match ipset type '%s'Zipr$z invalid address '%s' in '%s'[%d]�z.invalid address range '%s' in '%s' for %s (%s)z(invalid address '%s' in '%s' for %s (%s)z0.0.0.0rZnetz/0zhash:net,ifaceZmacz00:00:00:00:00:00z invalid mac address '%s' in '%s'Zportr%zinvalid port '%s'Zicmpz(invalid protocol for family '%s' in '%s'zinvalid icmp type '%s' in '%s'�icmpv6�	ipv6-icmpz invalid icmpv6 type '%s' in '%s'�tcp�sctp�udp�udplitezinvalid protocol '%s' in '%s'zinvalid port '%s'in '%s'zinvalid port '%s' in '%s'ZmarkZ0x�zinvalid mark '%s' in '%s'l��Ziface�zinvalid interface '%s' in '%s')rCrD)rErFrGrH)�
startswithrr�
INVALID_IPSET�split�lenZ
INVALID_ENTRY�rangerrrr	�endswithrrrrrrr�int�
ValueErrorr
)
r*r!Z
ipset_typer=�flagsr;�i�flag�itemZsplitsZ_splitZip_checkZint_valr1r1r2�check_entrybs@























zIPSet.check_entrycCs�|dkr |tkr ttjd|��|dkr�x�|j�D]�}|tkrNttjd|��|dkr�yt||�}Wn,tk
r�ttj	d|||f��YnX|d	kr�ttj	d
|||f��q2|dkr2||dkr2ttj
||��q2WdS)Nr z'%s' is not valid ipset typer!zipset invalid option '%s'�timeout�hashsize�maxelemz)Option '%s': Value '%s' is not an integerrz#Option '%s': Value '%s' is negativer=�inetr>)rXrYrZ)r[r>)rrr�INVALID_TYPE�keysrrLrQrR�
INVALID_VALUE�INVALID_FAMILY)r/rrVZ
all_config�key�	int_valuer1r1r2�
_check_configs2

zIPSet._check_configcsrd|dkr6|dddkr6t|d�dkr6ttj��x&|dD]}tj||d|d�q@Wtt|�j|�dS)NrX��0r?r�)rNrrZIPSET_WITH_TIMEOUTrrWr,�
import_config)r/rr*)r0r1r2rf3s
zIPSet.import_config)rr)rr)rr)r r)�__name__�
__module__�__qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSr-r4r<�staticmethodrWrbrf�
__classcell__r1r1)r0r2r,s,


	7c@seZdZdd�Zdd�ZdS)�ipset_ContentHandlerc
Cs�tj|||�|jj||�|dkrpd|krX|dtkrLttjd|d��|d|j_d|krl|d|j_	�nz|dkr|�nn|dkr��nb|dk�r�d}d	|kr�|d	}|d
dkr�ttj
d|d
��|jjdko�|d
dk�r�ttj
d|d
|jjf��|d
dk�r&|�r&ttj
d|d
��|d
dk�r�yt|�}Wn.tk
�rnttj
d|d
|f��YnX|dk�r�ttj
d|d
|f��|d
dk�r�|dk�r�ttj|��|d
|jjk�r�||jj|d
<ntjd|d
�dS)Nr(r z%srrrr)rr+r'r=rXrYrZzUnknown option '%s'zhash:macz%Unsupported option '%s' for type '%s'z&Missing mandatory value of option '%s'z)Option '%s': Value '%s' is not an integerrz#Option '%s': Value '%s' is negativer[r>z Option %s already set, ignoring.)r=rXrYrZ)r=)r=rXrYrZ)rXrYrZ)r[r>)r�startElementrVZparser_check_element_attrsrrrr\r rZINVALID_OPTIONrQrRr^r_r!r�warning)r/r'�attrsr+rar1r1r2rm>sd

z!ipset_ContentHandler.startElementcCs(tj||�|dkr$|jjj|j�dS)Nr*)r�
endElementrVr"�appendZ_element)r/r'r1r1r2rpuszipset_ContentHandler.endElementN)rgrhrirmrpr1r1r1r2rl=s7rlc%Cst�}|jd�s ttjd|��|dd�|_|j|j�||_||_|j	t
j�rVdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}zttjd|j���WYdd}~XnXWdQRX~~d	|jk�rF|jd	d
k�rFt|j�dk�rFtjd|j�|jdd�=d}	t�}
x�|	t|j�k�r|j|	|
k�r�tjd
|j|	�|jj|	�nry|j |j|	|j|j!�Wn<tk
�r�}ztjd|�|jj|	�WYdd}~XnX|
j"|j|	�|	d7}	�qRW~
t#�r|j$�|S)Nz.xmlz'%s' is missing .xml suffixrcFTz%s/%s�rbznot a valid ipset file: %srXrdrz6ipset '%s': timeout option is set, entries are ignoredzEntry %s already set, ignoring.z
%s, ignoring.rA���)%rrPrrZINVALID_NAMEr'Z
check_name�filename�pathrKr�
ETC_FIREWALLDZbuiltin�defaultrl�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionrLZgetExceptionr!rNr"rrn�set�poprWr �addrr<)rtrur(�handler�parserr'�f�source�msgrTZentries_setr9r1r1r2rzs^




(cCs�|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�d	|ji}|j�r|jd
k�r|j|d<|jd|�|jd
�|j�rz|jd
k�rz|jd�|jdi�|j|j�|jd�|jd
�|j�r�|jd
k�r�|jd�|jdi�|j|j�|jd�|jd
�xZ|jj�D]L\}	}
|jd�|
d
k�r|jd|	|
d��n|jdd|	i�|jd
��q�WxD|jD]:}|jd�|jdi�|j|�|jd�|jd
��q(W|jd�|jd
�|j�|j �~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingr rrr(�
z  rrr))r'r+r'r*)!rurtr'�os�exists�shutilZcopy2�	Exceptionr�error�dirnamerKrrv�mkdir�ioryrZ
startDocumentr rrmZignorableWhitespacerZ
charactersrprr!r;Z
simpleElementr"ZendDocument�close)r(ru�_pathr'r��dirpathr�r~ror`r+r*r1r1r2r�sf 















)N))�__doc__�__all__Zxml.saxrxr�r�r�ZfirewallrZfirewall.functionsrrrr	r
rrr
rZfirewall.core.io.io_objectrrrrZfirewall.core.ipsetrrZfirewall.core.icmprrrrZfirewall.core.loggerrrZfirewall.errorsrrrlrrr1r1r1r2�<module>s&

,=5core/io/__pycache__/functions.cpython-36.pyc000064400000005256150351351720014763 0ustar003

��gy�@s�ddlZddlmZddlmZddlmZddlmZddl	m
Z
ddlmZddl
mZdd	lmZdd
lmZddlmZddlmZdd
lmZdd�ZdS)�N)�config)�
FirewallError)�FirewallConfig)�zone_reader)�service_reader)�ipset_reader)�icmptype_reader)�
helper_reader)�
policy_reader)�Direct)�LockdownWhitelist)�firewalld_confc	-Cs|t|�}t|jtjtjgd�t|jtjtj	gd�t
|jtjtj
gd�t|jtjtjgd�t|jtjtjgd�t|jtjtjgd�d�}�x
|j�D�]�}x�||dD]�}tjj|�s�q�x�ttj|��D]�}|j d�r�yD||d||�}|d
k�r�||_!|j"|j#��||d|�Wq�t$k
�rT}zt$|j%d	||j&f��WYdd}~Xq�t'k
�r�}zt'd	||f��WYdd}~Xq�Xq�Wq�Wq�Wtjj(tj)��r:y$t*tj)�}|j+�|j,|j-��Wnpt$k
�r}zt$|j%d	tj)|j&f��WYdd}~Xn6t'k
�r8}zt'd	tj)|f��WYdd}~XnXtjj(tj.��r�y$t/tj.�}|j+�|j,|j-��Wnpt$k
�r�}zt$|j%d	tj.|j&f��WYdd}~Xn6t'k
�r�}zt'd	tj.|f��WYdd}~XnXtjj(tj0��rxyt1tj0�}|j+�Wnpt$k
�rB}zt$|j%d	tj0|j&f��WYdd}~Xn6t'k
�rv}zt'd	tj0|f��WYdd}~XnXdS)N)�reader�add�dirs)Zipset�helperZicmptypeZservice�zone�policyrz.xmlrrrrz'%s': %s)rr)2rrZ	add_ipsetrZFIREWALLD_IPSETSZETC_FIREWALLD_IPSETSr	Z
add_helperZFIREWALLD_HELPERSZETC_FIREWALLD_HELPERSrZadd_icmptypeZFIREWALLD_ICMPTYPESZETC_FIREWALLD_ICMPTYPESrZadd_serviceZFIREWALLD_SERVICESZETC_FIREWALLD_SERVICESrZadd_zoneZFIREWALLD_ZONESZETC_FIREWALLD_ZONESr
Zadd_policy_objectZFIREWALLD_POLICIESZETC_FIREWALLD_POLICIES�keys�os�path�isdir�sorted�listdir�endswith�	fw_configZcheck_config_dictZexport_config_dictr�code�msg�	Exception�isfileZFIREWALLD_DIRECTr�read�check_configZ
export_configZLOCKDOWN_WHITELISTrZFIREWALLD_CONFr
)	�fwrZreadersrZ_dir�file�obj�errorr�r&�/usr/lib/python3.6/functions.pyr!&sz

&.
($
($
(r!)rZfirewallrZfirewall.errorsrZfirewall.core.fw_configrZfirewall.core.io.zonerZfirewall.core.io.servicerZfirewall.core.io.ipsetrZfirewall.core.io.icmptyperZfirewall.core.io.helperr	Zfirewall.core.io.policyr
Zfirewall.core.io.directrZ#firewall.core.io.lockdown_whitelistrZfirewall.core.io.firewalld_confr
r!r&r&r&r'�<module>score/io/__pycache__/io_object.cpython-36.opt-1.pyc000064400000027540150351351720015647 0ustar003

��g5�@sdZddddddddgZd	d
ljZd	d
ljjZd	d
lZd	d
lZd	dlm	Z	d	dl
mZd	d
lm
Z
d	dl
mZd	dlmZejdkZGdd�de�ZGdd�de�ZGdd�de�ZGdd�de�ZGdd�dejj�ZGdd�dej�Zdd�Zdd�Zdd�Z dd�Z!d
S)z5Generic io_object handler, io specific check methods.�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator�
check_port�check_tcpudp�check_protocol�
check_address�N)�OrderedDict)�	functions)�b2u)�errors)�
FirewallError�3c@s|eZdZdZfZdZgZiZiZdd�Z	dd�Z
dd�Zd	d
�Zdd�Z
d
d�Zdd�Zdd�Zdd�Zdd�Zdd�ZdS)rz; Abstract IO_Object as base for icmptype, service and zone z()cCs"d|_d|_d|_d|_d|_dS)N�F)�filename�path�name�defaultZbuiltin)�self�r�/usr/lib/python3.6/io_object.py�__init__2s
zIO_Object.__init__cCs6g}x(|jD]}|jtjt||d���qWt|�S)Nr	)�IMPORT_EXPORT_STRUCTURE�append�copy�deepcopy�getattr�tuple)r�ret�xrrr�
export_config9szIO_Object.export_configcCsXi}tdd�|jD��}x:|D]2}t||�s<tt||�t�rtjt||��||<qW|S)NcSsg|]}|d|df�qS)r	�r)�.0r rrr�
<listcomp>Asz0IO_Object.export_config_dict.<locals>.<listcomp>)�dictrr�
isinstance�boolrr)r�conf�type_formats�keyrrr�export_config_dict?s
zIO_Object.export_config_dictcCs�|j|�x�t|j�D]~\}\}}t||t�r~g}t�}x,||D] }||krD|j|�|j|�qDW~t||t	j
|��qt||t	j
||��qWdS)N)�check_config�	enumeraterr&�list�setr�add�setattrrr)rr(�i�elementZdummyZ_confZ_setr rrr�
import_configGs

zIO_Object.import_configc	Cs~|j|�xn|D]f}t||�s0ttjdj|���t||t�r`t||tt	j
tj||����qt||tj||��qWdS)Nz-Internal error. '{}' is not a valid attribute)
�check_config_dict�hasattrrr
Z
UNKNOWN_ERROR�formatr&r.r1r
�fromkeysrr)rr(r*rrr�import_config_dictWs


"zIO_Object.import_config_dictcCszt|t�s(ttjd|td�t|�f��t|�dkr@ttjd��x4|D],}|j�rF||j	krFttjd||f��qFWdS)Nz'%s' not of type %s, but %srr"zname can't be emptyz'%s' is not allowed in '%s')
r&�strrr
�INVALID_TYPE�type�lenZINVALID_NAME�isalnum�ADDITIONAL_ALNUM_CHARS)rr�charrrr�
check_namecs


zIO_Object.check_namecCsjt|�t|j�kr0ttjdt|�t|j�f��i}x&t|j�D]\}\}}||||<q@W|j|�dS)Nz structure size mismatch %d != %d)r=rrr
r;r-r5)rr(Z	conf_dictr2r �yrrrr,pszIO_Object.check_configcCsrtdd�|jD��}xX|D]P}|dd�|jD�krDttjdj|���|j||||�|j||||�qWdS)NcSsg|]}|d|df�qS)r	r"r)r#r rrrr$|sz/IO_Object.check_config_dict.<locals>.<listcomp>cSsg|]\}}|�qSrr)r#r rBrrrr$~szoption '{}' is not valid)r%rrr
ZINVALID_OPTIONr7�_check_config_structure�
_check_config)rr(r)r*rrrr5{s
zIO_Object.check_config_dictcCsdS)Nr)rZdummy1Zdummy2Zdummy3rrrrD�szIO_Object._check_configc	Cs`t|t|��s,ttjd|t|�t|�f��t|t�rrt|�dkrRttjd|��x|D]}|j||d�qXWn�t|t�r�t|�t|�kr�ttjd|t|�f��x�t	|�D]\}}|j|||�q�Wn�t|t
��r\t|j��d\}}xn|j�D]b\}}t|t|���s,ttjd|t|�t|�f��t|t|��s�ttjd|t|�t|�f��q�WdS)Nz'%s' not of type %s, but %sr"zlen('%s') != 1r	zlen('%s') != %d)r&r<rr
r;r.r=rCrr-r%�items)	rr(Z	structurer r2�valueZskeyZsvaluer*rrrrC�s8



z!IO_Object._check_config_structurecCs�|j�}d}||jkrdd}|j|dk	rdx:|j|D],}||krL|j|�q4ttjd||f��q4W||jkr�d}x$|j|D]}||kr~|j|�q~W|s�ttjd|��x |D]}ttjd||f��q�WdS)NFTzMissing attribute %s for %szUnexpected element %sz%s: Unexpected attribute %s)ZgetNames�PARSER_REQUIRED_ELEMENT_ATTRS�removerr
ZPARSE_ERROR�PARSER_OPTIONAL_ELEMENT_ATTRS)rr�attrsZ_attrs�foundr rrr�parser_check_element_attrs�s,



z$IO_Object.parser_check_element_attrsN)�__name__�
__module__�__qualname__�__doc__rZDBUS_SIGNATUREr?rGrIrr!r+r4r9rAr,r5rDrCrLrrrrr)s"
!cs$eZdZ�fdd�Zdd�Z�ZS)�UnexpectedElementErrorcstt|�j�||_dS)N)�superrQrr)rr)�	__class__rrr�szUnexpectedElementError.__init__cCs
d|jS)NzUnexpected element '%s')r)rrrr�__str__�szUnexpectedElementError.__str__)rMrNrOrrT�
__classcell__rr)rSrrQ�srQcs$eZdZ�fdd�Zdd�Z�ZS)�MissingAttributeErrorcstt|�j�||_||_dS)N)rRrVrr�	attribute)rrrW)rSrrr�szMissingAttributeError.__init__cCsd|j|jfS)Nz$Element '%s': missing '%s' attribute)rrW)rrrrrT�szMissingAttributeError.__str__)rMrNrOrrTrUrr)rSrrV�srVcs$eZdZ�fdd�Zdd�Z�ZS)�UnexpectedAttributeErrorcstt|�j�||_||_dS)N)rRrXrrrW)rrrW)rSrrr�sz!UnexpectedAttributeError.__init__cCsd|j|jfS)Nz'Element '%s': unexpected attribute '%s')rrW)rrrrrT�sz UnexpectedAttributeError.__str__)rMrNrOrrTrUrr)rSrrX�srXc@s4eZdZdd�Zdd�Zdd�Zdd�Zd	d
�ZdS)rcCs||_d|_dS)Nr)�item�_element)rrYrrrr�sz!IO_Object_ContentHandler.__init__cCs
d|_dS)Nr)rZ)rrrr�
startDocument�sz&IO_Object_ContentHandler.startDocumentcCs
d|_dS)Nr)rZ)rrrJrrr�startElement�sz%IO_Object_ContentHandler.startElementcCs*|dkr|j|j_n|dkr&|j|j_dS)N�short�description)rZrYr]r^)rrrrr�
endElement�sz#IO_Object_ContentHandler.endElementcCs|j|jdd�7_dS)N�
� )rZ�replace)r�contentrrr�
characters�sz#IO_Object_ContentHandler.charactersN)rMrNrOrr[r\r_rdrrrrr�s
c@s<eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
S)rcCsNtjjj|�|j|_|j|_ig|_|jd|_	g|_
d|_d|_d|_
dS)Nr"zutf-8F���)�sax�handler�ContentHandlerr�write�_write�flushZ_flushZ_ns_contextsZ_current_contextZ_undeclared_ns_mapsZ	_encodingZ_pending_start_elementZ_short_empty_elements)r�outrrrr�szIO_Object_XMLGenerator.__init__cCs*trdd�|j�D�}tjj|||�dS)a saxutils.XMLGenerator.startElement() expects name and attrs to be
            unicode and bad things happen if any of them is (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        cSsi|]\}}t|�t|��qSr)r)r#rrFrrr�
<dictcomp>sz7IO_Object_XMLGenerator.startElement.<locals>.<dictcomp>N)rrE�saxutils�XMLGeneratorr\)rrrJrrrr\sz#IO_Object_XMLGenerator.startElementcCs�trX|jdt|��x4|j�D](\}}|jdt|�tjt|��f�q W|jd�nF|jd|�x,|j�D] \}}|jd|tj|�f�qpW|jd�dS)z* slightly modified startElement()
        �<z %s=%sz/>N)rrjrrErnZ	quoteattr)rrrJrFrrr�
simpleElementsz$IO_Object_XMLGenerator.simpleElementcCstjj|t|��dS)z� saxutils.XMLGenerator.endElement() expects name to be
            unicode and bad things happen if it's (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        N)rnror_r)rrrrrr_sz!IO_Object_XMLGenerator.endElementcCstjj|t|��dS)z� saxutils.XMLGenerator.characters() expects content to be
            unicode and bad things happen if it's (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        N)rnrordr)rrcrrrrd%sz!IO_Object_XMLGenerator.characterscCstjj|t|��dS)a saxutils.XMLGenerator.ignorableWhitespace() expects content to be
            unicode and bad things happen if it's (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        N)rnro�ignorableWhitespacer)rrcrrrrr-sz*IO_Object_XMLGenerator.ignorableWhitespaceN)	rMrNrOrr\rqr_rdrrrrrrr�s
cCs�tj|�}|dkr$ttjd|��n`|dkr>ttjd|��nF|dkrXttjd|��n,t|�dkr�|d|dkr�ttjd|��dS)	N�zport number in '%s' is too bigr"z'%s' is invalid port rangezport range '%s' is ambiguousr	���re)rZgetPortRangerr
ZINVALID_PORTr=)ZportZ
port_rangerrrr5s
cCs|dkrttjd|��dS)N�tcp�udp�sctp�dccpz)'%s' not from {'tcp'|'udp'|'sctp'|'dccp'})rurvrwrx)rr
�INVALID_PROTOCOL)�protocolrrrrDscCstj|�sttj|��dS)N)rZ
checkProtocolrr
ry)rzrrrrJs
cCs$tj||�s ttjd||f��dS)Nz'%s' is not valid %s address)rrrr
ZINVALID_ADDR)ZipvZaddrrrrrNs)"rP�__all__Zxml.saxrfZxml.sax.saxutilsrnr�sys�collectionsr
ZfirewallrZfirewall.functionsrr
Zfirewall.errorsr�versionr�objectr�	ExceptionrQrVrXrgrhrrorrrrrrrrr�<module>s0

		Ccore/io/__pycache__/lockdown_whitelist.cpython-36.pyc000064400000022550150351351720016663 0ustar003

��g�1�@s�ddljZddlZddlZddlZddlmZddlmZm	Z	m
Z
mZddlm
Z
ddlmZmZmZmZmZmZddlmZddlmZGdd	�d	e
�ZGd
d�de	�ZdS)�N)�config)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator)�log)�uniqify�	checkUser�checkUid�checkCommand�checkContext�
u2b_if_py2)�errors)�
FirewallErrorc@seZdZdd�Zdd�ZdS)�!lockdown_whitelist_ContentHandlercCstj||�d|_dS)NF)r�__init__�	whitelist)�self�item�r�(/usr/lib/python3.6/lockdown_whitelist.pyr%sz*lockdown_whitelist_ContentHandler.__init__cCsVtj|||�|jj||�|dkr@|jr6ttjd��d|_�n|dkrr|js\tj	d�dS|d}|jj
|�n�|dkr�|js�tj	d�dSd	|kr�yt|d	�}Wn&tk
r�tj	d
|d	�dSX|jj
|�nd|kr�|jj|d�n\|dk�r@|j�stj	d�dSd
|k�r.tj	d�dS|jj|d
�ntj	d|�dSdS)NrzMore than one whitelist.T�commandz)Parse Error: command outside of whitelist�name�userz&Parse Error: user outside of whitelist�idz"Parse Error: %s is not a valid uid�selinuxz)Parse Error: selinux outside of whitelist�contextzParse Error: no contextzUnknown XML element %s)r�startElementrZparser_check_element_attrsrrrZPARSE_ERRORr�error�add_command�int�
ValueError�add_uid�add_user�add_context)rrZattrsr�uidrrrr)sJ






z.lockdown_whitelist_ContentHandler.startElementN)�__name__�
__module__�__qualname__rrrrrrr$srcs4eZdZdZddgfddgfddgfddgffZdZd	gZd
dgd
dgd
�ZdddgiZ�fdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�Zd<d=�Zd>d?�Z d@dA�Z!dBdC�Z"�Z#S)D�LockdownWhitelistz LockdownWhitelist class �commands��contexts�users�uidsrz
(asasasai)�_Nrr)rrrrrrcs6tt|�j�||_d|_g|_g|_g|_g|_dS)N)	�superr)r�filename�parserr*r,r-r.)rr1)�	__class__rrrnszLockdownWhitelist.__init__cCs�|d
kr.x�|D]}|j||dd�|�qWnv|dkrLt|�s�ttj|��nX|dkrjt|�s�ttj|��n:|dkr�t|�s�ttj|��n|d	kr�t	|�s�ttj
|��dS)Nr*r,r-r.�rrrr%)r*r,r-r.���)�
_check_configrrr�INVALID_COMMANDr�INVALID_CONTEXTr	�INVALID_USERr
�INVALID_UID)rrrZ
all_config�xrrrr6ys
zLockdownWhitelist._check_configcCs4|jdd�=|jdd�=|jdd�=|jdd�=dS)N)r*r,r-r.)rrrr�cleanup�szLockdownWhitelist.cleanupcCs:dd�|jD�|_dd�|jD�|_dd�|jD�|_dS)z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSsg|]}t|��qSr)r
)�.0r;rrr�
<listcomp>�sz4LockdownWhitelist.encode_strings.<locals>.<listcomp>cSsg|]}t|��qSr)r
)r=r;rrrr>�scSsg|]}t|��qSr)r
)r=r;rrrr>�sN)r*r,r-)rrrr�encode_strings�sz LockdownWhitelist.encode_stringscCs@t|�sttj|��||jkr,|jj|�nttjd|��dS)Nz!Command "%s" already in whitelist)rrrr7r*�append�ALREADY_ENABLED)rrrrrr�s
zLockdownWhitelist.add_commandcCs,||jkr|jj|�nttjd|��dS)NzCommand "%s" not in whitelist.)r*�removerr�NOT_ENABLED)rrrrr�remove_command�s
z LockdownWhitelist.remove_commandcCs
||jkS)N)r*)rrrrr�has_command�szLockdownWhitelist.has_commandcCsBx<|jD]2}|jd�r.|j|dd��r:dSq||krdSqWdS)N�*r4TFr5)r*�endswith�
startswith)rrZ_commandrrr�
match_command�s
zLockdownWhitelist.match_commandcCs|jS)N)r*)rrrr�get_commands�szLockdownWhitelist.get_commandscCsDt|�sttjt|���||jkr0|jj|�nttjd|��dS)NzUid "%s" already in whitelist)r
rrr:�strr.r@rA)rr%rrrr"�s
zLockdownWhitelist.add_uidcCs,||jkr|jj|�nttjd|��dS)NzUid "%s" not in whitelist.)r.rBrrrC)rr%rrr�
remove_uid�s
zLockdownWhitelist.remove_uidcCs
||jkS)N)r.)rr%rrr�has_uid�szLockdownWhitelist.has_uidcCs
||jkS)N)r.)rr%rrr�	match_uid�szLockdownWhitelist.match_uidcCs|jS)N)r.)rrrr�get_uids�szLockdownWhitelist.get_uidscCs@t|�sttj|��||jkr,|jj|�nttjd|��dS)NzUser "%s" already in whitelist)r	rrr9r-r@rA)rrrrrr#�s
zLockdownWhitelist.add_usercCs,||jkr|jj|�nttjd|��dS)NzUser "%s" not in whitelist.)r-rBrrrC)rrrrr�remove_user�s
zLockdownWhitelist.remove_usercCs
||jkS)N)r-)rrrrr�has_user�szLockdownWhitelist.has_usercCs
||jkS)N)r-)rrrrr�
match_user�szLockdownWhitelist.match_usercCs|jS)N)r-)rrrr�	get_users�szLockdownWhitelist.get_userscCs@t|�sttj|��||jkr,|jj|�nttjd|��dS)Nz!Context "%s" already in whitelist)rrrr8r,r@rA)rrrrrr$"s
zLockdownWhitelist.add_contextcCs,||jkr|jj|�nttjd|��dS)NzContext "%s" not in whitelist.)r,rBrrrC)rrrrr�remove_context,s
z LockdownWhitelist.remove_contextcCs
||jkS)N)r,)rrrrr�has_context3szLockdownWhitelist.has_contextcCs
||jkS)N)r,)rrrrr�
match_context6szLockdownWhitelist.match_contextcCs|jS)N)r,)rrrr�get_contexts9szLockdownWhitelist.get_contextscCs�|j�|jjd�s&ttjd|j��t|�}tj�}|j	|�y|j
|j�Wn8tjk
r�}zttjd|j
���WYdd}~XnX~~tr�|j�dS)Nz.xmlz'%s' is missing .xml suffixzNot a valid file: %s)r<r1rGrrZINVALID_NAMEr�saxZmake_parserZsetContentHandler�parseZSAXParseExceptionZINVALID_TYPEZgetExceptionrr?)r�handlerr2�msgrrr�read>s"
zLockdownWhitelist.readcCs�tjj|j�r\ytj|jd|j�Wn4tk
rZ}ztd|j|f��WYdd}~XnXtjjtj	�sxtj
tj	d�tj|jddd�}t
|�}|j�|jdi�|jd�x6t|j�D](}|jd	�|jd
d|i�|jd�q�Wx:t|j�D],}|jd	�|jdd
t|�i�|jd�q�Wx8t|j�D]*}|jd	�|jdd|i�|jd��q0Wx8t|j�D]*}|jd	�|jdd|i�|jd��qjW|jd�|jd�|j�|j�~dS)Nz%s.oldzBackup of '%s' failed: %si�ZwtzUTF-8)�mode�encodingr�
z  rrrrrr)�os�path�existsr1�shutilZcopy2�	Exception�IOErrorrZ
ETC_FIREWALLD�mkdir�io�openrZ
startDocumentrZignorableWhitespacerr*Z
simpleElementr.rKr-r,Z
endElementZendDocument�close)rr[�frZrr%rrrrr�writeQsB$






zLockdownWhitelist.write)$r&r'r(�__doc__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr6r<r?rrDrErIrJr"rLrMrNrOr#rPrQrRrSr$rTrUrVrWr\rk�
__classcell__rr)r3rr)WsL

	


1
r))Zxml.saxrXr`rgrcZfirewallrZfirewall.core.io.io_objectrrrrZfirewall.core.loggerrZfirewall.functionsrr	r
rrr
rZfirewall.errorsrrr)rrrr�<module>s
 3core/io/__pycache__/service.cpython-36.pyc000064400000020377150351351720014414 0ustar003

��g�2�@s�dddgZddljZddlZddlZddlZddlmZddlm	Z	ddl
mZmZm
Z
mZmZmZmZmZddlmZdd	lmZdd
lmZGdd�de�ZGdd
�d
e
�Zdd�Zddd�ZdS)�Service�service_reader�service_writer�N)�config)�
u2b_if_py2)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator�
check_port�check_tcpudp�check_protocol�
check_address)�log)�errors)�
FirewallErrorcs�eZdZd d!d"dd#gfddgfdddifddgfd	d$gfd
dgfddgff
Zdd
gZdddd�Zddgddgdgdgddgddgdgdgd�Z�fdd�Zdd�Zdd�Z	dd�Z
�ZS)%r�version��short�description�ports�modules�destination�	protocols�source_ports�includes�helpers�_�-N)rr�service�name�port�protocol�value�ipv4�ipv6r)rr!r"�modulerzsource-port�include�helpercsNtt|�j�d|_d|_d|_g|_g|_g|_i|_	g|_
g|_g|_dS)Nr)
�superr�__init__rrrrrrrrrr)�self)�	__class__��/usr/lib/python3.6/service.pyr*DszService.__init__cCshd|_d|_d|_|jdd�=|jdd�=|jdd�=|jj�|jdd�=|j	dd�=|j
dd�=dS)Nr)rrrrrrr�clearrrr)r+r-r-r.�cleanupQs
zService.cleanupcCs�t|j�|_t|j�|_t|j�|_dd�|jD�|_dd�|jD�|_dd�|jj�D�|_dd�|jD�|_dd�|j	D�|_	dd�|j
D�|_
d	d�|jD�|_d
S)z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSs g|]\}}t|�t|�f�qSr-)r)�.0�po�prr-r-r.�
<listcomp>dsz*Service.encode_strings.<locals>.<listcomp>cSsg|]}t|��qSr-)r)r1�mr-r-r.r4escSsi|]\}}t|�t|��qSr-)r)r1�k�vr-r-r.�
<dictcomp>fsz*Service.encode_strings.<locals>.<dictcomp>cSsg|]}t|��qSr-)r)r1r3r-r-r.r4gscSs g|]\}}t|�t|�f�qSr-)r)r1r2r3r-r-r.r4hscSsg|]}t|��qSr-)r)r1�sr-r-r.r4jscSsg|]}t|��qSr-)r)r1r9r-r-r.r4ksN)rrrrrrr�itemsrrrr)r+r-r-r.�encode_strings]szService.encode_stringscCs:|dkrJx>|D]6}|ddkr8t|d�t|d�qt|d�qWn�|dkrjx�|D]}t|�qXWn�|dkr�x�|D]}t|d�t|d�qxWn�|dkr�x�|D]*}|dkr�ttjd
|��t|||�q�Wn^|dk�r6xR|D]J}|jd��r|jdd�}d
|k�r|jd
d�}t	|�dkr�ttj
|��q�WdS)Nrrr�rrrr$r%z'%s' not in {'ipv4'|'ipv6'}r�
nf_conntrack_rr�)r$r%)rrr
rrZINVALID_DESTINATIONr�
startswith�replace�lenZINVALID_MODULE)r+r�itemZ
all_configr!�protorr&r-r-r.�
_check_configms8






zService._check_config)rr)rr)rr)rr)rr)�__name__�
__module__�__qualname__ZIMPORT_EXPORT_STRUCTUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSr*r0r;rD�
__classcell__r-r-)r,r.r&s4


c@seZdZdd�ZdS)�service_ContentHandlercCs0tj|||�|jj||�|dkrTd|kr<tjd|d�d|krP|d|j_�n�|dkr`�n�|dkrl�n�|dk�r$|ddkr�t|d�t|d	�|d|d	f}||jj	kr�|jj	j
|�ntjd
|d|d	�nBt|d	�|d	|jjk�r|jjj
|d	�ntjd|d	��n|d	k�rtt|d�|d|jjk�r`|jjj
|d�ntjd|d��n�|d
k�r�t|d�t|d	�|d|d	f}||jj
k�r�|jj
j
|�ntjd|d|d	��nN|dk�r>xRdD]J}||k�r�t|||�||jjk�r&tjd|�n|||jj|<�q�Wn�|dk�r�|d}|jd��r~|jdd�}d|k�r~|jdd�}||jjk�r�|jjj
|�ntjd|�n�|dk�r�|d|jjk�r�|jjj
|d�ntjd|d�n@|dk�r,|d|jjk�r|jjj
|d�ntjd|d�dS)Nrr z'Ignoring deprecated attribute name='%s'rrrr!rr"z#Port '%s/%s' already set, ignoring.z$Protocol '%s' already set, ignoring.r#zsource-portz)SourcePort '%s/%s' already set, ignoring.rr$r%z2Destination address for '%s' already set, ignoringr&r=rrz"Module '%s' already set, ignoring.r'z#Include '%s' already set, ignoring.r(z"Helper '%s' already set, ignoring.)r$r%)r	�startElementrBZparser_check_element_attrsrZwarningrrrr�appendr
rrrrr?r@rrr)r+r �attrs�entry�xr&r-r-r.rJ�s�










z#service_ContentHandler.startElementN)rErFrGrJr-r-r-r.rI�srIc	Cst�}|jd�s ttjd|��|dd	�|_|j|j�||_||_|j	t
j�rVdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}zttjd|j���WYdd}~XnXWdQRX~~t�r|j�|S)
Nz.xmlz'%s' is missing .xml suffix�FTz%s/%s�rbznot a valid service file: %s���)r�endswithrrZINVALID_NAMEr Z
check_name�filename�pathr?r�
ETC_FIREWALLDZbuiltin�defaultrI�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_SERVICEZgetExceptionrr;)	rSrTr�handler�parserr �f�source�msgr-r-r.r�s8




(cCsr|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�i}|j�r|jd	k�r|j|d
<|jd|�|jd�|j�rt|jd	k�rt|jd
�|jdi�|j|j�|jd�|jd�|j�r�|jd	k�r�|jd
�|jdi�|j|j�|jd�|jd�x>|jD]4}	|jd
�|jd|	d|	dd��|jd��q�Wx4|jD]*}
|jd
�|jdd|
i�|jd��qWx>|jD]4}	|jd
�|jd|	d|	dd��|jd��q<Wx4|jD]*}|jd
�|jdd|i�|jd��q|Wt|j �dk�r�|jd
�|jd|j �|jd�x4|j!D]*}|jd
�|jdd|i�|jd��q�Wx4|j"D]*}
|jd
�|jdd|
i�|jd��qW|jd�|jd�|j#�|j$�~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingrrr�
z  rrr!rr<)r!r"r"r#zsource-portr&r rr'r()%rTrSr �os�exists�shutilZcopy2�	Exceptionr�error�dirnamer?rrU�mkdir�iorXr
Z
startDocumentrrJZignorableWhitespacerZ
charactersZ
endElementrrZ
simpleElementrrrrArrrZendDocument�close)rrT�_pathr r^�dirpathr\rZrLr!r"r&r'r(r-r-r.rs� 

















)N)�__all__Zxml.saxrWrbrirdZfirewallrZfirewall.functionsrZfirewall.core.io.io_objectrrr	r
rrr
rZfirewall.core.loggerrrZfirewall.errorsrrrIrrr-r-r-r.�<module>s

(mQcore/io/__pycache__/zone.cpython-36.pyc000064400000031307150351351720013722 0ustar003

��g�M�@sdddgZddljZddlZddlZddlZddlmZddlm	Z	m
Z
mZmZm
Z
mZmZddlmZmZddlmZmZmZmZdd	lmZmZmZmZdd
lmZddlm Z ddlm!Z!dd
l"m#Z#Gdd�de�Z$Gdd�de�Z%ddd�Z&ddd�Z'dS)�Zone�zone_reader�zone_writer�N)�config)�checkIPnMask�
checkIP6nMask�checkInterface�uniqify�max_zone_name_len�
u2b_if_py2�	check_mac)�DEFAULT_ZONE_TARGET�ZONE_TARGETS)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator)�common_startElement�common_endElement�common_check_config�
common_writer)�rich)�log)�errors)�
FirewallErrorcsfeZdZdZd@dAdBdCdDd	dgfd
dEgfddgfdFd
dGgfddgfddgfddgfddgfddHgfdIdJfZdddgZddddgddgdgdgdddgdgddddgddgddddddgdgdd�Zddddgd gd!d"gd#d$gd%d&d'd#d(gd%d'd(gd)d*gd+gd,gd-�	Zed.d/��Z	�fd0d1�Z
d2d3�Zd4d5�Z�fd6d7�Z
�fd8d9�Zd:d;�Z�fd<d=�Zd>d?�Z�ZS)Krz Zone class �version��short�description�UNUSEDF�target�services�ports�icmp_blocks�
masquerade�
forward_ports�
interfaces�sources�	rules_str�	protocols�source_ports�icmp_block_inversion�forward�_�-�/N�name�port�protocol�value�set)rr�zone�servicer1z
icmp-blockz	icmp-typer,zforward-port�	interface�rule�source�destinationr2zsource-portrZauditZaccept�rejectZdropZmark�limitzicmp-block-inversion�	immutableZenabledzto-portzto-addr�familyZpriority�address�mac�invert�ipset�prefix�level�typeZburst)	r5r$zforward-portr8r9r:rr;r<cCs8x&ttj�D]\}\}}||kr|SqWttjd��dS)Nz
index_of())�	enumerater�IMPORT_EXPORT_STRUCTURErrZ
UNKNOWN_ERROR)�element�iZelZdummy�rJ�/usr/lib/python3.6/zone.py�index_ofdsz
Zone.index_ofcs�tt|�j�d|_d|_d|_d|_t|_g|_	g|_
g|_g|_d|_
d|_g|_g|_g|_g|_d|_g|_g|_d|_d|_d|_dS)NrF)�superr�__init__rrrrr
r r!r"r)r#r,r$r%r*r&r'�	fw_config�rulesr(r+�combined�applied)�self)�	__class__rJrKrNks,z
Zone.__init__cCs�d|_d|_d|_d|_t|_|jdd�=|jdd�=|jdd�=|j	dd�=d|_
d|_|jdd�=|j
dd�=|jdd�=|jdd�=d|_|jdd�=|jdd�=d|_d|_d|_dS)NrF)rrrrr
r r!r"r)r#r,r$r%r*r&r'rOrPr(r+rQrR)rSrJrJrK�cleanup�s*zZone.cleanupcCs�t|j�|_t|j�|_t|j�|_t|j�|_dd�|jD�|_dd�|jD�|_dd�|jD�|_dd�|jD�|_dd�|j	D�|_	dd�|j
D�|_
dd�|jD�|_d	d�|jD�|_d
d�|j
D�|_
dd�|jD�|_dS)
z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSsg|]}t|��qSrJ)r)�.0�srJrJrK�
<listcomp>�sz'Zone.encode_strings.<locals>.<listcomp>cSs g|]\}}t|�t|�f�qSrJ)r)rV�po�prrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrZrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrIrJrJrKrX�scSs0g|](\}}}}t|�t|�t|�t|�f�qSrJ)r)rVZp1Zp2Zp3Zp4rJrJrKrX�scSs g|]\}}t|�t|�f�qSrJ)r)rVrYrZrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrIrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrWrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrWrJrJrKrX�scSsg|]}t|��qSrJ)r)rVrWrJrJrKrX�sN)rrrrr r!r"r)r#r%r*r&r'rPr()rSrJrJrK�encode_strings�szZone.encode_stringscsN|dkr8dd�|D�|_tt|�j|dd�|jD��ntt|�j||�dS)Nr(cSsg|]}tj|d��qS))Zrule_str)rZ	Rich_Rule)rVrWrJrJrKrX�sz$Zone.__setattr__.<locals>.<listcomp>cSsg|]}t|��qSrJ)�str)rVrWrJrJrKrX�s)rPrMr�__setattr__)rSr0r3)rTrJrKr]�s zZone.__setattr__cstt|�j�}|d=|S)Nr)rMr�export_config_dict)rSZconf)rTrJrKr^�szZone.export_config_dictcCsLt||||�|dkr.|tkr*ttj|���n|dkr�xl|D]d}t|�sTttj|��|jr<xD|jj�D]6}||j	krvqf||jj
|�jkrfttjdj||���qfWq<Wn�|dk�rHx�|D]�}t
|�r�t|�r�t|�r�|jd�r�ttj|��|jr�xL|jj�D]>}||j	k�r�q||jj
|�jk�rttjdj||����qWq�WdS)Nr r&z)interface '{}' already bound to zone '{}'r'zipset:z&source '{}' already bound to zone '{}')rrrr�INVALID_TARGETrZINVALID_INTERFACErOZ	get_zonesr0Zget_zoner&�formatrrr�
startswith�INVALID_ADDRr')rSr�itemZ
all_configr7r5r9rJrJrK�
_check_config�s6



zZone._check_configcs�tt|�j|�|jd�r,ttjd|��n�|jd�rHttjd|��n�|jd�dkrhttjd|��nnd|kr�|d|j	d��}n|}t
|�t�kr�ttjd|t
|�t�|jf��|j
r�||j
j�kr�ttjd��dS)Nr/z'%s' can't start with '/'z'%s' can't end with '/'�zmore than one '/' in '%s'z'Zone of '%s' has %d chars, max is %d %sz+Zones can't have the same name as a policy.)rMr�
check_namerarr�INVALID_NAME�endswith�count�find�lenr
rQrOZget_policy_objectsZ
NAME_CONFLICT)rSr0Zchecked_name)rTrJrKrf�s,

zZone.check_namec
Cs�d|_d|_d|_d|_d|_x$|jD]}||jkr&|jj|�q&Wx$|jD]}||jkrL|jj|�qLWx$|jD]}||jkrr|jj|�qrWx$|j	D]}||j	kr�|j	j|�q�Wx$|j
D]}||j
kr�|j
j|�q�Wx$|jD]}||jkr�|jj|�q�W|j�rd|_|j
�rd|_
x(|jD]}||jk�r&|jj|��q&Wx(|jD]}||jk�rP|jj|��qPWx,|jD]"}	|jj|	�|jjt|	���qzW|j�r�d|_dS)NTr)rQ�filenamerrrr&�appendr'r!r"r)r#r,r$r%r*rPr(r\r+)
rSr5r7r9r6r1�protoZicmpr,r8rJrJrK�combine�sL





zZone.combine)rr)rr)rr)rF)r r)rr)r$F)rrrr)rr)r+F)r,F)�__name__�
__module__�__qualname__�__doc__rGZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRS�staticmethodrLrNrUr[r]r^rdrfro�
__classcell__rJrJ)rTrKr(sx


c@s$eZdZdd�Zdd�Zdd�ZdS)�zone_ContentHandlercCs"tj||�d|_d|_d|_dS)NF)rrN�_rule�_rule_errorZ	_limit_ok)rSrcrJrJrKrN szzone_ContentHandler.__init__c	Cs�tj|||�|jrdS|jj||�t|||�r6dS|dkr�d|krVtjd|d�d|krj|d|j_d|kr�tjd|d�d|kr�|d}|t	kr�t
tj|��|dkr�|t
kr�||j_�n�|d	kr�|jjr�tjd
�nd|j_�n�|dk�rh|j�rtjd
�d|_dSd|k�r.tjd�d|_dS|d|jjk�rT|jjj|d�ntjd|d��n8|dk�rf|j�r |jj�r�tjdt|j��d|_dSd}d|k�r�|dj�d$k�r�d}d}}}d|k�r�|d}d|k�r�|d}d|k�r|d}tj||||d�|j_dSd|k�rBd|k�rBtjd�dSd|k�rdd|k�rdtjd�dSd|k�r~tjd|d�d|k�r�tjd�dSd|k�r�t|d��r�t|d��r�t|d��r�t
tj|d��d|k�r$d|d}||jjk�r|jjj|�ntjd |d�d|k�r�|d}||jjk�rT|jjj|�ntjd |d�n:|d!k�r�|jj�r�tjd"�nd|j_ntjd#|�dSdS)%Nr5r0z'Ignoring deprecated attribute name='%s'rr=z,Ignoring deprecated attribute immutable='%s'r rr,zForward already set, ignoring.Tr7z$Invalid rule: interface use in rule.z Invalid interface: Name missing.z%Interface '%s' already set, ignoring.r9z:Invalid rule: More than one source in rule '%s', ignoring.FrA�yes�truer?r@rB)rAz$Invalid source: No address no ipset.z"Invalid source: Address and ipset.r>z)Ignoring deprecated attribute family='%s'z+Invalid source: Invertion not allowed here.zipset:%sz"Source '%s' already set, ignoring.zicmp-block-inversionz+Icmp-Block-Inversion already set, ignoring.zUnknown XML element '%s')ryrz)r�startElementrxrcZparser_check_element_attrsrrZwarningrrrrr_r
r r,rwr&rmr9r\�lowerrZRich_Sourcerrrrbr'r+)	rSr0�attrsr rAZaddrr@rB�entryrJrJrKr{&s�

























z zone_ContentHandler.startElementcCstj||�t||�dS)N)r�
endElementr)rSr0rJrJrKr�szzone_ContentHandler.endElementN)rprqrrrNr{rrJrJrJrKrvsprvFc
Cst�}|jd�s ttjd|��|dd	�|_|s>|j|j�||_||_|j	t
j�rZdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}	zttjd|	j���WYdd}	~	XnXWdQRX~~t�r|j�|S)
Nz.xmlz'%s' is missing .xml suffix�FTz%s/%s�rbznot a valid zone file: %s���)rrhrrrgr0rfrl�pathrar�
ETC_FIREWALLDZbuiltin�defaultrv�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_ZONEZgetExceptionrr[)
rlr�Z
no_check_namer5�handler�parserr0�fr9�msgrJrJrKr�s:




(cCs\|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�i}|j�r|jd	k�r|j|d
<|jtk�r*|j|d<|jd|�|jd
�t||�x8t|j�D]*}	|jd�|jdd|	i�|jd
��qVWx\t|j�D]N}
|jd�d|
k�r�|jdd|
dd�i�n|jdd|
i�|jd
��q�W|j�r
|jd�|jdi�|jd
�|j�r2|jd�|jdi�|jd
�|jd�|jd
�|j �|j!�~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingrrr r5�
z  r7r0zipset:r9rB�r?zicmp-block-inversionr,)"r�rlr0�os�exists�shutilZcopy2�	Exceptionr�error�dirnamerarr��mkdir�ior�rZ
startDocumentrr r
r{ZignorableWhitespacerr	r&Z
simpleElementr'r+r,rZendDocument�close)r5r��_pathr0r��dirpathr�r�r}r7r9rJrJrKr�s` 












)F)N)(�__all__Zxml.saxr�r�r�r�ZfirewallrZfirewall.functionsrrrr	r
rrZfirewall.core.baser
rZfirewall.core.io.io_objectrrrrZfirewall.core.io.policyrrrrZ
firewall.corerZfirewall.core.loggerrrZfirewall.errorsrrrvrrrJrJrJrK�<module>s$

$x|
core/io/__pycache__/ifcfg.cpython-36.pyc000064400000007721150351351720014030 0ustar003

��g��@s^dZdgZddlZddlZddlZddlZddlmZddl	m
Z
mZmZGdd�de
�ZdS)zifcfg file parser�ifcfg�N)�log)�b2u�u2b�PY2c@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dS)rcCsi|_g|_||_|j�dS)N)�_config�_deleted�filename�clear)�selfr	�r�/usr/lib/python3.6/ifcfg.py�__init__#szifcfg.__init__cCsi|_g|_dS)N)rr)rrrr
r
)szifcfg.clearcCs|jj�dS)N)rr
)rrrr
�cleanup-sz
ifcfg.cleanupcCs|jj|j��S)N)r�get�strip)r�keyrrr
r0sz	ifcfg.getcCs8t|j��}t|j��|j|<||jkr4|jj|�dS)N)rrrr�remove)rr�valueZ_keyrrr
�set3s
z	ifcfg.setcCsHd}x2|jj�D]$\}}|r$|d7}|d||f7}qWtrDt|�S|S)N��
z%s=%s)r�itemsrr)r�srrrrr
�__str__9sz
ifcfg.__str__cCsB|j�yt|jd�}Wn4tk
rL}ztjd|j|��WYdd}~XnXx�|D]�}|s^P|j�}t|�dksT|ddkr�qTdd�|jd	d�D�}t|�d
kr�qTt|d�d
kr�|dj	d�r�|dj
d�r�|ddd�|d<|ddkr�qTn,|jj|d�dk	�r tj
d
|j|j��qT|d|j|d<qTW|j�dS)N�rzFailed to load '%s': %s�r�#�;cSsg|]}|j��qSr)r)�.0�xrrr
�
<listcomp>Qszifcfg.read.<locals>.<listcomp>�=��"rz%%s: Duplicate option definition: '%s')rr���)r
�openr	�	Exceptionr�errorr�len�split�
startswith�endswithrrZwarning�close)r�f�msg�lineZpairrrr
�readBs2
z
ifcfg.readc:Cs�t|j�dkrdSg}y.tjddtjj|j�tjj|j�dd�}Wn2t	k
rv}zt
jd|��WYdd}~XnXd}d}ytj
|jddd	�}WnNt	k
r�}z0tjj|j�r�t
jd
|j|f��nd}WYdd}~X�ndX�x^|D�]T}|s�P|jd�}t|�dk�r(|�sD|jd�d}q�|d
dk�rPd}|j|�|jd�q�|jdd�}t|�dk�r~d}|j|d�q�|d
j�}	|dj�}
t|
�dk�r�|
jd��r�|
jd��r�|
dd�}
|	|k�r@|	|jk�r|j|	|
k�rd}|jd|	|j|	f�d}n$|	|jk�r"d}nd}|j|d�|j|	�q�d}q�Wt|j�d
k�r�xF|jj�D]8\}	}
|	|k�rz�qd|�s�d}|jd|	|
f�d}�qdW|�r�|j�|j�|�s�tj|j�dStjj|j��r8ytj|jd|j�WnBt	k
�r6}z$tj|j�td|j|f��WYdd}~XnXytj|j|j�WnBt	k
�r�}z$tj|j�td|j|f��WYdd}~XnXtj|jd�dS)NrZwtz%s.F)�mode�prefix�dir�deletez!Failed to open temporary file: %sZrtzUTF-8)r2�encodingzFailed to open '%s': %srTrrr"r#r$z%s=%s
z%s.bakzBackup of '%s' failed: %szFailed to create '%s': %si�r%)r)r�tempfileZNamedTemporaryFile�os�path�basenamer	�dirnamer'rr(�ior&�existsr�writer*r+r,r�appendrr-r�name�shutilZcopy2�IOErrorZmove�chmod)r�doneZ	temp_filer/Zmodified�emptyr.r0�prrrrr
r>_s�





$$zifcfg.writeN)�__name__�
__module__�__qualname__rr
rrrrr1r>rrrr
r"s	)�__doc__�__all__Zos.pathr8r<r7rAZfirewall.core.loggerrZfirewall.functionsrrr�objectrrrrr
�<module>score/io/__pycache__/direct.cpython-36.opt-1.pyc000064400000027263150351351720015166 0ustar003

��g�=�@s�ddljZddlZddlZddlZddlmZddlmZddl	m
Z
mZmZddl
mZmZmZddlmZddlmZddlmZdd	lmZdd
lmZGdd�de�ZGd
d�de�ZdS)�N)�config)�LastUpdatedOrderedDict)�	splitArgs�joinArgs�
u2b_if_py2)�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator)�log)�	ipXtables)�ebtables)�errors)�
FirewallErrorc@s$eZdZdd�Zdd�Zdd�ZdS)�direct_ContentHandlercCstj||�d|_dS)NF)r�__init__�direct)�self�item�r�/usr/lib/python3.6/direct.pyr(szdirect_ContentHandler.__init__cCs�tj|||�|jj||�|dkr@|jr6ttjd��d|_�n>|dkr�|js\tj	d�dS|d}|d}|d}|jj
t|�t|�t|��n�|dk�r6|js�tj	d	�dS|d}|dkr�ttjd
|��|d}|d}yt
|d�}Wn(tk
�rtj	d|d�dSXt|�t|�t|�|g|_nH|dk�rl|j�sVtj	d�dS|d}t|�g|_ntj	d|�dSdS)NrzMore than one direct tag.T�chainz$Parse Error: chain outside of direct�ipv�table�rulez#Parse Error: rule outside of direct�ipv4�ipv6�ebz"'%s' not from {'ipv4'|'ipv6'|'eb'}�priorityz'Parse Error: %s is not a valid priority�passthroughz&Parse Error: command outside of directzUnknown XML element %s)rrr)r�startElementrZparser_check_element_attrsrrr
ZPARSE_ERRORr
�error�	add_chainr�INVALID_IPV�int�
ValueError�_rule�_passthrough)r�nameZattrsrrrrrrrr,sT






z"direct_ContentHandler.startElementcCs�tj||�|dkrX|jrF|jjdd�t|j�D��|jj|j�n
tj	d�d|_nJ|dkr�|jr�|j
jdd�t|j�D��|jj|j
�n
tj	d	�d|_
dS)
NrcSsg|]}t|��qSr)r)�.0�xrrr�
<listcomp>dsz4direct_ContentHandler.endElement.<locals>.<listcomp>z2Error: rule does not have any arguments, ignoring.rcSsg|]}t|��qSr)r)r(r)rrrr*msz0Error: passthrough does not have any arguments, z	ignoring.z9Error: passthrough does not have any arguments, ignoring.)r�
endElementZ_elementr%�appendrr�add_ruler
r r&�add_passthrough)rr'rrrr+^s 
z direct_ContentHandler.endElementN)�__name__�
__module__�__qualname__rrr+rrrrr's2rcs<eZdZdZddBgfddddddgfgfdddgfgffZdZdd	d
dgd	d
ddgd	gd
�ZiZ�fdd�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�Zd<d=�Zd>d?�Z d@dA�Z!�Z"S)C�Directz Direct class �chains��rulesr�passthroughsz(a(sss)a(sssias)a(sas))Nrrrr)rrrrcs0tt|�j�||_t�|_t�|_t�|_dS)N)�superr2r�filenamerr3r5r6)rr8)�	__class__rrr�s
zDirect.__init__cCsdS)Nr)r�confrZall_confrrr�
_check_config�szDirect._check_configcCsg}g}x>|jD]4}x.|j|D] }|jtt|�t|g���q WqW|j|�g}xR|jD]H}xB|j|D]4}|jt|d|d|d|dt|d�f��qnWq^W|j|�g}x8|jD].}x(|j|D]}|jt|t|�f��q�Wq�W|j|�t|�S)Nr��)r3r,�tuple�listr5r6)r�retr)�keyrrrrr�
export_config�s$$


zDirect.export_configcCs�|j�|j|�x�t|j�D]x\}\}}|dkrNx||D]}|j|�q<W|dkrrx||D]}|j|�q`W|dkrx||D]}|j|�q�WqWdS)Nr3r5r6)�cleanupZcheck_config�	enumerate�IMPORT_EXPORT_STRUCTUREr!r-r.)rr:�i�elementZdummyr)rrr�
import_config�s
zDirect.import_configcCs"|jj�|jj�|jj�dS)N)r3�clearr5r6)rrrrrC�s

zDirect.cleanupcCs�td�x4|jD]*}td|d|ddj|j|�f�qWtd�xZ|jD]P}td|d|d|df�x,|j|D]\}}td	|d
j|�f�q|WqNWtd�x@|jD]6}td|�x$|j|D]}td
d
j|��q�Wq�WdS)Nr3z  (%s, %s): %srr<�,r5z  (%s, %s, %s):r=z    (%d, ('%s'))z','r6z  %s:z
    ('%s'))�printr3�joinr5r6)rrAr�argsrrr�output�sz
Direct.outputcCs*dddg}||kr&ttjd||f��dS)Nrrrz'%s' not in '%s')rr
r")rrZipvsrrr�
_check_ipv�s
zDirect._check_ipvcCsF|j|�|dkrtjj�ntjj�}||krBttjd||f��dS)Nrrz'%s' not in '%s')rr)rOrZBUILT_IN_CHAINS�keysrrr
Z
INVALID_TABLE)rrrZtablesrrr�_check_ipv_table�s

zDirect._check_ipv_tablecCsd|j||�||f}||jkr(g|j|<||j|krH|j|j|�ntjd|||fd�dS)Nz(Chain '%s' for table '%s' with ipv '%s' zalready in list, ignoring)rQr3r,r
�warning)rrrrrArrrr!�s

zDirect.add_chaincCsn|j||�||f}||jkrX||j|krX|j|j|�t|j|�dkrj|j|=ntd|||f��dS)Nrz4Chain '%s' with table '%s' with ipv '%s' not in list)rQr3�remove�lenr$)rrrrrArrr�remove_chain�s
zDirect.remove_chaincCs,|j||�||f}||jko*||j|kS)N)rQr3)rrrrrArrr�query_chain�szDirect.query_chaincCs<|j||�||f}||jkr(|j|Std||f��dS)Nz&No chains for table '%s' with ipv '%s')rQr3r$)rrrrArrr�
get_chains�s

zDirect.get_chainscCs|jS)N)r3)rrrr�get_all_chainsszDirect.get_all_chainscCs�|j||�|||f}||jkr,t�|j|<|t|�f}||j|krV||j||<n*tjddj|�||fd||fd�dS)Nz(Rule '%s' for table '%s' and chain '%s' z',zwith ipv '%s' and priority %d zalready in list, ignoring)rQr5rr>r
rRrL)rrrrrrMrA�valuerrrr-s

zDirect.add_rulecCs�|j||�|||f}|t|�f}||jkrb||j|krb|j||=t|j|�dkr�|j|=n$tddj|�||fd||f��dS)Nrz(Rule '%s' for table '%s' and chain '%s' z',z)with ipv '%s' and priority %d not in list)rQr>r5rTr$rL)rrrrrrMrArYrrr�remove_rules

zDirect.remove_rulecCsb|j||�|||f}||jkr^x"|j|j�D]}|j||=q0Wt|j|�dkr^|j|=dS)Nr)rQr5rPrT)rrrrrArYrrr�remove_rules"s

zDirect.remove_rulescCs:|j||�|||f}|t|�f}||jko8||j|kS)N)rQr>r5)rrrrrrMrArYrrr�
query_rule+s
zDirect.query_rulecCsF|j||�|||f}||jkr*|j|Std||fd|��dS)Nz'No rules for table '%s' and chain '%s' z
with ipv '%s')rQr5r$)rrrrrArrr�	get_rules1s


zDirect.get_rulescCs|jS)N)r5)rrrr�
get_all_rules:szDirect.get_all_rulescCs^|j|�||jkrg|j|<||j|kr>|j|j|�ntjddj|�|fd�dS)NzPassthrough '%s' for ipv '%s'z',zalready in list, ignoring)rOr6r,r
rRrL)rrrMrrrr.?s


zDirect.add_passthroughcCsl|j|�||jkrN||j|krN|j|j|�t|j|�dkrh|j|=ntddj|�|fd��dS)NrzPassthrough '%s' for ipv '%s'z',znot in list)rOr6rSrTr$rL)rrrMrrr�remove_passthroughIs

zDirect.remove_passthroughcCs"|j|�||jko ||j|kS)N)rOr6)rrrMrrr�query_passthroughSs
zDirect.query_passthroughcCs.|j|�||jkr|j|Std|��dS)NzNo passthroughs for ipv '%s')rOr6r$)rrrrr�get_passthroughsWs


zDirect.get_passthroughscCs|jS)N)r6)rrrr�get_all_passthroughs^szDirect.get_all_passthroughscCs�|j�|jjd�s&ttjd|j��t|�}tj�}|j	|�t
|jd��b}tjd�}|j|�y|j
|�Wn8tjk
r�}zttjd|j���WYdd}~XnXWdQRXdS)Nz.xmlz'%s' is missing .xml suffix�rbzNot a valid file: %s)rCr8�endswithrr
ZINVALID_NAMEr�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_TYPEZgetException)r�handler�parser�f�source�msgrrr�readcs 


zDirect.readc
CsBtjj|j�r\ytj|jd|j�Wn4tk
rZ}ztd|j|f��WYdd}~XnXtjjtj	�sxtj
tj	d�tj|jddd�}t
|�}|j�|jdi�|jd�xR|jD]H}|\}}x:|j|D],}|jd	�|jd
|||d��|jd�q�Wq�Wx�|jD]�}|\}}}xx|j|D]j\}}	t|	�dk�r@�q&|jd	�|jd
|||d|d��|jtjjt|	���|jd
�|jd��q&W�qWx||jD]r}xj|j|D]\}	t|	�dk�rȐq�|jd	�|jdd|i�|jtjjt|	���|jd�|jd��q�W�q�W|jd�|jd�|j�|j�~dS)Nz%s.oldzBackup of '%s' failed: %si�ZwtzUTF-8)�mode�encodingr�
z  r)rrrr<rz%d)rrrrrr)�os�path�existsr8�shutilZcopy2�	Exception�IOErrorrZ
ETC_FIREWALLD�mkdir�iorfr	Z
startDocumentrZignorableWhitespacer3Z
simpleElementr5rTreZsaxutils�escaperr+r6ZendDocument�close)
rrlrjrhrArrrrrMrrr�writeusZ$











zDirect.write)r4r4r4)#r/r0r1�__doc__rEZDBUS_SIGNATUREZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr;rBrHrCrNrOrQr!rUrVrWrXr-rZr[r\r]r^r.r_r`rarbrmr{�
__classcell__rr)r9rr2usH

	
		

r2)Zxml.saxrerqrxrtZfirewallrZfirewall.fw_typesrZfirewall.functionsrrrZfirewall.core.io.io_objectrrr	Zfirewall.core.loggerr
Z
firewall.corerrr
Zfirewall.errorsrrr2rrrr�<module>s
Ncore/io/__pycache__/__init__.cpython-36.pyc000064400000001227150351351720014504 0ustar003

��g<�@sjddlZdejkrfddlmZeed�s<dd�Zeede�ddlmZeed�sfd	d
�Z	eede	�dS)�NZ_xmlplus)�AttributesImpl�__contains__cCs|t|d�kS)NZ_attrs)�getattr)�self�name�r�/usr/lib/python3.6/__init__.py�__AttributesImpl__contains__sr	)�XMLGeneratorZ_writecCst|d�j|�dS)NZ_out)r�write)r�textrrr�__XMLGenerator_write$sr
)
Zxml�__file__Zxml.sax.xmlreaderr�hasattrr	�setattrZxml.sax.saxutilsr
r
rrrr�<module>s


core/io/__pycache__/__init__.cpython-36.opt-1.pyc000064400000001227150351351720015443 0ustar003

��g<�@sjddlZdejkrfddlmZeed�s<dd�Zeede�ddlmZeed�sfd	d
�Z	eede	�dS)�NZ_xmlplus)�AttributesImpl�__contains__cCs|t|d�kS)NZ_attrs)�getattr)�self�name�r�/usr/lib/python3.6/__init__.py�__AttributesImpl__contains__sr	)�XMLGeneratorZ_writecCst|d�j|�dS)NZ_out)r�write)r�textrrr�__XMLGenerator_write$sr
)
Zxml�__file__Zxml.sax.xmlreaderr�hasattrr	�setattrZxml.sax.saxutilsr
r
rrrr�<module>s


core/io/__pycache__/ipset.cpython-36.opt-1.pyc000064400000025614150351351720015036 0ustar003

��g�R�@sdZdddgZddljZddlZddlZddlZddlmZddl	m
Z
mZmZm
Z
mZmZmZmZmZddlmZmZmZmZdd	lmZmZdd
lmZmZmZmZddl m!Z!ddlm"Z"dd
l#m$Z$Gdd�de�Z%Gdd�de�Z&dd�Z'ddd�Z(dS)z$ipset io XML handler, reader, writer�IPSet�ipset_reader�ipset_writer�N)�config)	�checkIP�checkIP6�checkIPnMask�
checkIP6nMask�
u2b_if_py2�	check_mac�
check_port�checkInterface�
checkProtocol)�PY2�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator)�IPSET_TYPES�IPSET_CREATE_OPTIONS)�check_icmp_name�check_icmp_type�check_icmpv6_name�check_icmpv6_type)�log)�errors)�
FirewallErrorcs�eZdZddd d!dddifddgffZdZd	d
ddgZd
d
dgdgd
d�Zdgdgd�Z�fdd�Zdd�Z	dd�Z
edd��Zdd�Z
�fdd�Z�ZS)"r�version��short�description�type�options�entriesz
(ssssa{ss}as)�_�-�:�.N�name)rr�ipset�option�entry�value)r(r)cs<tt|�j�d|_d|_d|_d|_g|_i|_d|_	dS)NrF)
�superr�__init__rrrr r"r!�applied)�self)�	__class__��/usr/lib/python3.6/ipset.pyr-CszIPSet.__init__cCs8d|_d|_d|_d|_|jdd�=|jj�d|_dS)NrF)rrrr r"r!�clearr.)r/r1r1r2�cleanupMs
z
IPSet.cleanupcCs\t|j�|_t|j�|_t|j�|_t|j�|_dd�|jj�D�|_dd�|jD�|_dS)z� HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support.cSsi|]\}}t|�t|��qSr1)r
)�.0�k�vr1r1r2�
<dictcomp>^sz(IPSet.encode_strings.<locals>.<dictcomp>cSsg|]}t|��qSr1)r
)r5�er1r1r2�
<listcomp>`sz(IPSet.encode_strings.<locals>.<listcomp>N)r
rrrr r!�itemsr")r/r1r1r2�encode_stringsVszIPSet.encode_stringsc
Csd}d|kr|ddkrd}|jd�s6ttjd|��|dd�jd�}|jd�}t|�t|�ksnt|�d	kr�ttjd
||f���xztt|��D�]h}||}||}|dk�r�d|ko�|dk�rh|d	kr�ttjd
|||f��|jd�}	t|	�dk�rttjd||||f��x�|	D]J}
|dk�r2t|
��sH|dk�rt	|
��rttjd|
|||f���qWnh|dk�r�|dk�r�ttjd||||f��|dk�r�t
}nt}nt	}||��s�ttjd||||f��q�|dk�r@d|k�r�|jd�}	t|	�dk�rttjd||||f��|dk�r0t|	d��sJ|dk�rft	|	d��rfttjd|	d|||f��|dk�r�t
|	d	��s�|dk�r>t|	d	��r>ttjd|	d	|||f��n�|jd��r�|dk�o�|dk�o�|dk�s�ttjd||||f��|dk�rt
|��s&|dk�r�t|��r�ttjd||||f��q�|dk�rvt
|��s`|dk�r�ttjd||f��q�|dk�r�d|k�r�|jd�}	t|	�dk�r�ttjd|��|	ddk�r|dk�r�ttjd||f��t|	d	��r�t|	d	��r�ttjd|	d	|f��n�|	dd1k�r~|dk�rDttjd||f��t|	d	��r�t|	d	��r�ttjd!|	d	|f��n^|	dd2k�r�t|	d��r�ttjd&|	d|f��n&t|	d	��s�ttjd'|	d	|f��nt|��s�ttjd(||f��q�|d)k�r�|jd*��rPyt|d+�}Wn*tk
�rLttjd,||f��YnXn8yt|�}Wn*tk
�r�ttjd,||f��YnX|dk�s�|d-k�r�ttjd,||f��q�|d.k�r�t|��s�t|�d/k�r�ttjd0||f��q�ttjd|��q�WdS)3NZipv4�family�inet6Zipv6zhash:zipset type '%s' not usable��,�z)entry '%s' does not match ipset type '%s'Zipr$z invalid address '%s' in '%s'[%d]�z.invalid address range '%s' in '%s' for %s (%s)z(invalid address '%s' in '%s' for %s (%s)z0.0.0.0rZnetz/0zhash:net,ifaceZmacz00:00:00:00:00:00z invalid mac address '%s' in '%s'Zportr%zinvalid port '%s'Zicmpz(invalid protocol for family '%s' in '%s'zinvalid icmp type '%s' in '%s'�icmpv6�	ipv6-icmpz invalid icmpv6 type '%s' in '%s'�tcp�sctp�udp�udplitezinvalid protocol '%s' in '%s'zinvalid port '%s'in '%s'zinvalid port '%s' in '%s'ZmarkZ0x�zinvalid mark '%s' in '%s'l��Ziface�zinvalid interface '%s' in '%s')rCrD)rErFrGrH)�
startswithrr�
INVALID_IPSET�split�lenZ
INVALID_ENTRY�rangerrrr	�endswithrrrrrrr�int�
ValueErrorr
)
r*r!Z
ipset_typer=�flagsr;�i�flag�itemZsplitsZ_splitZip_checkZint_valr1r1r2�check_entrybs@























zIPSet.check_entrycCs�|dkr |tkr ttjd|��|dkr�x�|j�D]�}|tkrNttjd|��|dkr�yt||�}Wn,tk
r�ttj	d|||f��YnX|d	kr�ttj	d
|||f��q2|dkr2||dkr2ttj
||��q2WdS)Nr z'%s' is not valid ipset typer!zipset invalid option '%s'�timeout�hashsize�maxelemz)Option '%s': Value '%s' is not an integerrz#Option '%s': Value '%s' is negativer=�inetr>)rXrYrZ)r[r>)rrr�INVALID_TYPE�keysrrLrQrR�
INVALID_VALUE�INVALID_FAMILY)r/rrVZ
all_config�key�	int_valuer1r1r2�
_check_configs2

zIPSet._check_configcsrd|dkr6|dddkr6t|d�dkr6ttj��x&|dD]}tj||d|d�q@Wtt|�j|�dS)NrX��0r?r�)rNrrZIPSET_WITH_TIMEOUTrrWr,�
import_config)r/rr*)r0r1r2rf3s
zIPSet.import_config)rr)rr)rr)r r)�__name__�
__module__�__qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSr-r4r<�staticmethodrWrbrf�
__classcell__r1r1)r0r2r,s,


	7c@seZdZdd�Zdd�ZdS)�ipset_ContentHandlerc
Cs�tj|||�|jj||�|dkrpd|krX|dtkrLttjd|d��|d|j_d|krl|d|j_	�nz|dkr|�nn|dkr��nb|dk�r�d}d	|kr�|d	}|d
dkr�ttj
d|d
��|jjdko�|d
dk�r�ttj
d|d
|jjf��|d
dk�r&|�r&ttj
d|d
��|d
dk�r�yt|�}Wn.tk
�rnttj
d|d
|f��YnX|dk�r�ttj
d|d
|f��|d
dk�r�|dk�r�ttj|��|d
|jjk�r�||jj|d
<ntjd|d
�dS)Nr(r z%srrrr)rr+r'r=rXrYrZzUnknown option '%s'zhash:macz%Unsupported option '%s' for type '%s'z&Missing mandatory value of option '%s'z)Option '%s': Value '%s' is not an integerrz#Option '%s': Value '%s' is negativer[r>z Option %s already set, ignoring.)r=rXrYrZ)r=)r=rXrYrZ)rXrYrZ)r[r>)r�startElementrVZparser_check_element_attrsrrrr\r rZINVALID_OPTIONrQrRr^r_r!r�warning)r/r'�attrsr+rar1r1r2rm>sd

z!ipset_ContentHandler.startElementcCs(tj||�|dkr$|jjj|j�dS)Nr*)r�
endElementrVr"�appendZ_element)r/r'r1r1r2rpuszipset_ContentHandler.endElementN)rgrhrirmrpr1r1r1r2rl=s7rlc%Cst�}|jd�s ttjd|��|dd�|_|j|j�||_||_|j	t
j�rVdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}zttjd|j���WYdd}~XnXWdQRX~~d	|jk�rF|jd	d
k�rFt|j�dk�rFtjd|j�|jdd�=d}	t�}
x�|	t|j�k�r|j|	|
k�r�tjd
|j|	�|jj|	�nry|j |j|	|j|j!�Wn<tk
�r�}ztjd|�|jj|	�WYdd}~XnX|
j"|j|	�|	d7}	�qRW~
t#�r|j$�|S)Nz.xmlz'%s' is missing .xml suffixrcFTz%s/%s�rbznot a valid ipset file: %srXrdrz6ipset '%s': timeout option is set, entries are ignoredzEntry %s already set, ignoring.z
%s, ignoring.rA���)%rrPrrZINVALID_NAMEr'Z
check_name�filename�pathrKr�
ETC_FIREWALLDZbuiltin�defaultrl�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionrLZgetExceptionr!rNr"rrn�set�poprWr �addrr<)rtrur(�handler�parserr'�f�source�msgrTZentries_setr9r1r1r2rzs^




(cCs�|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�d	|ji}|j�r|jd
k�r|j|d<|jd|�|jd
�|j�rz|jd
k�rz|jd�|jdi�|j|j�|jd�|jd
�|j�r�|jd
k�r�|jd�|jdi�|j|j�|jd�|jd
�xZ|jj�D]L\}	}
|jd�|
d
k�r|jd|	|
d��n|jdd|	i�|jd
��q�WxD|jD]:}|jd�|jdi�|j|�|jd�|jd
��q(W|jd�|jd
�|j�|j �~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingr rrr(�
z  rrr))r'r+r'r*)!rurtr'�os�exists�shutilZcopy2�	Exceptionr�error�dirnamerKrrv�mkdir�ioryrZ
startDocumentr rrmZignorableWhitespacerZ
charactersrprr!r;Z
simpleElementr"ZendDocument�close)r(ru�_pathr'r��dirpathr�r~ror`r+r*r1r1r2r�sf 















)N))�__doc__�__all__Zxml.saxrxr�r�r�ZfirewallrZfirewall.functionsrrrr	r
rrr
rZfirewall.core.io.io_objectrrrrZfirewall.core.ipsetrrZfirewall.core.icmprrrrZfirewall.core.loggerrrZfirewall.errorsrrrlrrr1r1r1r2�<module>s&

,=5core/io/__pycache__/direct.cpython-36.pyc000064400000027263150351351720014227 0ustar003

��g�=�@s�ddljZddlZddlZddlZddlmZddlmZddl	m
Z
mZmZddl
mZmZmZddlmZddlmZddlmZdd	lmZdd
lmZGdd�de�ZGd
d�de�ZdS)�N)�config)�LastUpdatedOrderedDict)�	splitArgs�joinArgs�
u2b_if_py2)�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator)�log)�	ipXtables)�ebtables)�errors)�
FirewallErrorc@s$eZdZdd�Zdd�Zdd�ZdS)�direct_ContentHandlercCstj||�d|_dS)NF)r�__init__�direct)�self�item�r�/usr/lib/python3.6/direct.pyr(szdirect_ContentHandler.__init__cCs�tj|||�|jj||�|dkr@|jr6ttjd��d|_�n>|dkr�|js\tj	d�dS|d}|d}|d}|jj
t|�t|�t|��n�|dk�r6|js�tj	d	�dS|d}|dkr�ttjd
|��|d}|d}yt
|d�}Wn(tk
�rtj	d|d�dSXt|�t|�t|�|g|_nH|dk�rl|j�sVtj	d�dS|d}t|�g|_ntj	d|�dSdS)NrzMore than one direct tag.T�chainz$Parse Error: chain outside of direct�ipv�table�rulez#Parse Error: rule outside of direct�ipv4�ipv6�ebz"'%s' not from {'ipv4'|'ipv6'|'eb'}�priorityz'Parse Error: %s is not a valid priority�passthroughz&Parse Error: command outside of directzUnknown XML element %s)rrr)r�startElementrZparser_check_element_attrsrrr
ZPARSE_ERRORr
�error�	add_chainr�INVALID_IPV�int�
ValueError�_rule�_passthrough)r�nameZattrsrrrrrrrr,sT






z"direct_ContentHandler.startElementcCs�tj||�|dkrX|jrF|jjdd�t|j�D��|jj|j�n
tj	d�d|_nJ|dkr�|jr�|j
jdd�t|j�D��|jj|j
�n
tj	d	�d|_
dS)
NrcSsg|]}t|��qSr)r)�.0�xrrr�
<listcomp>dsz4direct_ContentHandler.endElement.<locals>.<listcomp>z2Error: rule does not have any arguments, ignoring.rcSsg|]}t|��qSr)r)r(r)rrrr*msz0Error: passthrough does not have any arguments, z	ignoring.z9Error: passthrough does not have any arguments, ignoring.)r�
endElementZ_elementr%�appendrr�add_ruler
r r&�add_passthrough)rr'rrrr+^s 
z direct_ContentHandler.endElementN)�__name__�
__module__�__qualname__rrr+rrrrr's2rcs<eZdZdZddBgfddddddgfgfdddgfgffZdZdd	d
dgd	d
ddgd	gd
�ZiZ�fdd�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�Zd<d=�Zd>d?�Z d@dA�Z!�Z"S)C�Directz Direct class �chains��rulesr�passthroughsz(a(sss)a(sssias)a(sas))Nrrrr)rrrrcs0tt|�j�||_t�|_t�|_t�|_dS)N)�superr2r�filenamerr3r5r6)rr8)�	__class__rrr�s
zDirect.__init__cCsdS)Nr)r�confrZall_confrrr�
_check_config�szDirect._check_configcCsg}g}x>|jD]4}x.|j|D] }|jtt|�t|g���q WqW|j|�g}xR|jD]H}xB|j|D]4}|jt|d|d|d|dt|d�f��qnWq^W|j|�g}x8|jD].}x(|j|D]}|jt|t|�f��q�Wq�W|j|�t|�S)Nr��)r3r,�tuple�listr5r6)r�retr)�keyrrrrr�
export_config�s$$


zDirect.export_configcCs�|j�|j|�x�t|j�D]x\}\}}|dkrNx||D]}|j|�q<W|dkrrx||D]}|j|�q`W|dkrx||D]}|j|�q�WqWdS)Nr3r5r6)�cleanupZcheck_config�	enumerate�IMPORT_EXPORT_STRUCTUREr!r-r.)rr:�i�elementZdummyr)rrr�
import_config�s
zDirect.import_configcCs"|jj�|jj�|jj�dS)N)r3�clearr5r6)rrrrrC�s

zDirect.cleanupcCs�td�x4|jD]*}td|d|ddj|j|�f�qWtd�xZ|jD]P}td|d|d|df�x,|j|D]\}}td	|d
j|�f�q|WqNWtd�x@|jD]6}td|�x$|j|D]}td
d
j|��q�Wq�WdS)Nr3z  (%s, %s): %srr<�,r5z  (%s, %s, %s):r=z    (%d, ('%s'))z','r6z  %s:z
    ('%s'))�printr3�joinr5r6)rrAr�argsrrr�output�sz
Direct.outputcCs*dddg}||kr&ttjd||f��dS)Nrrrz'%s' not in '%s')rr
r")rrZipvsrrr�
_check_ipv�s
zDirect._check_ipvcCsF|j|�|dkrtjj�ntjj�}||krBttjd||f��dS)Nrrz'%s' not in '%s')rr)rOrZBUILT_IN_CHAINS�keysrrr
Z
INVALID_TABLE)rrrZtablesrrr�_check_ipv_table�s

zDirect._check_ipv_tablecCsd|j||�||f}||jkr(g|j|<||j|krH|j|j|�ntjd|||fd�dS)Nz(Chain '%s' for table '%s' with ipv '%s' zalready in list, ignoring)rQr3r,r
�warning)rrrrrArrrr!�s

zDirect.add_chaincCsn|j||�||f}||jkrX||j|krX|j|j|�t|j|�dkrj|j|=ntd|||f��dS)Nrz4Chain '%s' with table '%s' with ipv '%s' not in list)rQr3�remove�lenr$)rrrrrArrr�remove_chain�s
zDirect.remove_chaincCs,|j||�||f}||jko*||j|kS)N)rQr3)rrrrrArrr�query_chain�szDirect.query_chaincCs<|j||�||f}||jkr(|j|Std||f��dS)Nz&No chains for table '%s' with ipv '%s')rQr3r$)rrrrArrr�
get_chains�s

zDirect.get_chainscCs|jS)N)r3)rrrr�get_all_chainsszDirect.get_all_chainscCs�|j||�|||f}||jkr,t�|j|<|t|�f}||j|krV||j||<n*tjddj|�||fd||fd�dS)Nz(Rule '%s' for table '%s' and chain '%s' z',zwith ipv '%s' and priority %d zalready in list, ignoring)rQr5rr>r
rRrL)rrrrrrMrA�valuerrrr-s

zDirect.add_rulecCs�|j||�|||f}|t|�f}||jkrb||j|krb|j||=t|j|�dkr�|j|=n$tddj|�||fd||f��dS)Nrz(Rule '%s' for table '%s' and chain '%s' z',z)with ipv '%s' and priority %d not in list)rQr>r5rTr$rL)rrrrrrMrArYrrr�remove_rules

zDirect.remove_rulecCsb|j||�|||f}||jkr^x"|j|j�D]}|j||=q0Wt|j|�dkr^|j|=dS)Nr)rQr5rPrT)rrrrrArYrrr�remove_rules"s

zDirect.remove_rulescCs:|j||�|||f}|t|�f}||jko8||j|kS)N)rQr>r5)rrrrrrMrArYrrr�
query_rule+s
zDirect.query_rulecCsF|j||�|||f}||jkr*|j|Std||fd|��dS)Nz'No rules for table '%s' and chain '%s' z
with ipv '%s')rQr5r$)rrrrrArrr�	get_rules1s


zDirect.get_rulescCs|jS)N)r5)rrrr�
get_all_rules:szDirect.get_all_rulescCs^|j|�||jkrg|j|<||j|kr>|j|j|�ntjddj|�|fd�dS)NzPassthrough '%s' for ipv '%s'z',zalready in list, ignoring)rOr6r,r
rRrL)rrrMrrrr.?s


zDirect.add_passthroughcCsl|j|�||jkrN||j|krN|j|j|�t|j|�dkrh|j|=ntddj|�|fd��dS)NrzPassthrough '%s' for ipv '%s'z',znot in list)rOr6rSrTr$rL)rrrMrrr�remove_passthroughIs

zDirect.remove_passthroughcCs"|j|�||jko ||j|kS)N)rOr6)rrrMrrr�query_passthroughSs
zDirect.query_passthroughcCs.|j|�||jkr|j|Std|��dS)NzNo passthroughs for ipv '%s')rOr6r$)rrrrr�get_passthroughsWs


zDirect.get_passthroughscCs|jS)N)r6)rrrr�get_all_passthroughs^szDirect.get_all_passthroughscCs�|j�|jjd�s&ttjd|j��t|�}tj�}|j	|�t
|jd��b}tjd�}|j|�y|j
|�Wn8tjk
r�}zttjd|j���WYdd}~XnXWdQRXdS)Nz.xmlz'%s' is missing .xml suffix�rbzNot a valid file: %s)rCr8�endswithrr
ZINVALID_NAMEr�saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_TYPEZgetException)r�handler�parser�f�source�msgrrr�readcs 


zDirect.readc
CsBtjj|j�r\ytj|jd|j�Wn4tk
rZ}ztd|j|f��WYdd}~XnXtjjtj	�sxtj
tj	d�tj|jddd�}t
|�}|j�|jdi�|jd�xR|jD]H}|\}}x:|j|D],}|jd	�|jd
|||d��|jd�q�Wq�Wx�|jD]�}|\}}}xx|j|D]j\}}	t|	�dk�r@�q&|jd	�|jd
|||d|d��|jtjjt|	���|jd
�|jd��q&W�qWx||jD]r}xj|j|D]\}	t|	�dk�rȐq�|jd	�|jdd|i�|jtjjt|	���|jd�|jd��q�W�q�W|jd�|jd�|j�|j�~dS)Nz%s.oldzBackup of '%s' failed: %si�ZwtzUTF-8)�mode�encodingr�
z  r)rrrr<rz%d)rrrrrr)�os�path�existsr8�shutilZcopy2�	Exception�IOErrorrZ
ETC_FIREWALLD�mkdir�iorfr	Z
startDocumentrZignorableWhitespacer3Z
simpleElementr5rTreZsaxutils�escaperr+r6ZendDocument�close)
rrlrjrhrArrrrrMrrr�writeusZ$











zDirect.write)r4r4r4)#r/r0r1�__doc__rEZDBUS_SIGNATUREZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr;rBrHrCrNrOrQr!rUrVrWrXr-rZr[r\r]r^r.r_r`rarbrmr{�
__classcell__rr)r9rr2usH

	
		

r2)Zxml.saxrerqrxrtZfirewallrZfirewall.fw_typesrZfirewall.functionsrrrZfirewall.core.io.io_objectrrr	Zfirewall.core.loggerr
Z
firewall.corerrr
Zfirewall.errorsrrr2rrrr�<module>s
Ncore/io/__pycache__/policy.cpython-36.opt-1.pyc000064400000051212150351351720015202 0ustar003

��gϢ�@s dddgZddljZddlZddlZddlZddlmZddlm	Z	m
Z
ddlmZmZm
Z
ddlmZmZmZdd	lmZmZmZmZmZmZdd
lmZddlmZddlmZdd
lmZdd�Z dd�Z!dd�Z"dd�Z#dd�Z$Gdd�de�Z%Gdd�de�Z&ddd�Z'ddd�Z(dS) �Policy�
policy_reader�
policy_writer�N)�config)�checkIP�checkIP6)�uniqify�max_policy_name_len�portStr)�DEFAULT_POLICY_TARGET�POLICY_TARGETS�DEFAULT_POLICY_PRIORITY)�	IO_Object�IO_Object_ContentHandler�IO_Object_XMLGenerator�
check_port�check_tcpudp�check_protocol)�rich)�log)�errors)�
FirewallErrorc	Cs�|dkr�n�|dkr�n�|dkr�|jr`|jjrJtjdt|j��d|_dStj|d�|j_dS|d|jj	kr�|jj	j
|d�ntjd|d��n|dk�rN|jr�|jjr�tjdt|j��d|_dStj|d|d	�|j_dSt|d�t
|d	�t|dd
�|d	f}||jjk�r4|jjj
|�ntjd|d|d	��nN|d	k�r�|j�r�|jj�r�tjdt|j��d|_dStj|d�|j_nBt|d�|d|jjk�r�|jjj
|d�ntjd
|d��n�|dk�rh|j�r.|jj�rtjdt|j��d|_dStj|d�|j_dS|d|jjk�rT|jjj
|d�ntjd|d��n4|dk�r�|j�r�|jj�r�tjdt|j��d|_dStj|d�|j_dStjd|d��n�|dk�r2|j�r|jj�rtjdt|j��d|_dStj�|j_n|jj�r&tjd�nd|j_�nj|dk�r�d}d|k�rR|d}d}d|k�rh|d}|j�r�|jj�r�tjdt|j��d|_dStj|d|d	||�|j_dSt|d�t
|d	�|�r�t|�|�r
t|��r
t|��r
ttjd|��t|dd
�|d	t|d
�t|�f}||jjk�rL|jjj
|�n6tjd|d|d	|�rld|nd|�r|d|nd��n|dk�r@|j�r�|jj�r�tjdt|j��d|_dStj|d|d	�|j_dSt|d�t
|d	�t|dd
�|d	f}||jj k�r&|jj j
|�ntjd|d|d	��n\|dk�r�|j�sftjd�d|_dS|jj!�r�tjd t|j��dSd!}d}d"|k�r�|d"}d}d#|k�r�|d#}d$|k�r�|d$j"�dLk�r�d}tj#|||�|j_!�n�|dMk�r�|j�stjd+�d|_dS|jj$�r0tjd,�d|_dS|d'k�rHtj%�|j_$nh|d(k�rxd}	d-|k�rh|d-}	tj&|	�|j_$n8|d)k�r�tj'�|j_$n |d*k�r�|d.}
tj(|
�|j_$|jj$|_)�n�|d/k�r^|j�s�tjd0�dS|jj�r�tjd1�dSd}d2|k�r*|d2}|dNk�r*tjd;�d|_dSd<|k�r<|d<nd}tj*||�|j_|jj|_)�n>|d=k�r�|j�s~tjd>�dS|jj+�r�tjd?t|j��d|_dStj,�|j_+|jj+|_)n�|d@k�r,d}
dA}dB|k�r|dB}
|
dOk�rtjdE|dB�d|_dSdF|k�rt-|dF�}tj.|
|dG�|_np|dHk�r�|j)�sRtjdI�d|_dS|j)j/�rxtjdJt|j��d|_dS|d}tj0||j1dK��|j)_/nd!SdS)PN�short�description�servicez;Invalid rule: More than one element in rule '%s', ignoring.T�namez#Service '%s' already set, ignoring.�port�protocol�-z#Port '%s/%s' already set, ignoring.�valuez$Protocol '%s' already set, ignoring.z
icmp-blockz&icmp-block '%s' already set, ignoring.z	icmp-typez-Invalid rule: icmp-block '%s' outside of rule�
masqueradez!Masquerade already set, ignoring.zforward-port�zto-portzto-addrz#to-addr '%s' is not a valid addressz-Forward port %s/%s%s%s already set, ignoring.z >%sz @%szsource-portz*Source port '%s/%s' already set, ignoring.�destinationz)Invalid rule: Destination outside of rulez?Invalid rule: More than one destination in rule '%s', ignoring.F�address�ipset�invert�yes�true�accept�reject�drop�markz$Invalid rule: Action outside of rulez"Invalid rule: More than one action�type�setrz!Invalid rule: Log outside of rulezInvalid rule: More than one log�level�emerg�alert�crit�error�warning�notice�info�debugzInvalid rule: Invalid log level�prefix�auditz#Invalid rule: Audit outside of rulez9Invalid rule: More than one audit in rule '%s', ignoring.�ruler�family�ipv4�ipv6z&Invalid rule: Rule family "%s" invalid�priority)r:r=�limitz4Invalid rule: Limit outside of action, log and auditz9Invalid rule: More than one limit in rule '%s', ignoring.�burst)r&r')r(r)r*r+)r/r0r1r2r3r4r5r6)r;r<)2�_rule�elementrr3�str�_rule_errorr�Rich_Service�item�services�append�	Rich_Portrrr
�ports�
Rich_Protocolr�	protocols�Rich_IcmpBlock�icmp_blocks�
Rich_IcmpType�Rich_Masquerader �Rich_ForwardPortrrrr�INVALID_ADDR�
forward_ports�Rich_SourcePort�source_portsr"�lowerZRich_Destination�action�Rich_Accept�Rich_Reject�	Rich_Drop�	Rich_Mark�	_limit_okZRich_Logr8Z
Rich_Audit�int�	Rich_Ruler>Z
Rich_Limit�get)�objr�attrs�entry�to_portZto_addrr%r#r$Z_typeZ_setr.r7r:r=r�rc�/usr/lib/python3.6/policy.py�common_startElements�


















































recCs�|dkr�|js�y|jj�Wn6tk
rR}ztjd|t|j��WYdd}~XnLXt|j�|jjkr�|jj	j
|j�|jjj
t|j��ntjdt|j��d|_d|_n|dkr�d|_dS)Nr9z%s: %sz Rule '%s' already set, ignoring.Fr(r)r*r+rr8)r(r)r*r+rr8)rCr@Zcheck�	Exceptionrr3rBrE�	rules_str�rulesrGr[)r_r�ercrcrd�common_endElements&rjcCs�t|t�rdnd}|dkrT|jrT|jj�}x$|D]}||kr0ttjd|��q0W�n�|dkr�x$|D]}t|d�t|d�qbW�nb|dkr�x|D]}t	|�q�W�n@|d	kr�|jr�|jj
�}	x$|D]}
|
|	kr�ttjd
|
��q�W�n�|dk�r�x�|D]�}t|d�t|d�|d�r>|d
�r>ttjd|��|d�rTt|d�|d
r�t
|d
�r�t|d
�r�ttjd|d
��q�W�nT|dk�r�x&|D]}t|d�t|d��q�W�n|dk�r�x|D�]}tj|d�}
|j�r�|
j�r�t|
jtj��st|
jtj��r�|jj
�}	|
jj|	k�rLttjd
|
jj��nH|
j�r�|jj|
jj�}|j�r�|
j|jk�r�ttjd|
j|
jjf��nL|j�r�t|
jtj��r�|jj�}|
jj|k�r�ttjdj||j|
jj����q�WdS)NrZZonerFz '%s' not among existing servicesrIr�rKrMz"'%s' not among existing icmp typesrR��z$'%s' is missing to-port AND to-addr z#to-addr '%s' is not a valid addressrTrg�
rich_rules)�rule_strz3rich rule family '%s' conflicts with icmp type '%s'z){} '{}': '{}' not among existing services)rgrn)�
isinstancer�	fw_configZget_servicesrrZINVALID_SERVICErrrZ
get_icmptypesZINVALID_ICMPTYPE�INVALID_FORWARDrrrQrr]rArLrNrr:Zget_icmptyper"rD�format)r_rrE�
all_configZobj_typeZexisting_servicesrr�protoZexisting_icmptypesZicmptype�fwd_portr9Zobj_richZictrcrcrd�common_check_config2s�












 

rwcCs0d|ji}|j}|dk	r ||d<|jd|�dS)Nrr?r>)rr?�
simpleElement)�handlerr>�dr?rcrcrd�_handler_add_rich_limitxs

r{cCs�|jrF|jdkrF|jd�|jdi�|j|j�|jd�|jd�|jr�|jdkr�|jd�|jdi�|j|j�|jd�|jd�x6t|j�D](}|jd�|jdd|i�|jd�q�Wx@t|j	�D]2}|jd�|jd|d	|d
d��|jd�q�Wx8t|j
�D]*}|jd�|jdd
|i�|jd��qWx8t|j�D]*}|jd�|jdd|i�|jd��qLW|j�r�|jd�|jdi�|jd�x�t|j
�D]�}|jd�|d	|d
d�}|d�r�|ddk�r�|d|d<|d�r|ddk�r|d|d<|jd|�|jd��q�WxBt|j�D]4}|jd�|jd|d	|d
d��|jd��q>W�xT|jD�]H}i}|j�r�|j|d<|jd	k�r�t|j�|d<|jd�|jd|�|jd�|j�rVi}|jj�r�|jj|d<|jj�r|jj|d<|jj�r$|jj|d<|jj�r6d|d<|jd�|jd|�|jd�|j�r�i}|jj�rx|jj|d<|jj�r�|jj|d<|jj�r�d|d<|jd�|jd |�|jd�|j�rxd}	i}t|j�tjk�r�d}	|jj|d<�nbt|j�tjk�r(d}	|jj|d<|jj |d<�n0t|j�tj!k�rNd}	|jj"|d
<�n
t|j�tj#k�rfd}	n�t|j�tj$k�r�d}	|jj|d<n�t|j�tj%k�r�d!}	|jj|d<n�t|j�tj&k�rd}	|jj|d<|jj |d<|jj'dk�r�|jj'|d<|jj(dk�rX|jj(|d<nFt|j�tj)k�rBd}	|jj|d<|jj |d<nt*t+j,d"t|j���|jd�|j|	|�|jd�|j-�ri}|j-j.�r�|j-j.|d#<|j-j/�r�|j-j/|d$<|j-j0�r�|jd�|jd%|�|jd&�t1||j-j0�|jd'�|jd%�n|jd�|jd%|�|jd�|j2�r�i}|j2j0�rx|jd�|jd(i�|jd&�t1||j2j0�|jd'�|jd(�n|jd�|jd(|�|jd�|j3�r�d}
i}t|j3�tj4k�r�d)}
n|t|j3�tj5k�r�d*}
|j3j�r<|j3j|d+<nNt|j3�tj6k�rd,}
n6t|j3�tj7k�r*d-}
|j3j8|d.<nt-j9d/t|j3��|j3j0�r�|jd�|j|
|�|jd&�t1||j3j0�|jd'�|j|
�n|jd�|j|
|�|jd�|jd�|jd�|jd��q�WdS)0Nr!z  r�
rrrrrrk)rrrrz
icmp-blockr rlzto-portrmzto-addrzforward-portzsource-portr:r=r9r#�macr$�Truer%z    �sourcer"z	icmp-typez"Unknown element '%s' in obj_writerr7r.rz
      z
    r8r(r)r,r*r+r-zUnknown action '%s'):r�ignorableWhitespace�startElementZ
characters�
endElementrrrFrxrIrKrMr rRrTrhr:r=rBr�addrr}r$r%r"rAr,rrDrrHrrrJrrOrLrNrPrb�
to_addressrSrrZINVALID_OBJECTrr7r.r>r{r8rVrWrXrYrZr-r3)r_ryrrrZicmpZforwardr`r9rArVrcrcrd�
common_writer�s\




















































r�csPeZdZd7ZdZeZdgZd8d9d:d;d	dgfd
d<gfddgfd=dd>gfddgfddgfdd?gfd@ddgfddgffZdddgZ	dddgdgddgdgdgdddgddddgddgddddddgdgdgdgd�Z
ddgdd gd!dgd"d#d$d!d%gd"d$d%gd&d'gd(gd)gd*�Z�fd+d,�Zd-d.�Z
�fd/d0�Z�fd1d2�Zd3d4�Z�fd5d6�Z�ZS)Ari�i�r�versionr!rr�targetrFrIrMr FrRrnrKrTr=�
ingress_zones�egress_zones�_r�/Nrrrrr-)rr�policyrrz
icmp-blockz	icmp-typer zforward-portr9rr"rzsource-portrr8r(r)r*r+r>zingress-zonezegress-zonezto-portzto-addrr:r#r}r%r$r7r.r,r?)r�zforward-portr9rr"rr)r>cs�tt|�j�d|_d|_d|_t|_g|_g|_	g|_
g|_d|_g|_
g|_d|_g|_g|_d|_|j|_d|_g|_g|_dS)Nr!F)�superr�__init__r�rrrr�rFrIrKrMr rRrTrqrhrg�applied�priority_defaultr=Zderived_from_zoner�r�)�self)�	__class__rcrdr��s(zPolicy.__init__cCs�d|_d|_d|_t|_|jdd�=|jdd�=|jdd�=|jdd�=d|_	|j
dd�=|jdd�=d|_|j
dd�=|jdd�=d|_|j|_|jdd�=|jdd�=dS)Nr!F)r�rrrr�rFrIrKrMr rRrTrqrhrgr�r�r=r�r�)r�rcrcrd�cleanup�s$zPolicy.cleanupcs"|dkr|jSttt|�|�SdS)Nrn)rg�getattrr�r)r�r)r�rcrd�__getattr__�szPolicy.__getattr__csB|dkr,dd�|D�|_dd�|jD�|_ntt|�j||�dS)NrncSsg|]}tj|d��qS))ro)rr])�.0�srcrcrd�
<listcomp>�sz&Policy.__setattr__.<locals>.<listcomp>cSsg|]}t|��qSrc)rB)r�r�rcrcrdr��s)rhrgr�r�__setattr__)r�rr)r�rcrdr��szPolicy.__setattr__c
Cst||||�|dkr2|tkr.ttjd|���n�|dkrz||jksX||jksX||jkrvttjd||j|j|jf���n�|dk�rhddg}|j	r�||j	j
�7}x�|D]�}||kr�ttjd	|��|dkr�tddg�t|�@�s�|dk�rt|�t|g��rttjd
|��|dkr�|dk�r8d|k�r8d|dk�sT|dkr�d|kr�d|dkr�ttjd��q�W�n�|dk�r|�rd|k�r�d|dk�r�ttjd
��nxd|k�rd|dk�r�ttjd��xR|dD]F}|dk�rސq�|j	j
|�}|j	�r�d|j	j|�k�r�ttjd���q�W�n�|dk�r4�x�|D�]}tj|d�}|j�r�t|jtj��r�d|k�r|d|dk�r|ttjd
��nxd|k�r,d|dk�r�ttjd��xR|dD]F}|dk�r��q�|j	j
|�}|j	�r�d|j	j|�k�r�ttjd���q�W�q,|j�r�t|jtj��r�d|k�r,d|dk�r@|jj�r�ttjd��nt|d�r,|jj�s`ttjd��d|dk�r,x�|dD]8}|j	j
|�}|j	�rxd|j	j|�k�rxttjd���qxWnv|j�r,t|jtj��r,d|k�r,xR|dD]F}|dk�r�q�|j	j
|�}|j	�r�d|j	j|�k�r�ttjd���q�W�q,Wn�|dk�rx�|D]�}	d|k�rnd|dk�rnttjd��n�d|k�rDd|dk�r�|	d�rttjd��nt|d�rD|	d�s�ttjd��d|dk�rDxD|dD]8}|j	j
|�}|j	�r�d|j	j|�k�r�ttjd���q�W�qDWdS)Nr�z'%s' is invalid targetr=zQ%d is invalid priority. Must be in range [%d, %d]. The following are reserved: %sr�r��ANY�HOSTz'%s' not among existing zonesz>'%s' may only contain one of: many regular zones, ANY, or HOSTzF'HOST' can only appear in either ingress or egress zones, but not bothr z.'masquerade' is invalid for egress zone 'HOST'z/'masquerade' is invalid for ingress zone 'HOST'Z
interfaceszR'masquerade' cannot be used in a policy if an ingress zone has assigned interfacesrn)rozAA 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'zC'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zonezS'forward-port' cannot be used in a policy if an egress zone has assigned interfaceszR'mark' action cannot be used in a policy if an egress zone has assigned interfacesrRz1'forward-port' is invalid for ingress zone 'HOST'rm)r�r�)r�r�)r�r�)r�r�)rwrrr�INVALID_TARGET�priority_reserved�priority_max�priority_minZINVALID_PRIORITYrq�	get_zonesZINVALID_ZONEr-Zget_zoneZget_zone_config_dictrr]rArprOrPr�rrrVrZ)
r�rrErtZexisting_zones�zoneZz_objr9r_rvrcrcrd�
_check_config�s�






"
















zPolicy._check_configcs�tt|�j|�|jd�r,ttjd|��n�|jd�rHttjd|��n�|jd�dkrhttjd|��njd|kr�|d|j	d��}n|}t
|�t�kr�ttjd|t
|�t�f��|jr�||jj
�kr�ttjd��dS)Nr�z'%s' can't start with '/'z'%s' can't end with '/'rkzmore than one '/' in '%s'z&Policy of '%s' has %d chars, max is %dz,Policies can't have the same name as a zone.)r�r�
check_name�
startswithrr�INVALID_NAME�endswith�count�find�lenr	rqr�Z
NAME_CONFLICT)r�rZchecked_name)r�rcrdr�,s*

zPolicy.check_namei���)r�r!)rr!)rr!)r�r!)r!r!)r F)r!r!r!r!)r!r!)r=r)�__name__�
__module__�__qualname__r�r�r
r�r�ZIMPORT_EXPORT_STRUCTUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSr�r�r�r�r�r��
__classcell__rcrc)r�rdrZsr


^c@s$eZdZdd�Zdd�Zdd�ZdS)�policy_ContentHandlercCs"tj||�d|_d|_d|_dS)NF)rr�r@rCr[)r�rErcrcrdr�Hszpolicy_ContentHandler.__init__cCstj|||�|jrdS|jj||�t|||�r6dS|dkr�d|krR|d|j_d|krjt|d�|j_d|kr�|d}|t	kr�t
tj|��|r�||j_
�n^|dkr�|d|jjkr�|jjj|d�ntjd|d��n|dk�r |d|jjk�r|jjj|d�ntjd	|d�n�|d
k�r�|j�sFtjd�d|_dS|jj�rltjd
t|j��d|_dSd}d|k�r�|dj�dk�r�d}d}}}d|k�r�|d}d|k�r�|d}d|k�r�|d}tj||||d�|j_dStjd|�dSdS)Nr�r�r=r�zingress-zonerz(Ingress zone '%s' already set, ignoring.zegress-zonez'Egress zone '%s' already set, ignoring.rz$Invalid rule: Source outside of ruleTz:Invalid rule: More than one source in rule '%s', ignoring.Fr%r&r'r#r}r$)r%zUnknown XML element '%s')r&r')rr�rCrEZparser_check_element_attrsrer�r\r=rrrr�r�r�rGrr3r�r@rrBrUrZRich_Source)r�rr`r�r%r�r}r$rcrcrdr�Nsf








z"policy_ContentHandler.startElementcCstj||�t||�dS)N)rr�rj)r�rrcrcrdr��sz policy_ContentHandler.endElementN)r�r�r�r�r�r�rcrcrcrdr�Gs@r�Fc
Cst�}|jd�s ttjd|��|dd	�|_|s>|j|j�||_||_|j	t
j�rZdnd|_|j|_
t|�}tj�}|j|�d||f}t|d��b}tjd�}|j|�y|j|�Wn8tjk
r�}	zttjd|	j���WYdd}	~	XnXWdQRX~~|S)
Nz.xmlz'%s' is missing .xml suffix�FTz%s/%s�rbznot a valid policy file: %s���)rr�rrr�rr��filename�pathr�r�
ETC_FIREWALLDZbuiltin�defaultr��saxZmake_parserZsetContentHandler�openZInputSourceZ
setByteStream�parseZSAXParseExceptionZINVALID_POLICYZgetException)
r�r�Z
no_check_namer�ry�parserr�fr�msgrcrcrdr�s6




(c
Cs�|r|n|j}|jr$d||jf}nd||jf}tjj|�r�ytj|d|�Wn0tk
r�}ztj	d||�WYdd}~XnXtjj
|�}|jtj
�r�tjj|�r�tjjtj
�s�tjtj
d�tj|d�tj|ddd�}t|�}|j�i}|j�r|jd	k�r|j|d
<|j|jk�r0t|j�|d<|j|d<|jd
|�|jd�t||�x8t|j�D]*}	|jd�|jdd|	i�|jd��qfWx8t|j�D]*}	|jd�|jdd|	i�|jd��q�W|jd
�|jd�|j �|j!�~dS)Nz%s/%sz	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %si�ZwtzUTF-8)�mode�encodingr!r�r=r�r�r|z  zingress-zonerzegress-zone)"r�r�r�os�exists�shutilZcopy2rfrr2�dirnamer�rr��mkdir�ior�rZ
startDocumentr�r=r�rBr�r�r�r�rr�rxr�r�ZendDocument�close)
r�r��_pathrr��dirpathr�ryr`r�rcrcrdr�sN 







)F)N))�__all__Zxml.saxr�r�r�r�ZfirewallrZfirewall.functionsrrrr	r
Zfirewall.core.baserrr
Zfirewall.core.io.io_objectrrrrrrZ
firewall.corerZfirewall.core.loggerrrZfirewall.errorsrrerjrwr{r�rr�rrrcrcrcrd�<module>s4

 F[nL
core/io/ipset.py000064400000051205150351351720007606 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2015-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""ipset io XML handler, reader, writer"""

__all__ = [ "IPSet", "ipset_reader", "ipset_writer" ]

import xml.sax as sax
import os
import io
import shutil

from firewall import config
from firewall.functions import checkIP, checkIP6, checkIPnMask, \
    checkIP6nMask, u2b_if_py2, check_mac, check_port, checkInterface, \
    checkProtocol
from firewall.core.io.io_object import PY2, IO_Object, \
    IO_Object_ContentHandler, IO_Object_XMLGenerator
from firewall.core.ipset import IPSET_TYPES, IPSET_CREATE_OPTIONS
from firewall.core.icmp import check_icmp_name, check_icmp_type, \
    check_icmpv6_name, check_icmpv6_type
from firewall.core.logger import log
from firewall import errors
from firewall.errors import FirewallError

class IPSet(IO_Object):
    IMPORT_EXPORT_STRUCTURE = (
        ( "version",  "" ),              # s
        ( "short", "" ),                 # s
        ( "description", "" ),           # s
        ( "type", "" ),                  # s
        ( "options", { "": "", }, ),     # a{ss}
        ( "entries", [ "" ], ),          # as
    )
    DBUS_SIGNATURE = '(ssssa{ss}as)'
    ADDITIONAL_ALNUM_CHARS = [ "_", "-", ":", "." ]
    PARSER_REQUIRED_ELEMENT_ATTRS = {
        "short": None,
        "description": None,
        "ipset": [ "type" ],
        "option": [ "name" ],
        "entry": None,
    }
    PARSER_OPTIONAL_ELEMENT_ATTRS = {
        "ipset": [ "version" ],
        "option": [ "value" ],
    }

    def __init__(self):
        super(IPSet, self).__init__()
        self.version = ""
        self.short = ""
        self.description = ""
        self.type = ""
        self.entries = [ ]
        self.options = { }
        self.applied = False

    def cleanup(self):
        self.version = ""
        self.short = ""
        self.description = ""
        self.type = ""
        del self.entries[:]
        self.options.clear()
        self.applied = False

    def encode_strings(self):
        """ HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support."""
        self.version = u2b_if_py2(self.version)
        self.short = u2b_if_py2(self.short)
        self.description = u2b_if_py2(self.description)
        self.type = u2b_if_py2(self.type)
        self.options = { u2b_if_py2(k):u2b_if_py2(v)
                         for k, v in self.options.items() }
        self.entries = [ u2b_if_py2(e) for e in self.entries ]

    @staticmethod
    def check_entry(entry, options, ipset_type):
        family = "ipv4"
        if "family" in options:
            if options["family"] == "inet6":
                family = "ipv6"

        if not ipset_type.startswith("hash:"):
            raise FirewallError(errors.INVALID_IPSET,
                                "ipset type '%s' not usable" % ipset_type)
        flags = ipset_type[5:].split(",")
        items = entry.split(",")

        if len(flags) != len(items) or len(flags) < 1:
            raise FirewallError(
                errors.INVALID_ENTRY,
                "entry '%s' does not match ipset type '%s'" % \
                (entry, ipset_type))

        for i in range(len(flags)):
            flag = flags[i]
            item = items[i]

            if flag == "ip":
                if "-" in item and family == "ipv4":
                    # IP ranges only with plain IPs, no masks
                    if i > 1:
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid address '%s' in '%s'[%d]" % \
                            (item, entry, i))
                    splits = item.split("-")
                    if len(splits) != 2:
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid address range '%s' in '%s' for %s (%s)" % \
                            (item, entry, ipset_type, family))
                    for _split in splits:
                        if (family == "ipv4" and not checkIP(_split)) or \
                           (family == "ipv6" and not checkIP6(_split)):
                            raise FirewallError(
                                errors.INVALID_ENTRY,
                                "invalid address '%s' in '%s' for %s (%s)" % \
                                (_split, entry, ipset_type, family))
                else:
                    # IPs with mask only allowed in the first
                    # position of the type
                    if family == "ipv4":
                        if item == "0.0.0.0":
                            raise FirewallError(
                                errors.INVALID_ENTRY,
                                "invalid address '%s' in '%s' for %s (%s)" % \
                                (item, entry, ipset_type, family))
                        if i == 0:
                            ip_check = checkIPnMask
                        else:
                            ip_check = checkIP
                    else:
                        ip_check = checkIP6
                    if not ip_check(item):
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid address '%s' in '%s' for %s (%s)" % \
                            (item, entry, ipset_type, family))
            elif flag == "net":
                if "-" in item:
                    # IP ranges only with plain IPs, no masks
                    splits = item.split("-")
                    if len(splits) != 2:
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid address range '%s' in '%s' for %s (%s)" % \
                            (item, entry, ipset_type, family))
                    # First part can only be a plain IP
                    if (family == "ipv4" and not checkIP(splits[0])) or \
                       (family == "ipv6" and not checkIP6(splits[0])):
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid address '%s' in '%s' for %s (%s)" % \
                            (splits[0], entry, ipset_type, family))
                    # Second part can also have a mask
                    if (family == "ipv4" and not checkIPnMask(splits[1])) or \
                       (family == "ipv6" and not checkIP6nMask(splits[1])):
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid address '%s' in '%s' for %s (%s)" % \
                            (splits[1], entry, ipset_type, family))
                else:
                    # IPs with mask allowed in all positions, but no /0
                    if item.endswith("/0"):
                        if not (family == "ipv6" and i == 0 and
                                ipset_type == "hash:net,iface"):
                            raise FirewallError(
                                errors.INVALID_ENTRY,
                                "invalid address '%s' in '%s' for %s (%s)" % \
                                (item, entry, ipset_type, family))
                    if (family == "ipv4" and not checkIPnMask(item)) or \
                       (family == "ipv6" and not checkIP6nMask(item)):
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid address '%s' in '%s' for %s (%s)" % \
                            (item, entry, ipset_type, family))
            elif flag == "mac":
                # ipset does not allow to add 00:00:00:00:00:00
                if not check_mac(item) or item == "00:00:00:00:00:00":
                    raise FirewallError(
                        errors.INVALID_ENTRY,
                        "invalid mac address '%s' in '%s'" % (item, entry))
            elif flag == "port":
                if ":" in item:
                    splits = item.split(":")
                    if len(splits) != 2:
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid port '%s'" % (item))
                    if splits[0] == "icmp":
                        if family != "ipv4":
                            raise FirewallError(
                                errors.INVALID_ENTRY,
                                "invalid protocol for family '%s' in '%s'" % \
                                (family, entry))
                        if not check_icmp_name(splits[1]) and not \
                           check_icmp_type(splits[1]):
                            raise FirewallError(
                                errors.INVALID_ENTRY,
                                "invalid icmp type '%s' in '%s'" % \
                                (splits[1], entry))
                    elif splits[0] in [ "icmpv6", "ipv6-icmp" ]:
                        if family != "ipv6":
                            raise FirewallError(
                                errors.INVALID_ENTRY,
                                "invalid protocol for family '%s' in '%s'" % \
                                (family, entry))
                        if not check_icmpv6_name(splits[1]) and not \
                           check_icmpv6_type(splits[1]):
                            raise FirewallError(
                                errors.INVALID_ENTRY,
                                "invalid icmpv6 type '%s' in '%s'" % \
                                (splits[1], entry))
                    elif splits[0] not in [ "tcp", "sctp", "udp", "udplite" ] \
                       and not checkProtocol(splits[0]):
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid protocol '%s' in '%s'" % (splits[0],
                                                               entry))
                    elif not check_port(splits[1]):
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid port '%s'in '%s'" % (splits[1], entry))
                else:
                    if not check_port(item):
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid port '%s' in '%s'" % (item, entry))
            elif flag == "mark":
                if item.startswith("0x"):
                    try:
                        int_val = int(item, 16)
                    except ValueError:
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid mark '%s' in '%s'" % (item, entry))
                else:
                    try:
                        int_val = int(item)
                    except ValueError:
                        raise FirewallError(
                            errors.INVALID_ENTRY,
                            "invalid mark '%s' in '%s'" % (item, entry))
                if int_val < 0 or int_val > 4294967295:
                    raise FirewallError(
                        errors.INVALID_ENTRY,
                        "invalid mark '%s' in '%s'" % (item, entry))
            elif flag == "iface":
                if not checkInterface(item) or len(item) > 15:
                    raise FirewallError(
                        errors.INVALID_ENTRY,
                        "invalid interface '%s' in '%s'" % (item, entry))
            else:
                raise FirewallError(errors.INVALID_IPSET,
                                    "ipset type '%s' not usable" % ipset_type)

    def _check_config(self, config, item, all_config):
        if item == "type":
            if config not in IPSET_TYPES:
                raise FirewallError(errors.INVALID_TYPE,
                                    "'%s' is not valid ipset type" % config)
        if item == "options":
            for key in config.keys():
                if key not in IPSET_CREATE_OPTIONS:
                    raise FirewallError(errors.INVALID_IPSET,
                                        "ipset invalid option '%s'" % key)
                if key in [ "timeout", "hashsize", "maxelem" ]:
                    try:
                        int_value = int(config[key])
                    except ValueError:
                        raise FirewallError(
                            errors.INVALID_VALUE,
                            "Option '%s': Value '%s' is not an integer" % \
                            (key, config[key]))
                    if int_value < 0:
                        raise FirewallError(
                            errors.INVALID_VALUE,
                            "Option '%s': Value '%s' is negative" % \
                            (key, config[key]))
                elif key == "family" and \
                     config[key] not in [ "inet", "inet6" ]:
                    raise FirewallError(errors.INVALID_FAMILY, config[key])

    def import_config(self, config):
        if "timeout" in config[4] and config[4]["timeout"] != "0":
            if len(config[5]) != 0:
                raise FirewallError(errors.IPSET_WITH_TIMEOUT)
        for entry in config[5]:
            IPSet.check_entry(entry, config[4], config[3])
        super(IPSet, self).import_config(config)

# PARSER

class ipset_ContentHandler(IO_Object_ContentHandler):
    def startElement(self, name, attrs):
        IO_Object_ContentHandler.startElement(self, name, attrs)
        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"]
        elif name == "short":
            pass
        elif name == "description":
            pass
        elif name == "option":
            value = ""
            if "value" in attrs:
                value = attrs["value"]

            if attrs["name"] not in \
               [ "family", "timeout", "hashsize", "maxelem" ]:
                raise FirewallError(
                    errors.INVALID_OPTION,
                    "Unknown option '%s'" % attrs["name"])
            if self.item.type == "hash:mac" and attrs["name"] in [ "family" ]:
                raise FirewallError(
                    errors.INVALID_OPTION,
                    "Unsupported option '%s' for type '%s'" % \
                    (attrs["name"], self.item.type))
            if attrs["name"] in [ "family", "timeout", "hashsize", "maxelem" ] \
               and not value:
                raise FirewallError(
                    errors.INVALID_OPTION,
                    "Missing mandatory value of option '%s'" % attrs["name"])
            if attrs["name"] in [ "timeout", "hashsize", "maxelem" ]:
                try:
                    int_value = int(value)
                except ValueError:
                    raise FirewallError(
                        errors.INVALID_VALUE,
                        "Option '%s': Value '%s' is not an integer" % \
                        (attrs["name"], value))
                if int_value < 0:
                    raise FirewallError(
                        errors.INVALID_VALUE,
                        "Option '%s': Value '%s' is negative" % \
                        (attrs["name"], value))
            if attrs["name"] == "family" and value not in [ "inet", "inet6" ]:
                raise FirewallError(errors.INVALID_FAMILY, value)
            if attrs["name"] not in self.item.options:
                self.item.options[attrs["name"]] = value
            else:
                log.warning("Option %s already set, ignoring.", attrs["name"])
        # nothing to do for entry and entries here

    def endElement(self, name):
        IO_Object_ContentHandler.endElement(self, name)
        if name == "entry":
            self.item.entries.append(self._element)

def ipset_reader(filename, path):
    ipset = IPSet()
    if not filename.endswith(".xml"):
        raise FirewallError(errors.INVALID_NAME,
                            "'%s' is missing .xml suffix" % filename)
    ipset.name = filename[:-4]
    ipset.check_name(ipset.name)
    ipset.filename = filename
    ipset.path = path
    ipset.builtin = False if path.startswith(config.ETC_FIREWALLD) else True
    ipset.default = ipset.builtin
    handler = ipset_ContentHandler(ipset)
    parser = sax.make_parser()
    parser.setContentHandler(handler)
    name = "%s/%s" % (path, filename)
    with open(name, "rb") as f:
        source = sax.InputSource(None)
        source.setByteStream(f)
        try:
            parser.parse(source)
        except sax.SAXParseException as msg:
            raise FirewallError(errors.INVALID_IPSET,
                                "not a valid ipset file: %s" % \
                                msg.getException())
    del handler
    del parser
    if "timeout" in ipset.options and ipset.options["timeout"] != "0" and \
       len(ipset.entries) > 0:
        # no entries visible for ipsets with timeout
        log.warning("ipset '%s': timeout option is set, entries are ignored",
                    ipset.name)
        del ipset.entries[:]
    i = 0
    entries_set = set()
    while i < len(ipset.entries):
        if ipset.entries[i] in entries_set:
            log.warning("Entry %s already set, ignoring.", ipset.entries[i])
            ipset.entries.pop(i)
        else:
            try:
                ipset.check_entry(ipset.entries[i], ipset.options, ipset.type)
            except FirewallError as e:
                log.warning("%s, ignoring.", e)
                ipset.entries.pop(i)
            else:
                entries_set.add(ipset.entries[i])
                i += 1
    del entries_set
    if PY2:
        ipset.encode_strings()

    return ipset

def ipset_writer(ipset, path=None):
    _path = path if path else ipset.path

    if ipset.filename:
        name = "%s/%s" % (_path, ipset.filename)
    else:
        name = "%s/%s.xml" % (_path, ipset.name)

    if os.path.exists(name):
        try:
            shutil.copy2(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)

    dirpath = os.path.dirname(name)
    if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath):
        if not os.path.exists(config.ETC_FIREWALLD):
            os.mkdir(config.ETC_FIREWALLD, 0o750)
        os.mkdir(dirpath, 0o750)

    f = io.open(name, mode='wt', encoding='UTF-8')
    handler = IO_Object_XMLGenerator(f)
    handler.startDocument()

    # start ipset element
    attrs = { "type": ipset.type }
    if ipset.version and ipset.version != "":
        attrs["version"] = ipset.version
    handler.startElement("ipset", attrs)
    handler.ignorableWhitespace("\n")

    # short
    if ipset.short and ipset.short != "":
        handler.ignorableWhitespace("  ")
        handler.startElement("short", { })
        handler.characters(ipset.short)
        handler.endElement("short")
        handler.ignorableWhitespace("\n")

    # description
    if ipset.description and ipset.description != "":
        handler.ignorableWhitespace("  ")
        handler.startElement("description", { })
        handler.characters(ipset.description)
        handler.endElement("description")
        handler.ignorableWhitespace("\n")

    # options
    for key,value in ipset.options.items():
        handler.ignorableWhitespace("  ")
        if value != "":
            handler.simpleElement("option", { "name": key, "value": value })
        else:
            handler.simpleElement("option", { "name": key })
        handler.ignorableWhitespace("\n")

    # entries
    for entry in ipset.entries:
        handler.ignorableWhitespace("  ")
        handler.startElement("entry", { })
        handler.characters(entry)
        handler.endElement("entry")
        handler.ignorableWhitespace("\n")

    # end ipset element
    handler.endElement('ipset')
    handler.ignorableWhitespace("\n")
    handler.endDocument()
    f.close()
    del handler
core/io/policy.py000064400000121317150351351720007763 0ustar00# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: GPL-2.0-or-later

__all__ = [ "Policy", "policy_reader", "policy_writer" ]

import xml.sax as sax
import os
import io
import shutil

from firewall import config
from firewall.functions import checkIP, checkIP6
from firewall.functions import uniqify, max_policy_name_len, portStr
from firewall.core.base import DEFAULT_POLICY_TARGET, POLICY_TARGETS, DEFAULT_POLICY_PRIORITY
from firewall.core.io.io_object import IO_Object, \
    IO_Object_ContentHandler, IO_Object_XMLGenerator, check_port, \
    check_tcpudp, check_protocol
from firewall.core import rich
from firewall.core.logger import log
from firewall import errors
from firewall.errors import FirewallError


def common_startElement(obj, name, attrs):
    if name == "short":
        pass
    elif name == "description":
        pass

    elif name == "service":
        if obj._rule:
            if obj._rule.element:
                log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
                            str(obj._rule))
                obj._rule_error = True
                return True
            obj._rule.element = rich.Rich_Service(attrs["name"])
            return True
        if attrs["name"] not in obj.item.services:
            obj.item.services.append(attrs["name"])
        else:
            log.warning("Service '%s' already set, ignoring.",
                        attrs["name"])

    elif name == "port":
        if obj._rule:
            if obj._rule.element:
                log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
                            str(obj._rule))
                obj._rule_error = True
                return True
            obj._rule.element = rich.Rich_Port(attrs["port"],
                                                attrs["protocol"])
            return True
        check_port(attrs["port"])
        check_tcpudp(attrs["protocol"])
        entry = (portStr(attrs["port"], "-"), attrs["protocol"])
        if entry not in obj.item.ports:
            obj.item.ports.append(entry)
        else:
            log.warning("Port '%s/%s' already set, ignoring.",
                        attrs["port"], attrs["protocol"])

    elif name == "protocol":
        if obj._rule:
            if obj._rule.element:
                log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
                            str(obj._rule))
                obj._rule_error = True
                return True
            obj._rule.element = rich.Rich_Protocol(attrs["value"])
        else:
            check_protocol(attrs["value"])
            if attrs["value"] not in obj.item.protocols:
                obj.item.protocols.append(attrs["value"])
            else:
                log.warning("Protocol '%s' already set, ignoring.",
                            attrs["value"])
    elif name == "icmp-block":
        if obj._rule:
            if obj._rule.element:
                log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
                            str(obj._rule))
                obj._rule_error = True
                return True
            obj._rule.element = rich.Rich_IcmpBlock(attrs["name"])
            return True
        if attrs["name"] not in obj.item.icmp_blocks:
            obj.item.icmp_blocks.append(attrs["name"])
        else:
            log.warning("icmp-block '%s' already set, ignoring.",
                        attrs["name"])

    elif name == "icmp-type":
        if obj._rule:
            if obj._rule.element:
                log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
                            str(obj._rule))
                obj._rule_error = True
                return True
            obj._rule.element = rich.Rich_IcmpType(attrs["name"])
            return True
        else:
            log.warning("Invalid rule: icmp-block '%s' outside of rule",
                        attrs["name"])

    elif name == "masquerade":
        if obj._rule:
            if obj._rule.element:
                log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
                            str(obj._rule))
                obj._rule_error = True
                return True
            obj._rule.element = rich.Rich_Masquerade()
        else:
            if obj.item.masquerade:
                log.warning("Masquerade already set, ignoring.")
            else:
                obj.item.masquerade = True

    elif name == "forward-port":
        to_port = ""
        if "to-port" in attrs:
            to_port = attrs["to-port"]
        to_addr = ""
        if "to-addr" in attrs:
            to_addr = attrs["to-addr"]

        if obj._rule:
            if obj._rule.element:
                log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
                            str(obj._rule))
                obj._rule_error = True
                return True
            obj._rule.element = rich.Rich_ForwardPort(attrs["port"],
                                                       attrs["protocol"],
                                                       to_port, to_addr)
            return True

        check_port(attrs["port"])
        check_tcpudp(attrs["protocol"])
        if to_port:
            check_port(to_port)
        if to_addr:
            if not checkIP(to_addr) and not checkIP6(to_addr):
                raise FirewallError(errors.INVALID_ADDR,
                                    "to-addr '%s' is not a valid address" \
                                    % to_addr)
        entry = (portStr(attrs["port"], "-"), attrs["protocol"],
                 portStr(to_port, "-"), str(to_addr))
        if entry not in obj.item.forward_ports:
            obj.item.forward_ports.append(entry)
        else:
            log.warning("Forward port %s/%s%s%s already set, ignoring.",
                        attrs["port"], attrs["protocol"],
                        " >%s" % to_port if to_port else "",
                        " @%s" % to_addr if to_addr else "")

    elif name == "source-port":
        if obj._rule:
            if obj._rule.element:
                log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
                            str(obj._rule))
                obj._rule_error = True
                return True
            obj._rule.element = rich.Rich_SourcePort(attrs["port"],
                                                      attrs["protocol"])
            return True
        check_port(attrs["port"])
        check_tcpudp(attrs["protocol"])
        entry = (portStr(attrs["port"], "-"), attrs["protocol"])
        if entry not in obj.item.source_ports:
            obj.item.source_ports.append(entry)
        else:
            log.warning("Source port '%s/%s' already set, ignoring.",
                        attrs["port"], attrs["protocol"])

    elif name == "destination":
        if not obj._rule:
            log.warning('Invalid rule: Destination outside of rule')
            obj._rule_error = True
            return True
        if obj._rule.destination:
            log.warning("Invalid rule: More than one destination in rule '%s', ignoring.",
                        str(obj._rule))
            return True
        invert = False
        address = None
        if "address" in attrs:
            address = attrs["address"]
        ipset = None
        if "ipset" in attrs:
            ipset = attrs["ipset"]
        if "invert" in attrs and \
                attrs["invert"].lower() in [ "yes", "true" ]:
            invert = True
        obj._rule.destination = rich.Rich_Destination(address,
                                                      ipset,
                                                      invert)

    elif name in [ "accept", "reject", "drop", "mark" ]:
        if not obj._rule:
            log.warning('Invalid rule: Action outside of rule')
            obj._rule_error = True
            return True
        if obj._rule.action:
            log.warning('Invalid rule: More than one action')
            obj._rule_error = True
            return True
        if name == "accept":
            obj._rule.action = rich.Rich_Accept()
        elif name == "reject":
            _type = None
            if "type" in attrs:
                _type = attrs["type"]
            obj._rule.action = rich.Rich_Reject(_type)
        elif name == "drop":
            obj._rule.action = rich.Rich_Drop()
        elif name == "mark":
            _set = attrs["set"]
            obj._rule.action = rich.Rich_Mark(_set)
        obj._limit_ok = obj._rule.action

    elif name == "log":
        if not obj._rule:
            log.warning('Invalid rule: Log outside of rule')
            return True
        if obj._rule.log:
            log.warning('Invalid rule: More than one log')
            return True
        level = None
        if "level" in attrs:
            level = attrs["level"]
            if level not in [ "emerg", "alert", "crit", "error",
                              "warning", "notice", "info", "debug" ]:
                log.warning('Invalid rule: Invalid log level')
                obj._rule_error = True
                return True
        prefix = attrs["prefix"] if "prefix" in attrs else None
        obj._rule.log = rich.Rich_Log(prefix, level)
        obj._limit_ok = obj._rule.log

    elif name == "audit":
        if not obj._rule:
            log.warning('Invalid rule: Audit outside of rule')
            return True
        if obj._rule.audit:
            log.warning("Invalid rule: More than one audit in rule '%s', ignoring.",
                        str(obj._rule))
            obj._rule_error = True
            return True
        obj._rule.audit = rich.Rich_Audit()
        obj._limit_ok = obj._rule.audit

    elif name == "rule":
        family = None
        priority = 0
        if "family" in attrs:
            family = attrs["family"]
            if family not in [ "ipv4", "ipv6" ]:
                log.warning('Invalid rule: Rule family "%s" invalid',
                            attrs["family"])
                obj._rule_error = True
                return True
        if "priority" in attrs:
            priority = int(attrs["priority"])
        obj._rule = rich.Rich_Rule(family=family, priority=priority)

    elif name == "limit":
        if not obj._limit_ok:
            log.warning('Invalid rule: Limit outside of action, log and audit')
            obj._rule_error = True
            return True
        if obj._limit_ok.limit:
            log.warning("Invalid rule: More than one limit in rule '%s', ignoring.",
                        str(obj._rule))
            obj._rule_error = True
            return True
        value = attrs["value"]
        obj._limit_ok.limit = rich.Rich_Limit(value, attrs.get("burst"))
    else:
        return False

    return True

def common_endElement(obj, name):
    if name == "rule":
        if not obj._rule_error:
            try:
                obj._rule.check()
            except Exception as e:
                log.warning("%s: %s", e, str(obj._rule))
            else:
                if str(obj._rule) not in obj.item.rules_str:
                    obj.item.rules.append(obj._rule)
                    obj.item.rules_str.append(str(obj._rule))
                else:
                    log.warning("Rule '%s' already set, ignoring.",
                                str(obj._rule))
        obj._rule = None
        obj._rule_error = False
    elif name in [ "accept", "reject", "drop", "mark", "log", "audit" ]:
        obj._limit_ok = None

def common_check_config(obj, config, item, all_config):
    obj_type = "Policy" if isinstance(obj, Policy) else "Zone"

    if item == "services" and obj.fw_config:
        existing_services = obj.fw_config.get_services()
        for service in config:
            if service not in existing_services:
                raise FirewallError(errors.INVALID_SERVICE,
                                    "'%s' not among existing services" % \
                                    service)
    elif item == "ports":
        for port in config:
            check_port(port[0])
            check_tcpudp(port[1])
    elif item == "protocols":
        for proto in config:
            check_protocol(proto)
    elif item == "icmp_blocks" and obj.fw_config:
        existing_icmptypes = obj.fw_config.get_icmptypes()
        for icmptype in config:
            if icmptype not in existing_icmptypes:
                raise FirewallError(errors.INVALID_ICMPTYPE,
                                    "'%s' not among existing icmp types" % \
                                    icmptype)
    elif item == "forward_ports":
        for fwd_port in config:
            check_port(fwd_port[0])
            check_tcpudp(fwd_port[1])
            if not fwd_port[2] and not fwd_port[3]:
                raise FirewallError(
                    errors.INVALID_FORWARD,
                    "'%s' is missing to-port AND to-addr " % fwd_port)
            if fwd_port[2]:
                check_port(fwd_port[2])
            if fwd_port[3]:
                if not checkIP(fwd_port[3]) and not checkIP6(fwd_port[3]):
                    raise FirewallError(
                        errors.INVALID_ADDR,
                        "to-addr '%s' is not a valid address" % fwd_port[3])
    elif item == "source_ports":
        for port in config:
            check_port(port[0])
            check_tcpudp(port[1])
    elif item in ["rules_str", "rich_rules"]:
        for rule in config:
            obj_rich = rich.Rich_Rule(rule_str=rule)
            if obj.fw_config and obj_rich.element and (isinstance(obj_rich.element, rich.Rich_IcmpBlock) or
                                                       isinstance(obj_rich.element, rich.Rich_IcmpType)):
                existing_icmptypes = obj.fw_config.get_icmptypes()
                if obj_rich.element.name not in existing_icmptypes:
                    raise FirewallError(errors.INVALID_ICMPTYPE,
                                        "'%s' not among existing icmp types" % \
                                        obj_rich.element.name)
                elif obj_rich.family:
                    ict = obj.fw_config.get_icmptype(obj_rich.element.name)
                    if ict.destination and obj_rich.family not in ict.destination:
                        raise FirewallError(errors.INVALID_ICMPTYPE,
                                            "rich rule family '%s' conflicts with icmp type '%s'" % \
                                            (obj_rich.family, obj_rich.element.name))
            elif obj.fw_config and isinstance(obj_rich.element, rich.Rich_Service):
                existing_services = obj.fw_config.get_services()
                if obj_rich.element.name not in existing_services:
                    raise FirewallError(
                        errors.INVALID_SERVICE,
                        "{} '{}': '{}' not among existing services".format(
                            obj_type, obj.name, obj_rich.element.name
                        ),
                    )


def _handler_add_rich_limit(handler, limit):
    d = {"value": limit.value}
    burst = limit.burst
    if burst is not None:
        d["burst"] = burst
    handler.simpleElement("limit", d)


def common_writer(obj, handler):
    # short
    if obj.short and obj.short != "":
        handler.ignorableWhitespace("  ")
        handler.startElement("short", { })
        handler.characters(obj.short)
        handler.endElement("short")
        handler.ignorableWhitespace("\n")

    # description
    if obj.description and obj.description != "":
        handler.ignorableWhitespace("  ")
        handler.startElement("description", { })
        handler.characters(obj.description)
        handler.endElement("description")
        handler.ignorableWhitespace("\n")

    # services
    for service in uniqify(obj.services):
        handler.ignorableWhitespace("  ")
        handler.simpleElement("service", { "name": service })
        handler.ignorableWhitespace("\n")

    # ports
    for port in uniqify(obj.ports):
        handler.ignorableWhitespace("  ")
        handler.simpleElement("port", { "port": port[0], "protocol": port[1] })
        handler.ignorableWhitespace("\n")

    # protocols
    for protocol in uniqify(obj.protocols):
        handler.ignorableWhitespace("  ")
        handler.simpleElement("protocol", { "value": protocol })
        handler.ignorableWhitespace("\n")

    # icmp-blocks
    for icmp in uniqify(obj.icmp_blocks):
        handler.ignorableWhitespace("  ")
        handler.simpleElement("icmp-block", { "name": icmp })
        handler.ignorableWhitespace("\n")

    # masquerade
    if obj.masquerade:
        handler.ignorableWhitespace("  ")
        handler.simpleElement("masquerade", { })
        handler.ignorableWhitespace("\n")

    # forward-ports
    for forward in uniqify(obj.forward_ports):
        handler.ignorableWhitespace("  ")
        attrs = { "port": forward[0], "protocol": forward[1] }
        if forward[2] and forward[2] != "" :
            attrs["to-port"] = forward[2]
        if forward[3] and forward[3] != "" :
            attrs["to-addr"] = forward[3]
        handler.simpleElement("forward-port", attrs)
        handler.ignorableWhitespace("\n")

    # source-ports
    for port in uniqify(obj.source_ports):
        handler.ignorableWhitespace("  ")
        handler.simpleElement("source-port", { "port": port[0],
                                               "protocol": port[1] })
        handler.ignorableWhitespace("\n")

    # rules
    for rule in obj.rules:
        attrs = { }
        if rule.family:
            attrs["family"] = rule.family
        if rule.priority != 0:
            attrs["priority"] = str(rule.priority)
        handler.ignorableWhitespace("  ")
        handler.startElement("rule", attrs)
        handler.ignorableWhitespace("\n")

        # source
        if rule.source:
            attrs = { }
            if rule.source.addr:
                attrs["address"] = rule.source.addr
            if rule.source.mac:
                attrs["mac"] = rule.source.mac
            if rule.source.ipset:
                attrs["ipset"] = rule.source.ipset
            if rule.source.invert:
                attrs["invert"] = "True"
            handler.ignorableWhitespace("    ")
            handler.simpleElement("source", attrs)
            handler.ignorableWhitespace("\n")

        # destination
        if rule.destination:
            attrs = { }
            if rule.destination.addr:
                attrs["address"] = rule.destination.addr
            if rule.destination.ipset:
                attrs["ipset"] = rule.destination.ipset
            if rule.destination.invert:
                attrs["invert"] = "True"
            handler.ignorableWhitespace("    ")
            handler.simpleElement("destination", attrs)
            handler.ignorableWhitespace("\n")

        # element
        if rule.element:
            element = ""
            attrs = { }

            if type(rule.element) == rich.Rich_Service:
                element = "service"
                attrs["name"] = rule.element.name
            elif type(rule.element) == rich.Rich_Port:
                element = "port"
                attrs["port"] = rule.element.port
                attrs["protocol"] = rule.element.protocol
            elif type(rule.element) == rich.Rich_Protocol:
                element = "protocol"
                attrs["value"] = rule.element.value
            elif type(rule.element) == rich.Rich_Masquerade:
                element = "masquerade"
            elif type(rule.element) == rich.Rich_IcmpBlock:
                element = "icmp-block"
                attrs["name"] = rule.element.name
            elif type(rule.element) == rich.Rich_IcmpType:
                element = "icmp-type"
                attrs["name"] = rule.element.name
            elif type(rule.element) == rich.Rich_ForwardPort:
                element = "forward-port"
                attrs["port"] = rule.element.port
                attrs["protocol"] = rule.element.protocol
                if rule.element.to_port != "":
                    attrs["to-port"] = rule.element.to_port
                if rule.element.to_address != "":
                    attrs["to-addr"] = rule.element.to_address
            elif type(rule.element) == rich.Rich_SourcePort:
                element = "source-port"
                attrs["port"] = rule.element.port
                attrs["protocol"] = rule.element.protocol
            else:
                raise FirewallError(
                    errors.INVALID_OBJECT,
                    "Unknown element '%s' in obj_writer" % type(rule.element))

            handler.ignorableWhitespace("    ")
            handler.simpleElement(element, attrs)
            handler.ignorableWhitespace("\n")

        # rule.element

        # log
        if rule.log:
            attrs = { }
            if rule.log.prefix:
                attrs["prefix"] = rule.log.prefix
            if rule.log.level:
                attrs["level"] = rule.log.level
            if rule.log.limit:
                handler.ignorableWhitespace("    ")
                handler.startElement("log", attrs)
                handler.ignorableWhitespace("\n      ")
                _handler_add_rich_limit(handler, rule.log.limit)
                handler.ignorableWhitespace("\n    ")
                handler.endElement("log")
            else:
                handler.ignorableWhitespace("    ")
                handler.simpleElement("log", attrs)
            handler.ignorableWhitespace("\n")

        # audit
        if rule.audit:
            attrs = {}
            if rule.audit.limit:
                handler.ignorableWhitespace("    ")
                handler.startElement("audit", { })
                handler.ignorableWhitespace("\n      ")
                _handler_add_rich_limit(handler, rule.audit.limit)
                handler.ignorableWhitespace("\n    ")
                handler.endElement("audit")
            else:
                handler.ignorableWhitespace("    ")
                handler.simpleElement("audit", attrs)
            handler.ignorableWhitespace("\n")

        # action
        if rule.action:
            action = ""
            attrs = { }
            if type(rule.action) == rich.Rich_Accept:
                action = "accept"
            elif type(rule.action) == rich.Rich_Reject:
                action = "reject"
                if rule.action.type:
                    attrs["type"] = rule.action.type
            elif type(rule.action) == rich.Rich_Drop:
                action = "drop"
            elif type(rule.action) == rich.Rich_Mark:
                action = "mark"
                attrs["set"] = rule.action.set
            else:
                log.warning("Unknown action '%s'", type(rule.action))
            if rule.action.limit:
                handler.ignorableWhitespace("    ")
                handler.startElement(action, attrs)
                handler.ignorableWhitespace("\n      ")
                _handler_add_rich_limit(handler, rule.action.limit)
                handler.ignorableWhitespace("\n    ")
                handler.endElement(action)
            else:
                handler.ignorableWhitespace("    ")
                handler.simpleElement(action, attrs)
            handler.ignorableWhitespace("\n")

        handler.ignorableWhitespace("  ")
        handler.endElement("rule")
        handler.ignorableWhitespace("\n")


class Policy(IO_Object):
    priority_min = -32768
    priority_max =  32767
    priority_default = DEFAULT_POLICY_PRIORITY
    priority_reserved = [0]

    IMPORT_EXPORT_STRUCTURE = (
        ( "version",  "" ),                            # s
        ( "short", "" ),                               # s
        ( "description", "" ),                         # s
        ( "target", "" ),                              # s
        ( "services", [ "", ], ),                      # as
        ( "ports", [ ( "", "" ), ], ),                 # a(ss)
        ( "icmp_blocks", [ "", ], ),                   # as
        ( "masquerade", False ),                       # b
        ( "forward_ports", [ ( "", "", "", "" ), ], ), # a(ssss)
        ( "rich_rules", [ "" ] ),                      # as
        ( "protocols", [ "", ], ),                     # as
        ( "source_ports", [ ( "", "" ), ], ),          # a(ss)
        ( "priority", 0 ),                             # i
        ( "ingress_zones", [ "" ] ),                   # as
        ( "egress_zones", [ "" ] ),                    # as
        )
    ADDITIONAL_ALNUM_CHARS = [ "_", "-", "/" ]
    PARSER_REQUIRED_ELEMENT_ATTRS = {
        "short": None,
        "description": None,
        "policy": ["target"],
        "service": [ "name" ],
        "port": [ "port", "protocol" ],
        "icmp-block": [ "name" ],
        "icmp-type": [ "name" ],
        "masquerade": None,
        "forward-port": [ "port", "protocol" ],
        "rule": None,
        "source": None,
        "destination": None,
        "protocol": [ "value" ],
        "source-port": [ "port", "protocol" ],
        "log":  None,
        "audit": None,
        "accept": None,
        "reject": None,
        "drop": None,
        "mark": [ "set" ],
        "limit": [ "value" ],
        "ingress-zone": [ "name" ],
        "egress-zone": [ "name" ],
        }
    PARSER_OPTIONAL_ELEMENT_ATTRS = {
        "policy": [ "version", "priority" ],
        "forward-port": [ "to-port", "to-addr" ],
        "rule": [ "family", "priority" ],
        "source": [ "address", "mac", "invert", "family", "ipset" ],
        "destination": [ "address", "invert", "ipset" ],
        "log": [ "prefix", "level" ],
        "reject": [ "type" ],
        "limit": ["burst"],
        }

    def __init__(self):
        super(Policy, self).__init__()
        self.version = ""
        self.short = ""
        self.description = ""
        self.target = DEFAULT_POLICY_TARGET
        self.services = [ ]
        self.ports = [ ]
        self.protocols = [ ]
        self.icmp_blocks = [ ]
        self.masquerade = False
        self.forward_ports = [ ]
        self.source_ports = [ ]
        self.fw_config = None # to be able to check services and a icmp_blocks
        self.rules = [ ]
        self.rules_str = [ ]
        self.applied = False
        self.priority = self.priority_default
        self.derived_from_zone = None
        self.ingress_zones = []
        self.egress_zones = []

    def cleanup(self):
        self.version = ""
        self.short = ""
        self.description = ""
        self.target = DEFAULT_POLICY_TARGET
        del self.services[:]
        del self.ports[:]
        del self.protocols[:]
        del self.icmp_blocks[:]
        self.masquerade = False
        del self.forward_ports[:]
        del self.source_ports[:]
        self.fw_config = None # to be able to check services and a icmp_blocks
        del self.rules[:]
        del self.rules_str[:]
        self.applied = False
        self.priority = self.priority_default
        del self.ingress_zones[:]
        del self.egress_zones[:]

    def __getattr__(self, name):
        if name == "rich_rules":
            return self.rules_str
        else:
            return getattr(super(Policy, self), name)

    def __setattr__(self, name, value):
        if name == "rich_rules":
            self.rules = [rich.Rich_Rule(rule_str=s) for s in value]
            # must convert back to string to get the canonical string.
            self.rules_str = [str(s) for s in self.rules]
        else:
            super(Policy, self).__setattr__(name, value)

    def _check_config(self, config, item, all_config):
        common_check_config(self, config, item, all_config)

        if item == "target":
            if config not in POLICY_TARGETS:
                raise FirewallError(errors.INVALID_TARGET, "'%s' is invalid target" % (config))
        elif item == "priority":
            if config in self.priority_reserved or \
               config > self.priority_max or \
               config < self.priority_min:
                raise FirewallError(errors.INVALID_PRIORITY, "%d is invalid priority. Must be in range [%d, %d]. The following are reserved: %s" %
                                                             (config, self.priority_min, self.priority_max, self.priority_reserved))
        elif item in ["ingress_zones", "egress_zones"]:
            existing_zones = ["ANY", "HOST"]
            if self.fw_config:
                existing_zones += self.fw_config.get_zones()
            for zone in config:
                if zone not in existing_zones:
                    raise FirewallError(errors.INVALID_ZONE,
                                        "'%s' not among existing zones" % (zone))
                if ((zone not in ["ANY", "HOST"] and (set(["ANY", "HOST"]) & set(config))) or \
                   (zone in ["ANY", "HOST"] and (set(config) - set([zone])))):
                    raise FirewallError(errors.INVALID_ZONE,
                                        "'%s' may only contain one of: many regular zones, ANY, or HOST" % (item))
                if zone == "HOST" and \
                   ((item == "ingress_zones" and "egress_zones" in all_config and "HOST" in all_config["egress_zones"]) or \
                   (item == "egress_zones" and "ingress_zones" in all_config and "HOST" in all_config["ingress_zones"])):
                    raise FirewallError(errors.INVALID_ZONE,
                                        "'HOST' can only appear in either ingress or egress zones, but not both")
        elif item == "masquerade" and config:
            if "egress_zones" in all_config and "HOST" in all_config["egress_zones"]:
                raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for egress zone 'HOST'")
            elif "ingress_zones" in all_config:
                if "HOST" in all_config["ingress_zones"]:
                    raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for ingress zone 'HOST'")
                for zone in all_config["ingress_zones"]:
                    if zone == "ANY":
                        continue
                    z_obj = self.fw_config.get_zone(zone)
                    if self.fw_config and "interfaces" in self.fw_config.get_zone_config_dict(z_obj):
                        raise FirewallError(errors.INVALID_ZONE, "'masquerade' cannot be used in a policy if an ingress zone has assigned interfaces")
        elif item == "rich_rules":
            for rule in config:
                obj = rich.Rich_Rule(rule_str=rule)
                if obj.element and isinstance(obj.element, rich.Rich_Masquerade):
                    if "egress_zones" in all_config and "HOST" in all_config["egress_zones"]:
                        raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for egress zone 'HOST'")
                    elif "ingress_zones" in all_config:
                        if "HOST" in all_config["ingress_zones"]:
                            raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for ingress zone 'HOST'")
                        for zone in all_config["ingress_zones"]:
                            if zone == "ANY":
                                continue
                            z_obj = self.fw_config.get_zone(zone)
                            if self.fw_config and "interfaces" in self.fw_config.get_zone_config_dict(z_obj):
                                raise FirewallError(errors.INVALID_ZONE, "'masquerade' cannot be used in a policy if an ingress zone has assigned interfaces")
                elif obj.element and isinstance(obj.element, rich.Rich_ForwardPort):
                    if "egress_zones" in all_config:
                        if "HOST" in all_config["egress_zones"]:
                            if obj.element.to_address:
                                raise FirewallError(errors.INVALID_FORWARD, "A 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'")
                        elif all_config["egress_zones"]:
                            if not obj.element.to_address:
                                raise FirewallError(errors.INVALID_FORWARD, "'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zone")
                            if "ANY" not in all_config["egress_zones"]:
                                for zone in all_config["egress_zones"]:
                                    z_obj = self.fw_config.get_zone(zone)
                                    if self.fw_config and "interfaces" in self.fw_config.get_zone_config_dict(z_obj):
                                        raise FirewallError(errors.INVALID_ZONE, "'forward-port' cannot be used in a policy if an egress zone has assigned interfaces")
                elif obj.action and isinstance(obj.action, rich.Rich_Mark):
                    if "egress_zones" in all_config:
                        for zone in all_config["egress_zones"]:
                            if zone in ["ANY", "HOST"]:
                                continue
                            z_obj = self.fw_config.get_zone(zone)
                            if self.fw_config and "interfaces" in self.fw_config.get_zone_config_dict(z_obj):
                                raise FirewallError(errors.INVALID_ZONE, "'mark' action cannot be used in a policy if an egress zone has assigned interfaces")
        elif item == "forward_ports":
            for fwd_port in config:
                if "ingress_zones" in all_config and "HOST" in all_config["ingress_zones"]:
                    raise FirewallError(errors.INVALID_ZONE, "'forward-port' is invalid for ingress zone 'HOST'")
                elif "egress_zones" in all_config:
                    if "HOST" in all_config["egress_zones"]:
                        if fwd_port[3]:
                            raise FirewallError(errors.INVALID_FORWARD, "A 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'")
                    elif all_config["egress_zones"]:
                        if not fwd_port[3]:
                            raise FirewallError(errors.INVALID_FORWARD, "'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zone")
                        if "ANY" not in all_config["egress_zones"]:
                            for zone in all_config["egress_zones"]:
                                z_obj = self.fw_config.get_zone(zone)
                                if self.fw_config and "interfaces" in self.fw_config.get_zone_config_dict(z_obj):
                                    raise FirewallError(errors.INVALID_ZONE, "'forward-port' cannot be used in a policy if an egress zone has assigned interfaces")

    def check_name(self, name):
        super(Policy, self).check_name(name)
        if name.startswith('/'):
            raise FirewallError(errors.INVALID_NAME,
                                "'%s' can't start with '/'" % name)
        elif name.endswith('/'):
            raise FirewallError(errors.INVALID_NAME,
                                "'%s' can't end with '/'" % name)
        elif name.count('/') > 1:
            raise FirewallError(errors.INVALID_NAME,
                                "more than one '/' in '%s'" % name)
        else:
            if "/" in name:
                checked_name = name[:name.find('/')]
            else:
                checked_name = name
            if len(checked_name) > max_policy_name_len():
                raise FirewallError(errors.INVALID_NAME,
                                    "Policy of '%s' has %d chars, max is %d" % (
                                    name, len(checked_name),
                                    max_policy_name_len()))
            if self.fw_config:
                if checked_name in self.fw_config.get_zones():
                    raise FirewallError(errors.NAME_CONFLICT, "Policies can't have the same name as a zone.")

# PARSER

class policy_ContentHandler(IO_Object_ContentHandler):
    def __init__(self, item):
        IO_Object_ContentHandler.__init__(self, item)
        self._rule = None
        self._rule_error = False
        self._limit_ok = None

    def startElement(self, name, attrs):
        IO_Object_ContentHandler.startElement(self, name, attrs)
        if self._rule_error:
            return

        self.item.parser_check_element_attrs(name, attrs)

        if common_startElement(self, name, attrs):
            return

        elif name == "policy":
            if "version" in attrs:
                self.item.version = attrs["version"]
            if "priority" in attrs:
                self.item.priority = int(attrs["priority"])
            if "target" in attrs:
                target = attrs["target"]
                if target not in POLICY_TARGETS:
                    raise FirewallError(errors.INVALID_TARGET, target)
                if target:
                    self.item.target = target

        elif name == "ingress-zone":
            if attrs["name"] not in self.item.ingress_zones:
                self.item.ingress_zones.append(attrs["name"])
            else:
                log.warning("Ingress zone '%s' already set, ignoring.", attrs["name"])

        elif name == "egress-zone":
            if attrs["name"] not in self.item.egress_zones:
                self.item.egress_zones.append(attrs["name"])
            else:
                log.warning("Egress zone '%s' already set, ignoring.", attrs["name"])

        elif name == "source":
            if not self._rule:
                log.warning('Invalid rule: Source outside of rule')
                self._rule_error = True
                return

            if self._rule.source:
                log.warning("Invalid rule: More than one source in rule '%s', ignoring.",
                            str(self._rule))
                self._rule_error = True
                return
            invert = False
            if "invert" in attrs and \
                    attrs["invert"].lower() in [ "yes", "true" ]:
                invert = True
            addr = mac = ipset = None
            if "address" in attrs:
                addr = attrs["address"]
            if "mac" in attrs:
                mac = attrs["mac"]
            if "ipset" in attrs:
                ipset = attrs["ipset"]
            self._rule.source = rich.Rich_Source(addr, mac, ipset,
                                                 invert=invert)
            return

        else:
            log.warning("Unknown XML element '%s'", name)
            return

    def endElement(self, name):
        IO_Object_ContentHandler.endElement(self, name)

        common_endElement(self, name)

def policy_reader(filename, path, no_check_name=False):
    policy = Policy()
    if not filename.endswith(".xml"):
        raise FirewallError(errors.INVALID_NAME,
                            "'%s' is missing .xml suffix" % filename)
    policy.name = filename[:-4]
    if not no_check_name:
        policy.check_name(policy.name)
    policy.filename = filename
    policy.path = path
    policy.builtin = False if path.startswith(config.ETC_FIREWALLD) else True
    policy.default = policy.builtin
    handler = policy_ContentHandler(policy)
    parser = sax.make_parser()
    parser.setContentHandler(handler)
    name = "%s/%s" % (path, filename)
    with open(name, "rb") as f:
        source = sax.InputSource(None)
        source.setByteStream(f)
        try:
            parser.parse(source)
        except sax.SAXParseException as msg:
            raise FirewallError(errors.INVALID_POLICY,
                                "not a valid policy file: %s" % \
                                msg.getException())
    del handler
    del parser
    return policy

def policy_writer(policy, path=None):
    _path = path if path else policy.path

    if policy.filename:
        name = "%s/%s" % (_path, policy.filename)
    else:
        name = "%s/%s.xml" % (_path, policy.name)

    if os.path.exists(name):
        try:
            shutil.copy2(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)

    dirpath = os.path.dirname(name)
    if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath):
        if not os.path.exists(config.ETC_FIREWALLD):
            os.mkdir(config.ETC_FIREWALLD, 0o750)
        os.mkdir(dirpath, 0o750)

    f = io.open(name, mode='wt', encoding='UTF-8')
    handler = IO_Object_XMLGenerator(f)
    handler.startDocument()

    # start policy element
    attrs = {}
    if policy.version and policy.version != "":
        attrs["version"] = policy.version
    if policy.priority != policy.priority_default:
        attrs["priority"] = str(policy.priority)
    attrs["target"] = policy.target
    handler.startElement("policy", attrs)
    handler.ignorableWhitespace("\n")

    common_writer(policy, handler)

    # ingress-zones
    for zone in uniqify(policy.ingress_zones):
        handler.ignorableWhitespace("  ")
        handler.simpleElement("ingress-zone", { "name": zone })
        handler.ignorableWhitespace("\n")

    # egress-zones
    for zone in uniqify(policy.egress_zones):
        handler.ignorableWhitespace("  ")
        handler.simpleElement("egress-zone", { "name": zone })
        handler.ignorableWhitespace("\n")

    # end policy element
    handler.endElement("policy")
    handler.ignorableWhitespace("\n")
    handler.endDocument()
    f.close()
    del handler
core/io/lockdown_whitelist.py000064400000030647150351351720012405 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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 xml.sax as sax
import os
import io
import shutil

from firewall import config
from firewall.core.io.io_object import PY2, IO_Object, \
                    IO_Object_ContentHandler, IO_Object_XMLGenerator
from firewall.core.logger import log
from firewall.functions import uniqify, checkUser, checkUid, checkCommand, \
                               checkContext, u2b_if_py2
from firewall import errors
from firewall.errors import FirewallError

class lockdown_whitelist_ContentHandler(IO_Object_ContentHandler):
    def __init__(self, item):
        IO_Object_ContentHandler.__init__(self, item)
        self.whitelist = False

    def startElement(self, name, attrs):
        IO_Object_ContentHandler.startElement(self, name, attrs)
        self.item.parser_check_element_attrs(name, attrs)

        if name == "whitelist":
            if self.whitelist:
                raise FirewallError(errors.PARSE_ERROR,
                                    "More than one whitelist.")
            self.whitelist = True

        elif name == "command":
            if not self.whitelist:
                log.error("Parse Error: command outside of whitelist")
                return
            command = attrs["name"]
            self.item.add_command(command)

        elif name == "user":
            if not self.whitelist:
                log.error("Parse Error: user outside of whitelist")
                return
            if "id" in attrs:
                try:
                    uid = int(attrs["id"])
                except ValueError:
                    log.error("Parse Error: %s is not a valid uid" % 
                              attrs["id"])
                    return
                self.item.add_uid(uid)
            elif "name" in attrs:
                self.item.add_user(attrs["name"])

        elif name == "selinux":
            if not self.whitelist:
                log.error("Parse Error: selinux outside of whitelist")
                return
            if "context" not in attrs:
                log.error("Parse Error: no context")
                return
            self.item.add_context(attrs["context"])
            

        else:
            log.error('Unknown XML element %s' % name)
            return

class LockdownWhitelist(IO_Object):
    """ LockdownWhitelist class """

    IMPORT_EXPORT_STRUCTURE = (
        ( "commands", [ "" ] ),   # as
        ( "contexts", [ "" ] ),   # as
        ( "users", [ "" ] ),      # as
        ( "uids", [ 0 ] )         # ai
        )
    DBUS_SIGNATURE = '(asasasai)'
    ADDITIONAL_ALNUM_CHARS = [ "_" ]
    PARSER_REQUIRED_ELEMENT_ATTRS = {
        "whitelist": None,
        "command": [ "name" ],
        "user": None,
#        "group": None,
        "selinux": [ "context" ],
        }
    PARSER_OPTIONAL_ELEMENT_ATTRS = {
        "user": [ "id", "name" ],
#        "group": [ "id", "name" ],
        }

    def __init__(self, filename):
        super(LockdownWhitelist, self).__init__()
        self.filename = filename
        self.parser = None
        self.commands = [ ]
        self.contexts = [ ]
        self.users = [ ]
        self.uids = [ ]
#        self.gids = [ ]
#        self.groups = [ ]

    def _check_config(self, config, item, all_config):
        if item in [ "commands", "contexts", "users", "uids" ]:
            for x in config:
                self._check_config(x, item[:-1], all_config)
        elif item == "command":
            if not checkCommand(config):
                raise FirewallError(errors.INVALID_COMMAND, config)
        elif item == "context":
            if not checkContext(config):
                raise FirewallError(errors.INVALID_CONTEXT, config)
        elif item == "user":
            if not checkUser(config):
                raise FirewallError(errors.INVALID_USER, config)
        elif item == "uid":
            if not checkUid(config):
                raise FirewallError(errors.INVALID_UID, config)

    def cleanup(self):
        del self.commands[:]
        del self.contexts[:]
        del self.users[:]
        del self.uids[:]
#        del self.gids[:]
#        del self.groups[:]

    def encode_strings(self):
        """ HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support."""
        self.commands = [ u2b_if_py2(x) for x in self.commands ]
        self.contexts = [ u2b_if_py2(x) for x in self.contexts ]
        self.users = [ u2b_if_py2(x) for x in self.users ]

    # commands

    def add_command(self, command):
        if not checkCommand(command):
            raise FirewallError(errors.INVALID_COMMAND, command)
        if command not in self.commands:
            self.commands.append(command)
        else:
            raise FirewallError(errors.ALREADY_ENABLED,
                                'Command "%s" already in whitelist' % command)

    def remove_command(self, command):
        if command in self.commands:
            self.commands.remove(command)
        else:
            raise FirewallError(errors.NOT_ENABLED,
                                'Command "%s" not in whitelist.' % command)

    def has_command(self, command):
        return (command in self.commands)

    def match_command(self, command):
        for _command in self.commands:
            if _command.endswith("*"):
                if command.startswith(_command[:-1]):
                    return True
            else:
                if _command == command:
                    return True
        return False

    def get_commands(self):
        return self.commands

    # user ids

    def add_uid(self, uid):
        if not checkUid(uid):
            raise FirewallError(errors.INVALID_UID, str(uid))
        if uid not in self.uids:
            self.uids.append(uid)
        else:
            raise FirewallError(errors.ALREADY_ENABLED,
                                'Uid "%s" already in whitelist' % uid)


    def remove_uid(self, uid):
        if uid in self.uids:
            self.uids.remove(uid)
        else:
            raise FirewallError(errors.NOT_ENABLED,
                                'Uid "%s" not in whitelist.' % uid)

    def has_uid(self, uid):
        return (uid in self.uids)

    def match_uid(self, uid):
        return (uid in self.uids)

    def get_uids(self):
        return self.uids

    # users

    def add_user(self, user):
        if not checkUser(user):
            raise FirewallError(errors.INVALID_USER, user)
        if user not in self.users:
            self.users.append(user)
        else:
            raise FirewallError(errors.ALREADY_ENABLED,
                                'User "%s" already in whitelist' % user)


    def remove_user(self, user):
        if user in self.users:
            self.users.remove(user)
        else:
            raise FirewallError(errors.NOT_ENABLED,
                                'User "%s" not in whitelist.' % user)

    def has_user(self, user):
        return (user in self.users)

    def match_user(self, user):
        return (user in self.users)

    def get_users(self):
        return self.users

#    # group ids
#
#    def add_gid(self, gid):
#        if gid not in self.gids:
#            self.gids.append(gid)
#
#    def remove_gid(self, gid):
#        if gid in self.gids:
#            self.gids.remove(gid)
#        else:
#            raise FirewallError(errors.NOT_ENABLED,
#                                'Gid "%s" not in whitelist.' % gid)
#
#    def has_gid(self, gid):
#        return (gid in self.gids)
#
#    def match_gid(self, gid):
#        return (gid in self.gids)
#
#    def get_gids(self):
#        return self.gids

#    # groups
#
#    def add_group(self, group):
#        if group not in self.groups:
#            self.groups.append(group)
#
#    def remove_group(self, group):
#        if group in self.groups:
#            self.groups.remove(group)
#        else:
#            raise FirewallError(errors.NOT_ENABLED,
#                                'Group "%s" not in whitelist.' % group)
#
#    def has_group(self, group):
#        return (group in self.groups)
#
#    def match_group(self, group):
#        return (group in self.groups)
#
#    def get_groups(self):
#        return self.groups

    # selinux contexts

    def add_context(self, context):
        if not checkContext(context):
            raise FirewallError(errors.INVALID_CONTEXT, context)
        if context not in self.contexts:
            self.contexts.append(context)
        else:
            raise FirewallError(errors.ALREADY_ENABLED,
                                'Context "%s" already in whitelist' % context)


    def remove_context(self, context):
        if context in self.contexts:
            self.contexts.remove(context)
        else:
            raise FirewallError(errors.NOT_ENABLED,
                                'Context "%s" not in whitelist.' % context)

    def has_context(self, context):
        return (context in self.contexts)

    def match_context(self, context):
        return (context in self.contexts)

    def get_contexts(self):
        return self.contexts

    # read and write

    def read(self):
        self.cleanup()
        if not self.filename.endswith(".xml"):
            raise FirewallError(errors.INVALID_NAME,
                                "'%s' is missing .xml suffix" % self.filename)
        handler = lockdown_whitelist_ContentHandler(self)
        parser = sax.make_parser()
        parser.setContentHandler(handler)
        try:
            parser.parse(self.filename)
        except sax.SAXParseException as msg:
            raise FirewallError(errors.INVALID_TYPE,
                                "Not a valid file: %s" % \
                                msg.getException())
        del handler
        del parser
        if PY2:
            self.encode_strings()

    def write(self):
        if os.path.exists(self.filename):
            try:
                shutil.copy2(self.filename, "%s.old" % self.filename)
            except Exception as msg:
                raise IOError("Backup of '%s' failed: %s" % (self.filename, msg))

        if not os.path.exists(config.ETC_FIREWALLD):
            os.mkdir(config.ETC_FIREWALLD, 0o750)

        f = io.open(self.filename, mode='wt', encoding='UTF-8')
        handler = IO_Object_XMLGenerator(f)
        handler.startDocument()

        # start whitelist element
        handler.startElement("whitelist", { })
        handler.ignorableWhitespace("\n")

        # commands
        for command in uniqify(self.commands):
            handler.ignorableWhitespace("  ")
            handler.simpleElement("command", { "name": command })
            handler.ignorableWhitespace("\n")

        for uid in uniqify(self.uids):
            handler.ignorableWhitespace("  ")
            handler.simpleElement("user", { "id": str(uid) })
            handler.ignorableWhitespace("\n")

        for user in uniqify(self.users):
            handler.ignorableWhitespace("  ")
            handler.simpleElement("user", { "name": user })
            handler.ignorableWhitespace("\n")

#        for gid in uniqify(self.gids):
#            handler.ignorableWhitespace("  ")
#            handler.simpleElement("user", { "id": str(gid) })
#            handler.ignorableWhitespace("\n")

#        for group in uniqify(self.groups):
#            handler.ignorableWhitespace("  ")
#            handler.simpleElement("group", { "name": group })
#            handler.ignorableWhitespace("\n")

        for context in uniqify(self.contexts):
            handler.ignorableWhitespace("  ")
            handler.simpleElement("selinux", { "context": context })
            handler.ignorableWhitespace("\n")

        # end whitelist element
        handler.endElement("whitelist")
        handler.ignorableWhitespace("\n")
        handler.endDocument()
        f.close()
        del handler
core/io/io_object.py000064400000032422150351351720010417 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""Generic io_object handler, io specific check methods."""

__all__ = [ "PY2",
            "IO_Object", "IO_Object_ContentHandler", "IO_Object_XMLGenerator",
            "check_port", "check_tcpudp", "check_protocol", "check_address" ]

import xml.sax as sax
import xml.sax.saxutils as saxutils
import copy
import sys
from collections import OrderedDict

from firewall import functions
from firewall.functions import b2u
from firewall import errors
from firewall.errors import FirewallError

PY2 = sys.version < '3'

class IO_Object(object):
    """ Abstract IO_Object as base for icmptype, service and zone """

    IMPORT_EXPORT_STRUCTURE = ( )
    DBUS_SIGNATURE = '()'
    ADDITIONAL_ALNUM_CHARS = [ ] # additional to alnum
    PARSER_REQUIRED_ELEMENT_ATTRS = { }
    PARSER_OPTIONAL_ELEMENT_ATTRS = { }

    def __init__(self):
        self.filename = ""
        self.path = ""
        self.name = ""
        self.default = False
        self.builtin = False

    def export_config(self):
        ret = [ ]
        for x in self.IMPORT_EXPORT_STRUCTURE:
            ret.append(copy.deepcopy(getattr(self, x[0])))
        return tuple(ret)

    def export_config_dict(self):
        conf = {}
        type_formats = dict([(x[0], x[1]) for x in self.IMPORT_EXPORT_STRUCTURE])
        for key in type_formats:
            if getattr(self, key) or isinstance(getattr(self, key), bool):
                conf[key] = copy.deepcopy(getattr(self, key))
        return conf

    def import_config(self, conf):
        self.check_config(conf)
        for i,(element,dummy) in enumerate(self.IMPORT_EXPORT_STRUCTURE):
            if isinstance(conf[i], list):
                # remove duplicates without changing the order
                _conf = [ ]
                _set = set()
                for x in conf[i]:
                    if x not in _set:
                        _conf.append(x)
                        _set.add(x)
                del _set
                setattr(self, element, copy.deepcopy(_conf))
            else:
                setattr(self, element, copy.deepcopy(conf[i]))

    def import_config_dict(self, conf):
        self.check_config_dict(conf)

        for key in conf:
            if not hasattr(self, key):
                raise FirewallError(errors.UNKNOWN_ERROR, "Internal error. '{}' is not a valid attribute".format(key))
            if isinstance(conf[key], list):
                # maintain list order while removing duplicates
                setattr(self, key, list(OrderedDict.fromkeys(copy.deepcopy(conf[key]))))
            else:
                setattr(self, key, copy.deepcopy(conf[key]))

    def check_name(self, name):
        if not isinstance(name, str):
            raise FirewallError(errors.INVALID_TYPE,
                                "'%s' not of type %s, but %s" % (name, type(""),
                                                                 type(name)))
        if len(name) < 1:
            raise FirewallError(errors.INVALID_NAME, "name can't be empty")
        for char in name:
            if not char.isalnum() and char not in self.ADDITIONAL_ALNUM_CHARS:
                raise FirewallError(
                    errors.INVALID_NAME,
                    "'%s' is not allowed in '%s'" % ((char, name)))

    def check_config(self, conf):
        if len(conf) != len(self.IMPORT_EXPORT_STRUCTURE):
            raise FirewallError(
                errors.INVALID_TYPE,
                "structure size mismatch %d != %d" % \
                (len(conf), len(self.IMPORT_EXPORT_STRUCTURE)))
        conf_dict = {}
        for i,(x,y) in enumerate(self.IMPORT_EXPORT_STRUCTURE):
            conf_dict[x] = conf[i]
        self.check_config_dict(conf_dict)

    def check_config_dict(self, conf):
        type_formats = dict([(x[0], x[1]) for x in self.IMPORT_EXPORT_STRUCTURE])
        for key in conf:
            if key not in [x for (x,y) in self.IMPORT_EXPORT_STRUCTURE]:
                raise FirewallError(errors.INVALID_OPTION, "option '{}' is not valid".format(key))
            self._check_config_structure(conf[key], type_formats[key])
            self._check_config(conf[key], key, conf)

    def _check_config(self, dummy1, dummy2, dummy3):
        # to be overloaded by sub classes
        return

    def _check_config_structure(self, conf, structure):
        if not isinstance(conf, type(structure)):
            raise FirewallError(errors.INVALID_TYPE,
                                "'%s' not of type %s, but %s" % \
                                (conf, type(structure), type(conf)))
        if isinstance(structure, list):
            # same type elements, else struct
            if len(structure) != 1:
                raise FirewallError(errors.INVALID_TYPE,
                                    "len('%s') != 1" % structure)
            for x in conf:
                self._check_config_structure(x, structure[0])
        elif isinstance(structure, tuple):
            if len(structure) != len(conf):
                raise FirewallError(errors.INVALID_TYPE,
                                    "len('%s') != %d" % (conf,
                                                         len(structure)))
            for i,value in enumerate(structure):
                self._check_config_structure(conf[i], value)
        elif isinstance(structure, dict):
            # only one key value pair in structure
            (skey, svalue) = list(structure.items())[0]
            for (key, value) in conf.items():
                if not isinstance(key, type(skey)):
                    raise FirewallError(errors.INVALID_TYPE,
                                        "'%s' not of type %s, but %s" % (\
                            key, type(skey), type(key)))
                if not isinstance(value, type(svalue)):
                    raise FirewallError(errors.INVALID_TYPE,
                                        "'%s' not of type %s, but %s" % (\
                            value, type(svalue), type(value)))

    # check required elements and attributes and also optional attributes
    def parser_check_element_attrs(self, name, attrs):
        _attrs = attrs.getNames()

        found = False
        if name in self.PARSER_REQUIRED_ELEMENT_ATTRS:
            found = True
            if self.PARSER_REQUIRED_ELEMENT_ATTRS[name] is not None:
                for x in self.PARSER_REQUIRED_ELEMENT_ATTRS[name]:
                    if x in _attrs:
                        _attrs.remove(x)
                    else:
                        raise FirewallError(
                            errors.PARSE_ERROR,
                            "Missing attribute %s for %s" % (x, name))
        if name in self.PARSER_OPTIONAL_ELEMENT_ATTRS:
            found = True
            for x in self.PARSER_OPTIONAL_ELEMENT_ATTRS[name]:
                if x in _attrs:
                    _attrs.remove(x)
        if not found:
            raise FirewallError(errors.PARSE_ERROR,
                                "Unexpected element %s" % name)
        # raise attributes[0]
        for x in _attrs:
            raise FirewallError(errors.PARSE_ERROR,
                                "%s: Unexpected attribute %s" % (name, x))

# PARSER

class UnexpectedElementError(Exception):
    def __init__(self, name):
        super(UnexpectedElementError, self).__init__()
        self.name = name
    def __str__(self):
        return "Unexpected element '%s'" % (self.name)

class MissingAttributeError(Exception):
    def __init__(self, name, attribute):
        super(MissingAttributeError, self).__init__()
        self.name = name
        self.attribute = attribute
    def __str__(self):
        return "Element '%s': missing '%s' attribute" % \
            (self.name, self.attribute)

class UnexpectedAttributeError(Exception):
    def __init__(self, name, attribute):
        super(UnexpectedAttributeError, self).__init__()
        self.name = name
        self.attribute = attribute
    def __str__(self):
        return "Element '%s': unexpected attribute '%s'" % \
            (self.name, self.attribute)

class IO_Object_ContentHandler(sax.handler.ContentHandler):
    def __init__(self, item):
        self.item = item
        self._element = ""

    def startDocument(self):
        self._element = ""

    def startElement(self, name, attrs):
        self._element = ""

    def endElement(self, name):
        if name == "short":
            self.item.short = self._element
        elif name == "description":
            self.item.description = self._element

    def characters(self, content):
        self._element += content.replace('\n', ' ')

class IO_Object_XMLGenerator(saxutils.XMLGenerator):
    def __init__(self, out):
        # fix memory leak in saxutils.XMLGenerator.__init__:
        #   out = _gettextwriter(out, encoding)
        # creates unbound object results in garbage in gc
        #
        # saxutils.XMLGenerator.__init__(self, out, "utf-8")
        #   replaced by modified saxutils.XMLGenerator.__init__ code:
        sax.handler.ContentHandler.__init__(self)
        self._write = out.write
        self._flush = out.flush
        self._ns_contexts = [{}] # contains uri -> prefix dicts
        self._current_context = self._ns_contexts[-1]
        self._undeclared_ns_maps = []
        self._encoding = "utf-8"
        self._pending_start_element = False
        self._short_empty_elements = False

    def startElement(self, name, attrs):
        """ saxutils.XMLGenerator.startElement() expects name and attrs to be
            unicode and bad things happen if any of them is (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        """
        if PY2:
            attrs = { b2u(name):b2u(value) for name, value in attrs.items() }
        saxutils.XMLGenerator.startElement(self, name, attrs)

    def simpleElement(self, name, attrs):
        """ slightly modified startElement()
        """
        if PY2:
            self._write(u'<' + b2u(name))
            for (name, value) in attrs.items():
                self._write(u' %s=%s' % (b2u(name),
                                         saxutils.quoteattr(b2u(value))))
            self._write(u'/>')
        else:
            self._write('<' + name)
            for (name, value) in attrs.items():
                self._write(' %s=%s' % (name, saxutils.quoteattr(value)))
            self._write('/>')

    def endElement(self, name):
        """ saxutils.XMLGenerator.endElement() expects name to be
            unicode and bad things happen if it's (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        """
        saxutils.XMLGenerator.endElement(self, b2u(name))

    def characters(self, content):
        """ saxutils.XMLGenerator.characters() expects content to be
            unicode and bad things happen if it's (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        """
        saxutils.XMLGenerator.characters(self, b2u(content))

    def ignorableWhitespace(self, content):
        """ saxutils.XMLGenerator.ignorableWhitespace() expects content to be
            unicode and bad things happen if it's (utf-8) encoded.
            We override the method here to sanitize this case.
            Can be removed once we drop Python2 support.
        """
        saxutils.XMLGenerator.ignorableWhitespace(self, b2u(content))

def check_port(port):
    port_range = functions.getPortRange(port)
    if port_range == -2:
        raise FirewallError(errors.INVALID_PORT,
                            "port number in '%s' is too big" % port)
    elif port_range == -1:
        raise FirewallError(errors.INVALID_PORT,
                            "'%s' is invalid port range" % port)
    elif port_range is None:
        raise FirewallError(errors.INVALID_PORT,
                            "port range '%s' is ambiguous" % port)
    elif len(port_range) == 2 and port_range[0] >= port_range[1]:
        raise FirewallError(errors.INVALID_PORT,
                            "'%s' is invalid port range" % port)

def check_tcpudp(protocol):
    if protocol not in [ "tcp", "udp", "sctp", "dccp" ]:
        raise FirewallError(errors.INVALID_PROTOCOL,
                            "'%s' not from {'tcp'|'udp'|'sctp'|'dccp'}" % \
                            protocol)

def check_protocol(protocol):
    if not functions.checkProtocol(protocol):
        raise FirewallError(errors.INVALID_PROTOCOL, protocol)

def check_address(ipv, addr):
    if not functions.check_address(ipv, addr):
        raise FirewallError(errors.INVALID_ADDR,
                            "'%s' is not valid %s address" % (addr, ipv))

core/io/functions.py000064400000011171150351351720010470 0ustar00# -*- 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.fw_config import FirewallConfig
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.policy import policy_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):
    fw_config = FirewallConfig(fw)
    readers = {
        "ipset":    {"reader": ipset_reader,
                     "add": fw_config.add_ipset,
                     "dirs": [config.FIREWALLD_IPSETS, config.ETC_FIREWALLD_IPSETS],
                    },
        "helper":   {"reader": helper_reader,
                     "add": fw_config.add_helper,
                     "dirs": [config.FIREWALLD_HELPERS, config.ETC_FIREWALLD_HELPERS],
                    },
        "icmptype": {"reader": icmptype_reader,
                     "add": fw_config.add_icmptype,
                     "dirs": [config.FIREWALLD_ICMPTYPES, config.ETC_FIREWALLD_ICMPTYPES],
                    },
        "service":  {"reader": service_reader,
                     "add": fw_config.add_service,
                     "dirs": [config.FIREWALLD_SERVICES, config.ETC_FIREWALLD_SERVICES],
                    },
        "zone":     {"reader": zone_reader,
                     "add": fw_config.add_zone,
                     "dirs": [config.FIREWALLD_ZONES, config.ETC_FIREWALLD_ZONES],
                    },
        "policy":   {"reader": policy_reader,
                     "add": fw_config.add_policy_object,
                     "dirs": [config.FIREWALLD_POLICIES, config.ETC_FIREWALLD_POLICIES],
                    },
    }
    for reader in readers.keys():
        for _dir in readers[reader]["dirs"]:
            if not os.path.isdir(_dir):
                continue
            for file in sorted(os.listdir(_dir)):
                if file.endswith(".xml"):
                    try:
                        obj = readers[reader]["reader"](file, _dir)
                        if reader in ["zone", "policy"]:
                            obj.fw_config = fw_config
                        obj.check_config_dict(obj.export_config_dict())
                        readers[reader]["add"](obj)
                    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))
core/io/zone.py000064400000046600150351351720007440 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "Zone", "zone_reader", "zone_writer" ]

import xml.sax as sax
import os
import io
import shutil

from firewall import config
from firewall.functions import checkIPnMask, checkIP6nMask, checkInterface, uniqify, max_zone_name_len, u2b_if_py2, check_mac
from firewall.core.base import DEFAULT_ZONE_TARGET, ZONE_TARGETS
from firewall.core.io.io_object import PY2, IO_Object, \
    IO_Object_ContentHandler, IO_Object_XMLGenerator
from firewall.core.io.policy import common_startElement, common_endElement, common_check_config, common_writer
from firewall.core import rich
from firewall.core.logger import log
from firewall import errors
from firewall.errors import FirewallError

class Zone(IO_Object):
    """ Zone class """

    IMPORT_EXPORT_STRUCTURE = (
        ( "version",  "" ),                            # s
        ( "short", "" ),                               # s
        ( "description", "" ),                         # s
        ( "UNUSED", False ),                           # b
        ( "target", "" ),                              # s
        ( "services", [ "", ], ),                      # as
        ( "ports", [ ( "", "" ), ], ),                 # a(ss)
        ( "icmp_blocks", [ "", ], ),                   # as
        ( "masquerade", False ),                       # b
        ( "forward_ports", [ ( "", "", "", "" ), ], ), # a(ssss)
        ( "interfaces", [ "" ] ),                      # as
        ( "sources", [ "" ] ),                         # as
        ( "rules_str", [ "" ] ),                       # as
        ( "protocols", [ "", ], ),                     # as
        ( "source_ports", [ ( "", "" ), ], ),          # a(ss)
        ( "icmp_block_inversion", False ),             # b
        ( "forward", False ),                          # b
        )
    ADDITIONAL_ALNUM_CHARS = [ "_", "-", "/" ]
    PARSER_REQUIRED_ELEMENT_ATTRS = {
        "short": None,
        "description": None,
        "zone": None,
        "service": [ "name" ],
        "port": [ "port", "protocol" ],
        "icmp-block": [ "name" ],
        "icmp-type": [ "name" ],
        "forward": None,
        "forward-port": [ "port", "protocol" ],
        "interface": [ "name" ],
        "rule": None,
        "source": None,
        "destination": None,
        "protocol": [ "value" ],
        "source-port": [ "port", "protocol" ],
        "log":  None,
        "audit": None,
        "accept": None,
        "reject": None,
        "drop": None,
        "mark": [ "set" ],
        "limit": [ "value" ],
        "icmp-block-inversion": None,
        }
    PARSER_OPTIONAL_ELEMENT_ATTRS = {
        "zone": [ "name", "immutable", "target", "version" ],
        "masquerade": [ "enabled" ],
        "forward-port": [ "to-port", "to-addr" ],
        "rule": [ "family", "priority" ],
        "source": [ "address", "mac", "invert", "family", "ipset" ],
        "destination": [ "address", "invert", "ipset" ],
        "log": [ "prefix", "level" ],
        "reject": [ "type" ],
        "limit": ["burst"],
        }

    @staticmethod
    def index_of(element):
        for i, (el, dummy) in enumerate(Zone.IMPORT_EXPORT_STRUCTURE):
            if el == element:
                return i
        raise FirewallError(errors.UNKNOWN_ERROR, "index_of()")

    def __init__(self):
        super(Zone, self).__init__()
        self.version = ""
        self.short = ""
        self.description = ""
        self.UNUSED = False
        self.target = DEFAULT_ZONE_TARGET
        self.services = [ ]
        self.ports = [ ]
        self.protocols = [ ]
        self.icmp_blocks = [ ]
        self.forward = False
        self.masquerade = False
        self.forward_ports = [ ]
        self.source_ports = [ ]
        self.interfaces = [ ]
        self.sources = [ ]
        self.fw_config = None # to be able to check services and a icmp_blocks
        self.rules = [ ]
        self.rules_str = [ ]
        self.icmp_block_inversion = False
        self.combined = False
        self.applied = False

    def cleanup(self):
        self.version = ""
        self.short = ""
        self.description = ""
        self.UNUSED = False
        self.target = DEFAULT_ZONE_TARGET
        del self.services[:]
        del self.ports[:]
        del self.protocols[:]
        del self.icmp_blocks[:]
        self.forward = False
        self.masquerade = False
        del self.forward_ports[:]
        del self.source_ports[:]
        del self.interfaces[:]
        del self.sources[:]
        self.fw_config = None # to be able to check services and a icmp_blocks
        del self.rules[:]
        del self.rules_str[:]
        self.icmp_block_inversion = False
        self.combined = False
        self.applied = False

    def encode_strings(self):
        """ HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support."""
        self.version = u2b_if_py2(self.version)
        self.short = u2b_if_py2(self.short)
        self.description = u2b_if_py2(self.description)
        self.target = u2b_if_py2(self.target)
        self.services = [u2b_if_py2(s) for s in self.services]
        self.ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr) in self.ports]
        self.protocols = [u2b_if_py2(pr) for pr in self.protocols]
        self.icmp_blocks = [u2b_if_py2(i) for i in self.icmp_blocks]
        self.forward_ports = [(u2b_if_py2(p1),u2b_if_py2(p2),u2b_if_py2(p3),u2b_if_py2(p4)) for (p1,p2,p3,p4) in self.forward_ports]
        self.source_ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr)
                             in self.source_ports]
        self.interfaces = [u2b_if_py2(i) for i in self.interfaces]
        self.sources = [u2b_if_py2(s) for s in self.sources]
        self.rules = [u2b_if_py2(s) for s in self.rules]
        self.rules_str = [u2b_if_py2(s) for s in self.rules_str]

    def __setattr__(self, name, value):
        if name == "rules_str":
            self.rules = [rich.Rich_Rule(rule_str=s) for s in value]
            # must convert back to string to get the canonical string.
            super(Zone, self).__setattr__(name, [str(s) for s in self.rules])
        else:
            super(Zone, self).__setattr__(name, value)

    def export_config_dict(self):
        conf = super(Zone, self).export_config_dict()
        del conf["UNUSED"]
        return conf

    def _check_config(self, config, item, all_config):
        common_check_config(self, config, item, all_config)

        if item == "target":
            if config not in ZONE_TARGETS:
                raise FirewallError(errors.INVALID_TARGET, config)
        elif item == "interfaces":
            for interface in config:
                if not checkInterface(interface):
                    raise FirewallError(errors.INVALID_INTERFACE, interface)
                if self.fw_config:
                    for zone in self.fw_config.get_zones():
                        if zone == self.name:
                            continue
                        if interface in self.fw_config.get_zone(zone).interfaces:
                            raise FirewallError(errors.INVALID_INTERFACE,
                                    "interface '{}' already bound to zone '{}'".format(interface, zone))
        elif item == "sources":
            for source in config:
                if not checkIPnMask(source) and not checkIP6nMask(source) and \
                   not check_mac(source) and not source.startswith("ipset:"):
                    raise FirewallError(errors.INVALID_ADDR, source)
                if self.fw_config:
                    for zone in self.fw_config.get_zones():
                        if zone == self.name:
                            continue
                        if source in self.fw_config.get_zone(zone).sources:
                            raise FirewallError(errors.INVALID_ADDR,
                                    "source '{}' already bound to zone '{}'".format(source, zone))


    def check_name(self, name):
        super(Zone, self).check_name(name)
        if name.startswith('/'):
            raise FirewallError(errors.INVALID_NAME,
                                "'%s' can't start with '/'" % name)
        elif name.endswith('/'):
            raise FirewallError(errors.INVALID_NAME,
                                "'%s' can't end with '/'" % name)
        elif name.count('/') > 1:
            raise FirewallError(errors.INVALID_NAME,
                                "more than one '/' in '%s'" % name)
        else:
            if "/" in name:
                checked_name = name[:name.find('/')]
            else:
                checked_name = name
            if len(checked_name) > max_zone_name_len():
                raise FirewallError(errors.INVALID_NAME,
                                    "Zone of '%s' has %d chars, max is %d %s" % (
                                    name, len(checked_name),
                                    max_zone_name_len(),
                                    self.combined))
            if self.fw_config:
                if checked_name in self.fw_config.get_policy_objects():
                    raise FirewallError(errors.NAME_CONFLICT, "Zones can't have the same name as a policy.")

    def combine(self, zone):
        self.combined = True
        self.filename = None
        self.version = ""
        self.short = ""
        self.description = ""

        for interface in zone.interfaces:
            if interface not in self.interfaces:
                self.interfaces.append(interface)
        for source in zone.sources:
            if source not in self.sources:
                self.sources.append(source)
        for service in zone.services:
            if service not in self.services:
                self.services.append(service)
        for port in zone.ports:
            if port not in self.ports:
                self.ports.append(port)
        for proto in zone.protocols:
            if proto not in self.protocols:
                self.protocols.append(proto)
        for icmp in zone.icmp_blocks:
            if icmp not in self.icmp_blocks:
                self.icmp_blocks.append(icmp)
        if zone.forward:
            self.forward = True
        if zone.masquerade:
            self.masquerade = True
        for forward in zone.forward_ports:
            if forward not in self.forward_ports:
                self.forward_ports.append(forward)
        for port in zone.source_ports:
            if port not in self.source_ports:
                self.source_ports.append(port)
        for rule in zone.rules:
            self.rules.append(rule)
            self.rules_str.append(str(rule))
        if zone.icmp_block_inversion:
            self.icmp_block_inversion = True

# PARSER

class zone_ContentHandler(IO_Object_ContentHandler):
    def __init__(self, item):
        IO_Object_ContentHandler.__init__(self, item)
        self._rule = None
        self._rule_error = False
        self._limit_ok = None

    def startElement(self, name, attrs):
        IO_Object_ContentHandler.startElement(self, name, attrs)
        if self._rule_error:
            return

        self.item.parser_check_element_attrs(name, attrs)

        if common_startElement(self, name, attrs):
            return

        elif name == "zone":
            if "name" in attrs:
                log.warning("Ignoring deprecated attribute name='%s'",
                            attrs["name"])
            if "version" in attrs:
                self.item.version = attrs["version"]
            if "immutable" in attrs:
                log.warning("Ignoring deprecated attribute immutable='%s'",
                            attrs["immutable"])
            if "target" in attrs:
                target = attrs["target"]
                if target not in ZONE_TARGETS:
                    raise FirewallError(errors.INVALID_TARGET, target)
                if target != "" and target != DEFAULT_ZONE_TARGET:
                    self.item.target = target

        elif name == "forward":
            if self.item.forward:
                log.warning("Forward already set, ignoring.")
            else:
                self.item.forward = True

        elif name == "interface":
            if self._rule:
                log.warning('Invalid rule: interface use in rule.')
                self._rule_error = True
                return
            # zone bound to interface
            if "name" not in attrs:
                log.warning('Invalid interface: Name missing.')
                self._rule_error = True
                return
            if attrs["name"] not in self.item.interfaces:
                self.item.interfaces.append(attrs["name"])
            else:
                log.warning("Interface '%s' already set, ignoring.",
                            attrs["name"])

        elif name == "source":
            if self._rule:
                if self._rule.source:
                    log.warning("Invalid rule: More than one source in rule '%s', ignoring.",
                                str(self._rule))
                    self._rule_error = True
                    return
                invert = False
                if "invert" in attrs and \
                        attrs["invert"].lower() in [ "yes", "true" ]:
                    invert = True
                addr = mac = ipset = None
                if "address" in attrs:
                    addr = attrs["address"]
                if "mac" in attrs:
                    mac = attrs["mac"]
                if "ipset" in attrs:
                    ipset = attrs["ipset"]
                self._rule.source = rich.Rich_Source(addr, mac, ipset,
                                                     invert=invert)
                return
            # zone bound to source
            if "address" not in attrs and "ipset" not in attrs:
                log.warning('Invalid source: No address no ipset.')
                return
            if "address" in attrs and "ipset" in attrs:
                log.warning('Invalid source: Address and ipset.')
                return
            if "family" in attrs:
                log.warning("Ignoring deprecated attribute family='%s'",
                            attrs["family"])
            if "invert" in attrs:
                log.warning('Invalid source: Invertion not allowed here.')
                return
            if "address" in attrs:
                if not checkIPnMask(attrs["address"]) and \
                   not checkIP6nMask(attrs["address"]) and \
                   not check_mac(attrs["address"]):
                    raise FirewallError(errors.INVALID_ADDR, attrs["address"])
            if "ipset" in attrs:
                entry = "ipset:%s" % attrs["ipset"]
                if entry not in self.item.sources:
                    self.item.sources.append(entry)
                else:
                    log.warning("Source '%s' already set, ignoring.",
                                attrs["address"])
            if "address" in attrs:
                entry = attrs["address"]
                if entry not in self.item.sources:
                    self.item.sources.append(entry)
                else:
                    log.warning("Source '%s' already set, ignoring.",
                                attrs["address"])

        elif name == "icmp-block-inversion":
            if self.item.icmp_block_inversion:
                log.warning("Icmp-Block-Inversion already set, ignoring.")
            else:
                self.item.icmp_block_inversion = True

        else:
            log.warning("Unknown XML element '%s'", name)
            return

    def endElement(self, name):
        IO_Object_ContentHandler.endElement(self, name)

        common_endElement(self, name)

def zone_reader(filename, path, no_check_name=False):
    zone = Zone()
    if not filename.endswith(".xml"):
        raise FirewallError(errors.INVALID_NAME,
                            "'%s' is missing .xml suffix" % filename)
    zone.name = filename[:-4]
    if not no_check_name:
        zone.check_name(zone.name)
    zone.filename = filename
    zone.path = path
    zone.builtin = False if path.startswith(config.ETC_FIREWALLD) else True
    zone.default = zone.builtin
    handler = zone_ContentHandler(zone)
    parser = sax.make_parser()
    parser.setContentHandler(handler)
    name = "%s/%s" % (path, filename)
    with open(name, "rb") as f:
        source = sax.InputSource(None)
        source.setByteStream(f)
        try:
            parser.parse(source)
        except sax.SAXParseException as msg:
            raise FirewallError(errors.INVALID_ZONE,
                                "not a valid zone file: %s" % \
                                msg.getException())
    del handler
    del parser
    if PY2:
        zone.encode_strings()
    return zone

def zone_writer(zone, path=None):
    _path = path if path else zone.path

    if zone.filename:
        name = "%s/%s" % (_path, zone.filename)
    else:
        name = "%s/%s.xml" % (_path, zone.name)

    if os.path.exists(name):
        try:
            shutil.copy2(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)

    dirpath = os.path.dirname(name)
    if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath):
        if not os.path.exists(config.ETC_FIREWALLD):
            os.mkdir(config.ETC_FIREWALLD, 0o750)
        os.mkdir(dirpath, 0o750)

    f = io.open(name, mode='wt', encoding='UTF-8')
    handler = IO_Object_XMLGenerator(f)
    handler.startDocument()

    # start zone element
    attrs = {}
    if zone.version and zone.version != "":
        attrs["version"] = zone.version
    if zone.target != DEFAULT_ZONE_TARGET:
        attrs["target"] = zone.target
    handler.startElement("zone", attrs)
    handler.ignorableWhitespace("\n")

    common_writer(zone, handler)

    # interfaces
    for interface in uniqify(zone.interfaces):
        handler.ignorableWhitespace("  ")
        handler.simpleElement("interface", { "name": interface })
        handler.ignorableWhitespace("\n")

    # source
    for source in uniqify(zone.sources):
        handler.ignorableWhitespace("  ")
        if "ipset:" in source:
            handler.simpleElement("source", { "ipset": source[6:] })
        else:
            handler.simpleElement("source", { "address": source })
        handler.ignorableWhitespace("\n")

    # icmp-block-inversion
    if zone.icmp_block_inversion:
        handler.ignorableWhitespace("  ")
        handler.simpleElement("icmp-block-inversion", { })
        handler.ignorableWhitespace("\n")

    # forward
    if zone.forward:
        handler.ignorableWhitespace("  ")
        handler.simpleElement("forward", { })
        handler.ignorableWhitespace("\n")

    # end zone element
    handler.endElement("zone")
    handler.ignorableWhitespace("\n")
    handler.endDocument()
    f.close()
    del handler
core/io/firewalld_conf.py000064400000032774150351351720011452 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2012 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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.path
import io
import tempfile
import shutil

from firewall import config
from firewall.core.logger import log
from firewall.functions import b2u, u2b, PY2

valid_keys = [ "DefaultZone", "MinimalMark", "CleanupOnExit",
               "CleanupModulesOnExit", "Lockdown", "IPv6_rpfilter",
               "IndividualCalls", "LogDenied", "AutomaticHelpers",
               "FirewallBackend", "FlushAllOnReload", "RFC3964_IPv4",
               "AllowZoneDrifting" ]

class firewalld_conf(object):
    def __init__(self, filename):
        self._config = { }
        self._deleted = [ ]
        self.filename = filename
        self.clear()

    def clear(self):
        self._config = { }
        self._deleted = [ ]

    def cleanup(self):
        self._config.clear()
        self._deleted = [ ]

    def get(self, key):
        return self._config.get(key.strip())

    def set(self, key, value):
        _key = b2u(key.strip())
        self._config[_key] = b2u(value.strip())
        if _key in self._deleted:
            self._deleted.remove(_key)

    def __str__(self):
        s = ""
        for (key,value) in self._config.items():
            if s:
                s += '\n'
            s += '%s=%s' % (key, value)
        return u2b(s) if PY2 else s

    # load self.filename
    def read(self):
        self.clear()
        try:
            f = open(self.filename, "r")
        except Exception as msg:
            log.error("Failed to load '%s': %s", self.filename, msg)
            self.set("DefaultZone", config.FALLBACK_ZONE)
            self.set("MinimalMark", str(config.FALLBACK_MINIMAL_MARK))
            self.set("CleanupOnExit", "yes" if config.FALLBACK_CLEANUP_ON_EXIT else "no")
            self.set("CleanupModulesOnExit", "yes" if config.FALLBACK_CLEANUP_MODULES_ON_EXIT else "no")
            self.set("Lockdown", "yes" if config.FALLBACK_LOCKDOWN else "no")
            self.set("IPv6_rpfilter","yes" if config.FALLBACK_IPV6_RPFILTER else "no")
            self.set("IndividualCalls", "yes" if config.FALLBACK_INDIVIDUAL_CALLS else "no")
            self.set("LogDenied", config.FALLBACK_LOG_DENIED)
            self.set("AutomaticHelpers", config.FALLBACK_AUTOMATIC_HELPERS)
            self.set("FirewallBackend", config.FALLBACK_FIREWALL_BACKEND)
            self.set("FlushAllOnReload", "yes" if config.FALLBACK_FLUSH_ALL_ON_RELOAD else "no")
            self.set("RFC3964_IPv4", "yes" if config.FALLBACK_RFC3964_IPV4 else "no")
            self.set("AllowZoneDrifting", "yes" if config.FALLBACK_ALLOW_ZONE_DRIFTING else "no")
            raise

        for line in f:
            if not line:
                break
            line = line.strip()
            if len(line) < 1 or line[0] in ['#', ';']:
                continue
            # get key/value pair
            pair = [ x.strip() for x in line.split("=") ]
            if len(pair) != 2:
                log.error("Invalid option definition: '%s'", line.strip())
                continue
            elif pair[0] not in valid_keys:
                log.error("Invalid option: '%s'", line.strip())
                continue
            elif pair[1] == '':
                log.error("Missing value: '%s'", line.strip())
                continue
            elif self._config.get(pair[0]) is not None:
                log.error("Duplicate option definition: '%s'", line.strip())
                continue
            self._config[pair[0]] = pair[1]
        f.close()

        # check default zone
        if not self.get("DefaultZone"):
            log.error("DefaultZone is not set, using default value '%s'",
                      config.FALLBACK_ZONE)
            self.set("DefaultZone", str(config.FALLBACK_ZONE))

        # check minimal mark
        value = self.get("MinimalMark")
        try:
            int(value)
        except (ValueError, TypeError):
            if value is not None:
                log.warning("MinimalMark '%s' is not valid, using default "
                            "value '%d'", value if value else '',
                            config.FALLBACK_MINIMAL_MARK)
            self.set("MinimalMark", str(config.FALLBACK_MINIMAL_MARK))

        # check cleanup on exit
        value = self.get("CleanupOnExit")
        if not value or value.lower() not in [ "no", "false", "yes", "true" ]:
            if value is not None:
                log.warning("CleanupOnExit '%s' is not valid, using default "
                            "value %s", value if value else '',
                            config.FALLBACK_CLEANUP_ON_EXIT)
            self.set("CleanupOnExit", "yes" if config.FALLBACK_CLEANUP_ON_EXIT else "no")

        # check module cleanup on exit
        value = self.get("CleanupModulesOnExit")
        if not value or value.lower() not in [ "no", "false", "yes", "true" ]:
            if value is not None:
                log.warning("CleanupModulesOnExit '%s' is not valid, using default "
                            "value %s", value if value else '',
                            config.FALLBACK_CLEANUP_MODULES_ON_EXIT)
            self.set("CleanupModulesOnExit", "yes" if config.FALLBACK_CLEANUP_MODULES_ON_EXIT else "no")

        # check lockdown
        value = self.get("Lockdown")
        if not value or value.lower() not in [ "yes", "true", "no", "false" ]:
            if value is not None:
                log.warning("Lockdown '%s' is not valid, using default "
                            "value %s", value if value else '',
                            config.FALLBACK_LOCKDOWN)
            self.set("Lockdown", "yes" if config.FALLBACK_LOCKDOWN else "no")

        # check ipv6_rpfilter
        value = self.get("IPv6_rpfilter")
        if not value or value.lower() not in [ "yes", "true", "no", "false" ]:
            if value is not None:
                log.warning("IPv6_rpfilter '%s' is not valid, using default "
                            "value %s", value if value else '',
                            config.FALLBACK_IPV6_RPFILTER)
            self.set("IPv6_rpfilter","yes" if config.FALLBACK_IPV6_RPFILTER else "no")

        # check individual calls
        value = self.get("IndividualCalls")
        if not value or value.lower() not in [ "yes", "true", "no", "false" ]:
            if value is not None:
                log.warning("IndividualCalls '%s' is not valid, using default "
                            "value %s", value if value else '',
                            config.FALLBACK_INDIVIDUAL_CALLS)
            self.set("IndividualCalls", "yes" if config.FALLBACK_INDIVIDUAL_CALLS else "no")

        # check log denied
        value = self.get("LogDenied")
        if not value or value not in config.LOG_DENIED_VALUES:
            if value is not None:
                log.warning("LogDenied '%s' is invalid, using default value '%s'",
                            value, config.FALLBACK_LOG_DENIED)
            self.set("LogDenied", str(config.FALLBACK_LOG_DENIED))

        # check automatic helpers
        value = self.get("AutomaticHelpers")
        if not value or value.lower() not in config.AUTOMATIC_HELPERS_VALUES:
            if value is not None:
                log.warning("AutomaticHelpers '%s' is not valid, using default "
                            "value %s", value if value else '',
                            config.FALLBACK_AUTOMATIC_HELPERS)
            self.set("AutomaticHelpers", str(config.FALLBACK_AUTOMATIC_HELPERS))

        value = self.get("FirewallBackend")
        if not value or value.lower() not in config.FIREWALL_BACKEND_VALUES:
            if value is not None:
                log.warning("FirewallBackend '%s' is not valid, using default "
                            "value %s", value if value else '',
                            config.FALLBACK_FIREWALL_BACKEND)
            self.set("FirewallBackend", str(config.FALLBACK_FIREWALL_BACKEND))

        value = self.get("FlushAllOnReload")
        if not value or value.lower() not in [ "yes", "true", "no", "false" ]:
            if value is not None:
                log.warning("FlushAllOnReload '%s' is not valid, using default "
                            "value %s", value if value else '',
                            config.FALLBACK_FLUSH_ALL_ON_RELOAD)
            self.set("FlushAllOnReload", str(config.FALLBACK_FLUSH_ALL_ON_RELOAD))

        value = self.get("RFC3964_IPv4")
        if not value or value.lower() not in [ "yes", "true", "no", "false" ]:
            if value is not None:
                log.warning("RFC3964_IPv4 '%s' is not valid, using default "
                            "value %s", value if value else '',
                            config.FALLBACK_RFC3964_IPV4)
            self.set("RFC3964_IPv4", str(config.FALLBACK_RFC3964_IPV4))

        value = self.get("AllowZoneDrifting")
        if not value or value.lower() not in [ "yes", "true", "no", "false" ]:
            if value is not None:
                log.warning("AllowZoneDrifting '%s' is not valid, using default "
                            "value %s", value if value else '',
                            config.FALLBACK_ALLOW_ZONE_DRIFTING)
            self.set("AllowZoneDrifting", str(config.FALLBACK_ALLOW_ZONE_DRIFTING))

    # save to self.filename if there are key/value changes
    def write(self):
        if len(self._config) < 1:
            # no changes: nothing to do
            return

        # handled keys
        done = [ ]

        if not os.path.exists(config.ETC_FIREWALLD):
            os.mkdir(config.ETC_FIREWALLD, 0o750)

        try:
            temp_file = tempfile.NamedTemporaryFile(mode='wt',
                             prefix="%s." % os.path.basename(self.filename),
                             dir=os.path.dirname(self.filename), delete=False)
        except Exception as msg:
            log.error("Failed to open temporary file: %s" % msg)
            raise

        modified = False
        empty = False
        try:
            f= io.open(self.filename, mode='rt', encoding='UTF-8')
        except Exception as msg:
            if os.path.exists(self.filename):
                log.error("Failed to open '%s': %s" % (self.filename, msg))
                raise
            else:
                f = None
        else:
            for line in f:
                if not line:
                    break
                # remove newline
                line = line.strip("\n")

                if len(line) < 1:
                    if not empty:
                        temp_file.write(u"\n")
                        empty = True
                elif line[0] == '#':
                    empty = False
                    temp_file.write(line)
                    temp_file.write(u"\n")
                else:
                    p = line.split("=")
                    if len(p) != 2:
                        empty = False
                        temp_file.write(line+u"\n")
                        continue
                    key = p[0].strip()
                    value = p[1].strip()
                    # check for modified key/value pairs
                    if key not in done:
                        if (key in self._config and \
                                self._config[key] != value):
                            empty = False
                            temp_file.write(u'%s=%s\n' %
                                            (key, self._config[key]))
                            modified = True
                        elif key in self._deleted:
                            modified = True
                        else:
                            empty = False
                            temp_file.write(line+u"\n")
                        done.append(key)
                    else:
                        modified = True

        # write remaining key/value pairs
        if len(self._config) > 0:
            for (key,value) in self._config.items():
                if key in done:
                    continue
                if key in ["MinimalMark", "AutomaticHelpers"]: # omit deprecated from new config
                    continue
                if not empty:
                    temp_file.write(u"\n")
                    empty = True
                temp_file.write(u'%s=%s\n' % (key, value))
                modified = True

        if f:
            f.close()
        temp_file.close()

        if not modified: # not modified: remove tempfile
            os.remove(temp_file.name)
            return
        # make backup
        if os.path.exists(self.filename):
            try:
                shutil.copy2(self.filename, "%s.old" % self.filename)
            except Exception as msg:
                os.remove(temp_file.name)
                raise IOError("Backup of '%s' failed: %s" % (self.filename, msg))

        # copy tempfile
        try:
            shutil.move(temp_file.name, self.filename)
        except Exception as msg:
            os.remove(temp_file.name)
            raise IOError("Failed to create '%s': %s" % (self.filename, msg))
        else:
            os.chmod(self.filename, 0o600)
core/io/service.py000064400000031325150351351720010123 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "Service", "service_reader", "service_writer" ]

import xml.sax as sax
import os
import io
import shutil

from firewall import config
from firewall.functions import u2b_if_py2
from firewall.core.io.io_object import PY2, IO_Object, \
    IO_Object_ContentHandler, IO_Object_XMLGenerator, check_port, \
    check_tcpudp, check_protocol, check_address
from firewall.core.logger import log
from firewall import errors
from firewall.errors import FirewallError

class Service(IO_Object):
    IMPORT_EXPORT_STRUCTURE = (
        ( "version",  "" ),
        ( "short", "" ),
        ( "description", "" ),
        ( "ports", [ ( "", "" ), ], ),
        ( "modules", [ "", ], ),
        ( "destination", { "": "", }, ),
        ( "protocols", [ "", ], ),
        ( "source_ports", [ ( "", "" ), ], ),
        ( "includes", [ "" ], ),
        ( "helpers", [ "", ], ),
        )
    ADDITIONAL_ALNUM_CHARS = [ "_", "-" ]
    PARSER_REQUIRED_ELEMENT_ATTRS = {
        "short": None,
        "description": None,
        "service": None,
        }
    PARSER_OPTIONAL_ELEMENT_ATTRS = {
        "service": [ "name", "version" ],
        "port": [ "port", "protocol" ],
        "protocol": [ "value" ],
        "module": [ "name" ],
        "destination": [ "ipv4", "ipv6" ],
        "source-port": [ "port", "protocol" ],
        "include": [ "service" ],
        "helper": [ "name" ],
        }

    def __init__(self):
        super(Service, self).__init__()
        self.version = ""
        self.short = ""
        self.description = ""
        self.ports = [ ]
        self.protocols = [ ]
        self.modules = [ ]
        self.destination = { }
        self.source_ports = [ ]
        self.includes = [ ]
        self.helpers = [ ]

    def cleanup(self):
        self.version = ""
        self.short = ""
        self.description = ""
        del self.ports[:]
        del self.protocols[:]
        del self.modules[:]
        self.destination.clear()
        del self.source_ports[:]
        del self.includes[:]
        del self.helpers[:]

    def encode_strings(self):
        """ HACK. I haven't been able to make sax parser return
            strings encoded (because of python 2) instead of in unicode.
            Get rid of it once we throw out python 2 support."""
        self.version = u2b_if_py2(self.version)
        self.short = u2b_if_py2(self.short)
        self.description = u2b_if_py2(self.description)
        self.ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr) in self.ports]
        self.modules = [u2b_if_py2(m) for m in self.modules]
        self.destination = {u2b_if_py2(k):u2b_if_py2(v) for k,v in self.destination.items()}
        self.protocols = [u2b_if_py2(pr) for pr in self.protocols]
        self.source_ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr)
                             in self.source_ports]
        self.includes = [u2b_if_py2(s) for s in self.includes]
        self.helpers = [u2b_if_py2(s) for s in self.helpers]

    def _check_config(self, config, item, all_config):
        if item == "ports":
            for port in config:
                if port[0] != "":
                    check_port(port[0])
                    check_tcpudp(port[1])
                else:
                    # only protocol
                    check_protocol(port[1])

        elif item == "protocols":
            for proto in config:
                check_protocol(proto)

        elif item == "source_ports":
            for port in config:
                check_port(port[0])
                check_tcpudp(port[1])

        elif item == "destination":
            for destination in config:
                if destination not in [ "ipv4", "ipv6" ]:
                    raise FirewallError(errors.INVALID_DESTINATION,
                                        "'%s' not in {'ipv4'|'ipv6'}" % \
                                        destination)
                check_address(destination, config[destination])

        elif item == "modules":
            for module in config:
                if module.startswith("nf_conntrack_"):
                    module = module.replace("nf_conntrack_", "")
                    if "_" in module:
                        module = module.replace("_", "-")
                if len(module) < 2:
                    raise FirewallError(errors.INVALID_MODULE, module)

# PARSER

class service_ContentHandler(IO_Object_ContentHandler):
    def startElement(self, name, attrs):
        IO_Object_ContentHandler.startElement(self, name, attrs)
        self.item.parser_check_element_attrs(name, attrs)
        if name == "service":
            if "name" in attrs:
                log.warning("Ignoring deprecated attribute name='%s'",
                            attrs["name"])
            if "version" in attrs:
                self.item.version = attrs["version"]
        elif name == "short":
            pass
        elif name == "description":
            pass
        elif name == "port":
            if attrs["port"] != "":
                check_port(attrs["port"])
                check_tcpudp(attrs["protocol"])
                entry = (attrs["port"], attrs["protocol"])
                if entry not in self.item.ports:
                    self.item.ports.append(entry)
                else:
                    log.warning("Port '%s/%s' already set, ignoring.",
                                attrs["port"], attrs["protocol"])
            else:
                check_protocol(attrs["protocol"])
                if attrs["protocol"] not in self.item.protocols:
                    self.item.protocols.append(attrs["protocol"])
                else:
                    log.warning("Protocol '%s' already set, ignoring.",
                                attrs["protocol"])
        elif name == "protocol":
            check_protocol(attrs["value"])
            if attrs["value"] not in self.item.protocols:
                self.item.protocols.append(attrs["value"])
            else:
                log.warning("Protocol '%s' already set, ignoring.",
                            attrs["value"])
        elif name == "source-port":
            check_port(attrs["port"])
            check_tcpudp(attrs["protocol"])
            entry = (attrs["port"], attrs["protocol"])
            if entry not in self.item.source_ports:
                self.item.source_ports.append(entry)
            else:
                log.warning("SourcePort '%s/%s' already set, ignoring.",
                            attrs["port"], attrs["protocol"])
        elif name == "destination":
            for x in [ "ipv4", "ipv6" ]:
                if x in attrs:
                    check_address(x, attrs[x])
                    if x in self.item.destination:
                        log.warning("Destination address for '%s' already set, ignoring",
                                    x)
                    else:
                        self.item.destination[x] = attrs[x]
        elif name == "module":
            module = attrs["name"]
            if module.startswith("nf_conntrack_"):
                module = module.replace("nf_conntrack_", "")
                if "_" in module:
                    module = module.replace("_", "-")
            if module not in self.item.modules:
                self.item.modules.append(module)
            else:
                log.warning("Module '%s' already set, ignoring.",
                            module)
        elif name == "include":
            if attrs["service"] not in self.item.includes:
                self.item.includes.append(attrs["service"])
            else:
                log.warning("Include '%s' already set, ignoring.",
                            attrs["service"])
        elif name == "helper":
            if attrs["name"] not in self.item.helpers:
                self.item.helpers.append(attrs["name"])
            else:
                log.warning("Helper '%s' already set, ignoring.",
                            attrs["name"])


def service_reader(filename, path):
    service = Service()
    if not filename.endswith(".xml"):
        raise FirewallError(errors.INVALID_NAME,
                            "'%s' is missing .xml suffix" % filename)
    service.name = filename[:-4]
    service.check_name(service.name)
    service.filename = filename
    service.path = path
    service.builtin = False if path.startswith(config.ETC_FIREWALLD) else True
    service.default = service.builtin
    handler = service_ContentHandler(service)
    parser = sax.make_parser()
    parser.setContentHandler(handler)
    name = "%s/%s" % (path, filename)
    with open(name, "rb") as f:
        source = sax.InputSource(None)
        source.setByteStream(f)
        try:
            parser.parse(source)
        except sax.SAXParseException as msg:
            raise FirewallError(errors.INVALID_SERVICE,
                                "not a valid service file: %s" % \
                                msg.getException())
    del handler
    del parser
    if PY2:
        service.encode_strings()
    return service

def service_writer(service, path=None):
    _path = path if path else service.path

    if service.filename:
        name = "%s/%s" % (_path, service.filename)
    else:
        name = "%s/%s.xml" % (_path, service.name)

    if os.path.exists(name):
        try:
            shutil.copy2(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)

    dirpath = os.path.dirname(name)
    if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath):
        if not os.path.exists(config.ETC_FIREWALLD):
            os.mkdir(config.ETC_FIREWALLD, 0o750)
        os.mkdir(dirpath, 0o750)

    f = io.open(name, mode='wt', encoding='UTF-8')
    handler = IO_Object_XMLGenerator(f)
    handler.startDocument()

    # start service element
    attrs = {}
    if service.version and service.version != "":
        attrs["version"] = service.version
    handler.startElement("service", attrs)
    handler.ignorableWhitespace("\n")

    # short
    if service.short and service.short != "":
        handler.ignorableWhitespace("  ")
        handler.startElement("short", { })
        handler.characters(service.short)
        handler.endElement("short")
        handler.ignorableWhitespace("\n")

    # description
    if service.description and service.description != "":
        handler.ignorableWhitespace("  ")
        handler.startElement("description", { })
        handler.characters(service.description)
        handler.endElement("description")
        handler.ignorableWhitespace("\n")

    # ports
    for port in service.ports:
        handler.ignorableWhitespace("  ")
        handler.simpleElement("port", { "port": port[0], "protocol": port[1] })
        handler.ignorableWhitespace("\n")

    # protocols
    for protocol in service.protocols:
        handler.ignorableWhitespace("  ")
        handler.simpleElement("protocol", { "value": protocol })
        handler.ignorableWhitespace("\n")

    # source ports
    for port in service.source_ports:
        handler.ignorableWhitespace("  ")
        handler.simpleElement("source-port", { "port": port[0],
                                               "protocol": port[1] })
        handler.ignorableWhitespace("\n")

    # modules
    for module in service.modules:
        handler.ignorableWhitespace("  ")
        handler.simpleElement("module", { "name": module })
        handler.ignorableWhitespace("\n")

    # destination
    if len(service.destination) > 0:
        handler.ignorableWhitespace("  ")
        handler.simpleElement("destination", service.destination)
        handler.ignorableWhitespace("\n")

    # includes
    for include in service.includes:
        handler.ignorableWhitespace("  ")
        handler.simpleElement("include", { "service": include })
        handler.ignorableWhitespace("\n")

    # helpers
    for helper in service.helpers:
        handler.ignorableWhitespace("  ")
        handler.simpleElement("helper", { "name": helper })
        handler.ignorableWhitespace("\n")

    # end service element
    handler.endElement('service')
    handler.ignorableWhitespace("\n")
    handler.endDocument()
    f.close()
    del handler
core/prog.py000064400000002746150351351720007030 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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 subprocess


__all__ = ["runProg"]


def runProg(prog, argv=None, stdin=None):
    if argv is None:
        argv = []

    args = [prog] + argv

    input_string = None
    if stdin:
        with open(stdin, 'r') as handle:
            input_string = handle.read().encode()

    env = {'LANG': 'C'}
    try:
        process = subprocess.Popen(args, stdin=subprocess.PIPE,
                                   stderr=subprocess.STDOUT,
                                   stdout=subprocess.PIPE,
                                   close_fds=True, env=env)
    except OSError:
        return (255, '')

    (output, err_output) = process.communicate(input_string)
    output = output.decode('utf-8', 'replace')
    return (process.returncode, output)
core/fw_zone.py000064400000131171150351351720007523 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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 time
import copy
from firewall.core.base import SHORTCUTS, DEFAULT_ZONE_TARGET, SOURCE_IPSET_TYPES
from firewall.core.fw_transaction import FirewallTransaction
from firewall.core.io.policy import Policy
from firewall.core.logger import log
from firewall.core.rich import Rich_Service, Rich_Port, Rich_Protocol, Rich_SourcePort, Rich_ForwardPort, \
                               Rich_IcmpBlock, Rich_IcmpType, Rich_Masquerade, Rich_Mark
from firewall.functions import checkIPnMask, checkIP6nMask, check_mac
from firewall import errors
from firewall.errors import FirewallError
from firewall.fw_types import LastUpdatedOrderedDict

class FirewallZone(object):
    ZONE_POLICY_PRIORITY = 0

    def __init__(self, fw):
        self._fw = fw
        self._zones = { }
        self._zone_policies = { }

    def __repr__(self):
        return '%s(%r)' % (self.__class__, self._zones)

    def cleanup(self):
        self._zones.clear()
        self._zone_policies.clear()

    def new_transaction(self):
        return FirewallTransaction(self._fw)

    def policy_name_from_zones(self, fromZone, toZone):
        return "zone_{fromZone}_{toZone}".format(fromZone=fromZone, toZone=toZone)

    # zones

    def get_zones(self):
        return sorted(self._zones.keys())

    def get_active_zones(self):
        active_zones = []
        for zone in self.get_zones():
            if self.list_interfaces(zone) or self.list_sources(zone):
                active_zones.append(zone)
        return active_zones

    def get_zone_of_interface(self, interface):
        interface_id = self.__interface_id(interface)
        for zone in self._zones:
            if interface_id in self._zones[zone].settings["interfaces"]:
                # an interface can only be part of one zone
                return zone
        return None

    def get_zone_of_source(self, source):
        source_id = self.__source_id(source)
        for zone in self._zones:
            if source_id in self._zones[zone].settings["sources"]:
                # a source_id can only be part of one zone
                return zone
        return None

    def get_zone(self, zone):
        z = self._fw.check_zone(zone)
        return self._zones[z]

    def policy_obj_from_zone_obj(self, z_obj, fromZone, toZone):
        p_obj = Policy()
        p_obj.derived_from_zone = z_obj.name
        p_obj.name = self.policy_name_from_zones(fromZone, toZone)
        p_obj.priority = self.ZONE_POLICY_PRIORITY
        p_obj.target = z_obj.target
        p_obj.ingress_zones = [fromZone]
        p_obj.egress_zones = [toZone]

        # copy zone permanent config to policy permanent config
        # WARN: This assumes the same attribute names.
        #
        for setting in ["services", "ports",
                        "masquerade", "forward_ports",
                        "source_ports",
                        "icmp_blocks", "rules",
                        "protocols"]:
            if fromZone == z_obj.name and toZone == "HOST" and \
               setting in ["services", "ports", "source_ports", "icmp_blocks", "protocols"]:
                # zone --> HOST
                setattr(p_obj, setting, copy.deepcopy(getattr(z_obj, setting)))
            elif fromZone == "ANY" and toZone == z_obj.name and setting in ["masquerade"]:
                # any zone --> zone
                setattr(p_obj, setting, copy.deepcopy(getattr(z_obj, setting)))
            elif fromZone == z_obj.name and toZone == "ANY" and \
                 setting in ["icmp_blocks", "forward_ports"]:
                # zone --> any zone
                setattr(p_obj, setting, copy.deepcopy(getattr(z_obj, setting)))
            elif setting in ["rules"]:
                p_obj.rules = []
                for rule in z_obj.rules:
                    current_policy = self.policy_name_from_zones(fromZone, toZone)

                    if current_policy in self._rich_rule_to_policies(z_obj.name, rule):
                        p_obj.rules.append(copy.deepcopy(rule))

        return p_obj

    def add_zone(self, obj):
        obj.settings = { x : LastUpdatedOrderedDict()
                         for x in ["interfaces", "sources",
                                   "icmp_block_inversion",
                                   "forward"] }
        self._zones[obj.name] = obj
        self._zone_policies[obj.name] = []

        # Create policy objects, will need many:
        #   - (zone --> HOST) - ports, service, etc
        #   - (any zone --> zone) - masquerade
        #   - (zone --> any zone) - ICMP block, icmp block inversion
        #       - also includes forward-ports because it works on (nat,
        #       PREROUTING) and therefore applies to redirects to the local
        #       host or dnat to a different host.
        #       - also includes rich rule "mark" action for the same reason
        #
        for fromZone,toZone in [(obj.name, "HOST"),
                                ("ANY", obj.name), (obj.name, "ANY")]:
            p_obj = self.policy_obj_from_zone_obj(obj, fromZone, toZone)
            self._fw.policy.add_policy(p_obj)
            self._zone_policies[obj.name].append(p_obj.name)

        self.copy_permanent_to_runtime(obj.name)

    def copy_permanent_to_runtime(self, zone):
        obj = self._zones[zone]

        for arg in obj.interfaces:
            self.add_interface(zone, arg, allow_apply=False)
        for arg in obj.sources:
            self.add_source(zone, arg, allow_apply=False)
        if obj.forward:
            self.add_forward(zone)
        if obj.icmp_block_inversion:
            self.add_icmp_block_inversion(zone)

    def remove_zone(self, zone):
        obj = self._zones[zone]
        if obj.applied:
            self.unapply_zone_settings(zone)
        obj.settings.clear()
        del self._zones[zone]
        del self._zone_policies[zone]

    def apply_zones(self, use_transaction=None):
        for zone in self.get_zones():
            z_obj = self._zones[zone]
            if len(z_obj.interfaces) > 0 or len(z_obj.sources) > 0:
                log.debug1("Applying zone '%s'", zone)
                self.apply_zone_settings(zone, use_transaction=use_transaction)

    def set_zone_applied(self, zone, applied):
        obj = self._zones[zone]
        obj.applied = applied

    # zone from chain

    def zone_from_chain(self, chain):
        if "_" not in chain:
            # no zone chain
            return None
        splits = chain.split("_")
        if len(splits) < 2:
            return None
        _chain = None
        for x in SHORTCUTS:
            if splits[0] == SHORTCUTS[x]:
                _chain = x
        if _chain is not None:
            # next part needs to be zone name
            if splits[1] not in self.get_zones():
                return None
            if len(splits) == 2 or \
               (len(splits) == 3 and splits[2] in [ "pre", "log", "deny", "allow", "post" ]):
                return (splits[1], _chain)
        return None

    def policy_from_chain(self, chain):
        x = self.zone_from_chain(chain)
        if x is None:
            return None

        (zone, _chain) = x
        # derived from _get_table_chains_for_zone_dispatch()
        if _chain in ["PREROUTING", "FORWARD_IN"]:
            fromZone = zone
            toZone = "ANY"
        elif _chain in ["INPUT"]:
            fromZone = zone
            toZone = "HOST"
        elif _chain in ["POSTROUTING", "FORWARD_OUT"]:
            fromZone = "ANY"
            toZone = zone
        else:
            raise FirewallError(errors.INVALID_CHAIN, "chain '%s' can't be mapped to a policy" % (chain))

        return (self.policy_name_from_zones(fromZone, toZone), _chain)

    def create_zone_base_by_chain(self, ipv, table, chain,
                                  use_transaction=None):

        # Create zone base chains if the chain is reserved for a zone
        if ipv in [ "ipv4", "ipv6" ]:
            x = self.policy_from_chain(chain)
            if x is not None:
                (policy, _chain) = self.policy_from_chain(chain)
                if use_transaction is None:
                    transaction = self.new_transaction()
                else:
                    transaction = use_transaction

                self._fw.policy.gen_chain_rules(policy, True, table, _chain,
                                                transaction)

                if use_transaction is None:
                    transaction.execute(True)

    # settings

    # generate settings record with sender, timeout
    def __gen_settings(self, timeout, sender):
        ret = {
            "date": time.time(),
            "sender": sender,
            "timeout": timeout,
        }
        return ret

    def get_settings(self, zone):
        return self.get_zone(zone).settings

    def _zone_settings(self, enable, zone, transaction):
        settings = self.get_settings(zone)
        for key in settings:
            for args in settings[key]:
                if key == "interfaces":
                    self._interface(enable, zone, args, transaction)
                elif key == "sources":
                    self._source(enable, zone, args[0], args[1], transaction)
                elif key == "icmp_block_inversion":
                    continue
                elif key == "forward":
                    # no need to call this when applying the zone as the rules
                    # will be generated when adding the interfaces/sources
                    pass
                else:
                    log.warning("Zone '%s': Unknown setting '%s:%s', "
                                "unable to apply", zone, key, args)
        # ICMP-block-inversion is always applied
        if enable:
            self._icmp_block_inversion(enable, zone, transaction)

    def apply_zone_settings(self, zone, use_transaction=None):
        _zone = self._fw.check_zone(zone)
        obj = self._zones[_zone]
        if obj.applied:
            return
        obj.applied = True

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        for policy in self._zone_policies[_zone]:
            log.debug1("Applying policy (%s) derived from zone '%s'", policy, zone)
            self._fw.policy.apply_policy_settings(policy, use_transaction=transaction)

        self._zone_settings(True, _zone, transaction)

        if use_transaction is None:
            transaction.execute(True)

    def unapply_zone_settings(self, zone, use_transaction=None):
        _zone = self._fw.check_zone(zone)
        obj = self._zones[_zone]
        if not obj.applied:
            return

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        for policy in self._zone_policies[_zone]:
            self._fw.policy.unapply_policy_settings(policy, use_transaction=transaction)

        self._zone_settings(False, _zone, transaction)

        if use_transaction is None:
            transaction.execute(True)

    def get_config_with_settings(self, zone):
        """
        :return: exported config updated with runtime settings
        """
        obj = self.get_zone(zone)
        conf_dict = self.get_config_with_settings_dict(zone)
        conf_list = []
        for i in range(16): # tuple based API has 16 elements
            if obj.IMPORT_EXPORT_STRUCTURE[i][0] not in conf_dict:
                # old API needs the empty elements as well. Grab it from the
                # class otherwise we don't know the type.
                conf_list.append(copy.deepcopy(getattr(obj, obj.IMPORT_EXPORT_STRUCTURE[i][0])))
            else:
                conf_list.append(conf_dict[obj.IMPORT_EXPORT_STRUCTURE[i][0]])
        return tuple(conf_list)

    def get_config_with_settings_dict(self, zone):
        """
        :return: exported config updated with runtime settings
        """
        permanent = self.get_zone(zone).export_config_dict()
        if permanent["target"] == DEFAULT_ZONE_TARGET:
            permanent["target"] = "default"
        runtime = { "services": self.list_services(zone),
                    "ports": self.list_ports(zone),
                    "icmp_blocks": self.list_icmp_blocks(zone),
                    "masquerade": self.query_masquerade(zone),
                    "forward_ports": self.list_forward_ports(zone),
                    "interfaces": self.list_interfaces(zone),
                    "sources": self.list_sources(zone),
                    "rules_str": self.list_rules(zone),
                    "protocols": self.list_protocols(zone),
                    "source_ports": self.list_source_ports(zone),
                    "icmp_block_inversion": self.query_icmp_block_inversion(zone),
                    "forward": self.query_forward(zone),
                    }
        return self._fw.combine_runtime_with_permanent_settings(permanent, runtime)

    def set_config_with_settings_dict(self, zone, settings, sender):
        # stupid wrappers to convert rich rule string to rich rule object
        from firewall.core.rich import Rich_Rule
        def add_rule_wrapper(zone, rule_str, timeout=0, sender=None):
            self.add_rule(zone, Rich_Rule(rule_str=rule_str), timeout=0, sender=sender)
        def remove_rule_wrapper(zone, rule_str):
            self.remove_rule(zone, Rich_Rule(rule_str=rule_str))

        setting_to_fn = {
            "services": (self.add_service, self.remove_service),
            "ports": (self.add_port, self.remove_port),
            "icmp_blocks": (self.add_icmp_block, self.remove_icmp_block),
            "masquerade": (self.add_masquerade, self.remove_masquerade),
            "forward_ports": (self.add_forward_port, self.remove_forward_port),
            "interfaces": (self.add_interface, self.remove_interface),
            "sources": (self.add_source, self.remove_source),
            "rules_str": (add_rule_wrapper, remove_rule_wrapper),
            "protocols": (self.add_protocol, self.remove_protocol),
            "source_ports": (self.add_source_port, self.remove_source_port),
            "icmp_block_inversion": (self.add_icmp_block_inversion, self.remove_icmp_block_inversion),
            "forward": (self.add_forward, self.remove_forward),
        }

        old_settings = self.get_config_with_settings_dict(zone)
        (add_settings, remove_settings) = self._fw.get_added_and_removed_settings(old_settings, settings)

        for key in remove_settings:
            if isinstance(remove_settings[key], list):
                for args in remove_settings[key]:
                    if isinstance(args, tuple):
                        setting_to_fn[key][1](zone, *args)
                    else:
                        setting_to_fn[key][1](zone, args)
            else: # bool
                setting_to_fn[key][1](zone)

        for key in add_settings:
            if isinstance(add_settings[key], list):
                for args in add_settings[key]:
                    if key in ["interfaces", "sources"]:
                        # no timeout arg
                        setting_to_fn[key][0](zone, args, sender=sender)
                    else:
                        if isinstance(args, tuple):
                            setting_to_fn[key][0](zone, *args, timeout=0, sender=sender)
                        else:
                            setting_to_fn[key][0](zone, args, timeout=0, sender=sender)
            else: # bool
                if key in ["icmp_block_inversion"]:
                    # no timeout arg
                    setting_to_fn[key][0](zone, sender=sender)
                else:
                    setting_to_fn[key][0](zone, timeout=0, sender=sender)

    # INTERFACES

    def check_interface(self, interface):
        self._fw.check_interface(interface)

    def interface_get_sender(self, zone, interface):
        _zone = self._fw.check_zone(zone)
        _obj = self._zones[_zone]
        interface_id = self.__interface_id(interface)

        if interface_id in _obj.settings["interfaces"]:
            settings = _obj.settings["interfaces"][interface_id]
            if "sender" in settings and settings["sender"] is not None:
                return settings["sender"]

        return None

    def __interface_id(self, interface):
        self.check_interface(interface)
        return interface

    def add_interface(self, zone, interface, sender=None,
                      use_transaction=None, allow_apply=True):
        self._fw.check_panic()
        _zone = self._fw.check_zone(zone)
        _obj = self._zones[_zone]

        interface_id = self.__interface_id(interface)

        if interface_id in _obj.settings["interfaces"]:
            raise FirewallError(errors.ZONE_ALREADY_SET,
                                "'%s' already bound to '%s'" % (interface,
                                                                zone))
        if self.get_zone_of_interface(interface) is not None:
            raise FirewallError(errors.ZONE_CONFLICT,
                                "'%s' already bound to a zone" % interface)

        log.debug1("Setting zone of interface '%s' to '%s'" % (interface,
                                                               _zone))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if not _obj.applied and allow_apply:
            self.apply_zone_settings(zone,
                                     use_transaction=transaction)
            transaction.add_fail(self.set_zone_applied, _zone, False)

        if allow_apply:
            self._interface(True, _zone, interface, transaction)

        self.__register_interface(_obj, interface_id, zone, sender)
        transaction.add_fail(self.__unregister_interface, _obj,
                                  interface_id)

        if use_transaction is None:
            transaction.execute(True)

        return _zone

    def __register_interface(self, _obj, interface_id, zone, sender):
        _obj.settings["interfaces"][interface_id] = \
            self.__gen_settings(0, sender)
        # add information whether we add to default or specific zone
        _obj.settings["interfaces"][interface_id]["__default__"] = \
            (not zone or zone == "")

    def change_zone_of_interface(self, zone, interface, sender=None):
        self._fw.check_panic()
        _old_zone = self.get_zone_of_interface(interface)
        _new_zone = self._fw.check_zone(zone)

        if _new_zone == _old_zone:
            return _old_zone

        if _old_zone is not None:
            self.remove_interface(_old_zone, interface)

        _zone = self.add_interface(zone, interface, sender)

        return _zone

    def change_default_zone(self, old_zone, new_zone, use_transaction=None):
        self._fw.check_panic()

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        self.apply_zone_settings(new_zone, transaction)
        self._interface(True, new_zone, "+", transaction, append=True)
        if old_zone is not None and old_zone != "":
            self._interface(False, old_zone, "+", transaction, append=True)

        if use_transaction is None:
            transaction.execute(True)

    def remove_interface(self, zone, interface,
                         use_transaction=None):
        self._fw.check_panic()
        zoi = self.get_zone_of_interface(interface)
        if zoi is None:
            raise FirewallError(errors.UNKNOWN_INTERFACE,
                                "'%s' is not in any zone" % interface)
        _zone = zoi if zone == "" else self._fw.check_zone(zone)
        if zoi != _zone:
            raise FirewallError(errors.ZONE_CONFLICT,
                                "remove_interface(%s, %s): zoi='%s'" % \
                                (zone, interface, zoi))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        _obj = self._zones[_zone]
        interface_id = self.__interface_id(interface)
        transaction.add_post(self.__unregister_interface, _obj, interface_id)
        self._interface(False, _zone, interface, transaction)

        if use_transaction is None:
            transaction.execute(True)

        return _zone

    def __unregister_interface(self, _obj, interface_id):
        if interface_id in _obj.settings["interfaces"]:
            del _obj.settings["interfaces"][interface_id]

    def query_interface(self, zone, interface):
        return self.__interface_id(interface) in self.get_settings(zone)["interfaces"]

    def list_interfaces(self, zone):
        return self.get_settings(zone)["interfaces"].keys()

    # SOURCES

    def check_source(self, source, applied=False):
        if checkIPnMask(source):
            return "ipv4"
        elif checkIP6nMask(source):
            return "ipv6"
        elif check_mac(source):
            return ""
        elif source.startswith("ipset:"):
            self._check_ipset_type_for_source(source[6:])
            if applied:
                self._check_ipset_applied(source[6:])
            return self._ipset_family(source[6:])
        else:
            raise FirewallError(errors.INVALID_ADDR, source)

    def __source_id(self, source, applied=False):
        ipv = self.check_source(source, applied=applied)
        return (ipv, source)

    def add_source(self, zone, source, sender=None, use_transaction=None,
                   allow_apply=True):
        self._fw.check_panic()
        _zone = self._fw.check_zone(zone)
        _obj = self._zones[_zone]

        if check_mac(source):
            source = source.upper()

        source_id = self.__source_id(source, applied=allow_apply)

        if source_id in _obj.settings["sources"]:
            raise FirewallError(errors.ZONE_ALREADY_SET,
                            "'%s' already bound to '%s'" % (source, _zone))
        if self.get_zone_of_source(source) is not None:
            raise FirewallError(errors.ZONE_CONFLICT,
                                "'%s' already bound to a zone" % source)

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if not _obj.applied and allow_apply:
            self.apply_zone_settings(zone,
                                     use_transaction=transaction)
            transaction.add_fail(self.set_zone_applied, _zone, False)

        if allow_apply:
            self._source(True, _zone, source_id[0], source_id[1], transaction)

        self.__register_source(_obj, source_id, zone, sender)
        transaction.add_fail(self.__unregister_source, _obj, source_id)

        if use_transaction is None:
            transaction.execute(True)

        return _zone

    def __register_source(self, _obj, source_id, zone, sender):
        _obj.settings["sources"][source_id] = \
            self.__gen_settings(0, sender)
        # add information whether we add to default or specific zone
        _obj.settings["sources"][source_id]["__default__"] = (not zone or zone == "")

    def change_zone_of_source(self, zone, source, sender=None):
        self._fw.check_panic()
        _old_zone = self.get_zone_of_source(source)
        _new_zone = self._fw.check_zone(zone)

        if _new_zone == _old_zone:
            return _old_zone

        if check_mac(source):
            source = source.upper()

        if _old_zone is not None:
            self.remove_source(_old_zone, source)

        _zone = self.add_source(zone, source, sender)

        return _zone

    def remove_source(self, zone, source,
                      use_transaction=None):
        self._fw.check_panic()
        if check_mac(source):
            source = source.upper()
        zos = self.get_zone_of_source(source)
        if zos is None:
            raise FirewallError(errors.UNKNOWN_SOURCE,
                                "'%s' is not in any zone" % source)
        _zone = zos if zone == "" else self._fw.check_zone(zone)
        if zos != _zone:
            raise FirewallError(errors.ZONE_CONFLICT,
                                "remove_source(%s, %s): zos='%s'" % \
                                (zone, source, zos))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        _obj = self._zones[_zone]
        source_id = self.__source_id(source)
        transaction.add_post(self.__unregister_source, _obj, source_id)
        self._source(False, _zone, source_id[0], source_id[1], transaction)

        if use_transaction is None:
            transaction.execute(True)

        return _zone

    def __unregister_source(self, _obj, source_id):
        if source_id in _obj.settings["sources"]:
            del _obj.settings["sources"][source_id]

    def query_source(self, zone, source):
        if check_mac(source):
            source = source.upper()
        return self.__source_id(source) in self.get_settings(zone)["sources"]

    def list_sources(self, zone):
        return [ k[1] for k in self.get_settings(zone)["sources"].keys() ]

    def _interface(self, enable, zone, interface, transaction, append=False):
        for backend in self._fw.enabled_backends():
            if not backend.policies_supported:
                continue
            for policy in self._zone_policies[zone]:
                for (table, chain) in self._fw.policy._get_table_chains_for_zone_dispatch(policy):
                    rules = backend.build_zone_source_interface_rules(enable,
                                    zone, policy, interface, table, chain, append)
                    transaction.add_rules(backend, rules)

            # intra zone forward
            policy = self.policy_name_from_zones(zone, "ANY")
            # Skip adding wildcard/catch-all interface (for default
            # zone). Otherwise it would allow forwarding from interface
            # in default zone -> interface not in default zone (but in
            # a different zone).
            if self.get_settings(zone)["forward"] and interface not in ["+", "*"]:
                rules = backend.build_zone_forward_rules(enable, zone, policy, "filter", interface=interface)
                transaction.add_rules(backend, rules)

        # update policy dispatch for any policy using this zone in ingress
        # or egress
        for policy in self._fw.policy.get_policies_not_derived_from_zone():
            if zone not in self._fw.policy.list_ingress_zones(policy) and \
               zone not in self._fw.policy.list_egress_zones(policy):
                continue
            if policy in self._fw.policy.get_active_policies_not_derived_from_zone() and self._fw.policy.get_policy(policy).applied:
                # first remove the old set of interfaces using the current zone
                # settings.
                if not enable and len(self.list_interfaces(zone)) == 1:
                    self._fw.policy.unapply_policy_settings(policy, use_transaction=transaction)
                else:
                    self._fw.policy._ingress_egress_zones(False, policy, transaction)
                    # after the transaction ends and therefore the interface
                    # has been added to the zone's settings, update the
                    # dependent policies
                    transaction.add_post(lambda p: (p in self._fw.policy.get_active_policies_not_derived_from_zone()) and \
                                                   self._fw.policy._ingress_egress_zones_transaction(True, p), policy)
            elif enable:
                transaction.add_post(lambda p: (p in self._fw.policy.get_active_policies_not_derived_from_zone()) and \
                                               self._fw.policy.apply_policy_settings(p), policy)

    # IPSETS

    def _ipset_family(self, name):
        if self._ipset_type(name) == "hash:mac":
            return None
        return self._fw.ipset.get_family(name, applied=False)

    def _ipset_type(self, name):
        return self._fw.ipset.get_type(name, applied=False)

    def _ipset_match_flags(self, name, flag):
        return ",".join([flag] * self._fw.ipset.get_dimension(name))

    def _check_ipset_applied(self, name):
        return self._fw.ipset.check_applied(name)

    def _check_ipset_type_for_source(self, name):
        _type = self._ipset_type(name)
        if _type not in SOURCE_IPSET_TYPES:
            raise FirewallError(
                errors.INVALID_IPSET,
                "ipset '%s' with type '%s' not usable as source" % \
                (name, _type))

    def _source(self, enable, zone, ipv, source, transaction):
        # For mac source bindings ipv is an empty string, the mac source will
        # be added for ipv4 and ipv6
        for backend in [self._fw.get_backend_by_ipv(ipv)] if ipv else self._fw.enabled_backends():
            if not backend.policies_supported:
                continue
            for policy in self._zone_policies[zone]:
                for (table, chain) in self._fw.policy._get_table_chains_for_zone_dispatch(policy):
                    rules = backend.build_zone_source_address_rules(enable, zone,
                                            policy, source, table, chain)
                    transaction.add_rules(backend, rules)

            # intra zone forward
            policy = self.policy_name_from_zones(zone, "ANY")
            if self.get_settings(zone)["forward"]:
                rules = backend.build_zone_forward_rules(enable, zone, policy, "filter", source=source)
                transaction.add_rules(backend, rules)

        # update policy dispatch for any policy using this zone in ingress
        # or egress
        for policy in self._fw.policy.get_policies_not_derived_from_zone():
            if zone not in self._fw.policy.list_ingress_zones(policy) and \
               zone not in self._fw.policy.list_egress_zones(policy):
                continue
            if policy in self._fw.policy.get_active_policies_not_derived_from_zone() and self._fw.policy.get_policy(policy).applied:
                # first remove the old set of sources using the current zone
                # settings.
                if not enable and len(self.list_sources(zone)) == 1:
                    self._fw.policy.unapply_policy_settings(policy, use_transaction=transaction)
                else:
                    self._fw.policy._ingress_egress_zones(False, policy, transaction)
                    # after the transaction ends and therefore the sources
                    # has been added to the zone's settings, update the
                    # dependent policies
                    transaction.add_post(lambda p: (p in self._fw.policy.get_active_policies_not_derived_from_zone()) and \
                                                   self._fw.policy._ingress_egress_zones_transaction(True, p), policy)
            elif enable:
                transaction.add_post(lambda p: (p in self._fw.policy.get_active_policies_not_derived_from_zone()) and \
                                               self._fw.policy.apply_policy_settings(p), policy)

    def add_service(self, zone, service, timeout=0, sender=None):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.add_service(p_name, service, timeout, sender)
        return zone

    def remove_service(self, zone, service):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.remove_service(p_name, service)
        return zone

    def query_service(self, zone, service):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        return self._fw.policy.query_service(p_name, service)

    def list_services(self, zone):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        return self._fw.policy.list_services(p_name)

    def add_port(self, zone, port, protocol, timeout=0, sender=None):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.add_port(p_name, port, protocol, timeout, sender)
        return zone

    def remove_port(self, zone, port, protocol):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.remove_port(p_name, port, protocol)
        return zone

    def query_port(self, zone, port, protocol):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        return self._fw.policy.query_port(p_name, port, protocol)

    def list_ports(self, zone):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        return self._fw.policy.list_ports(p_name)

    def add_source_port(self, zone, source_port, protocol, timeout=0, sender=None):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.add_source_port(p_name, source_port, protocol, timeout, sender)
        return zone

    def remove_source_port(self, zone, source_port, protocol):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.remove_source_port(p_name, source_port, protocol)
        return zone

    def query_source_port(self, zone, source_port, protocol):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        return self._fw.policy.query_source_port(p_name, source_port, protocol)

    def list_source_ports(self, zone):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        return self._fw.policy.list_source_ports(p_name)

    def _rich_rule_to_policies(self, zone, rule):
        zone = self._fw.check_zone(zone)
        if type(rule.action) == Rich_Mark:
            return [self.policy_name_from_zones(zone, "ANY")]
        elif type(rule.element) in [Rich_Service, Rich_Port, Rich_Protocol,
                                    Rich_SourcePort]:
            return [self.policy_name_from_zones(zone, "HOST")]
        elif type(rule.element) in [Rich_IcmpBlock, Rich_IcmpType]:
            return [self.policy_name_from_zones(zone, "HOST"),
                    self.policy_name_from_zones(zone, "ANY")]
        elif type(rule.element) in [Rich_ForwardPort]:
            return [self.policy_name_from_zones(zone, "ANY")]
        elif type(rule.element) in [Rich_Masquerade]:
            return [self.policy_name_from_zones("ANY", zone)]
        elif rule.element is None:
            return [self.policy_name_from_zones(zone, "HOST")]
        else:
            raise FirewallError("Rich rule type (%s) not handled." % (type(rule.element)))

    def add_rule(self, zone, rule, timeout=0, sender=None):
        for p_name in self._rich_rule_to_policies(zone, rule):
            self._fw.policy.add_rule(p_name, rule, timeout, sender)
        return zone

    def remove_rule(self, zone, rule):
        for p_name in self._rich_rule_to_policies(zone, rule):
            self._fw.policy.remove_rule(p_name, rule)
        return zone

    def query_rule(self, zone, rule):
        ret = True
        for p_name in self._rich_rule_to_policies(zone, rule):
            ret = ret and self._fw.policy.query_rule(p_name, rule)
        return ret

    def list_rules(self, zone):
        zone = self._fw.check_zone(zone)
        ret = set()
        for p_name in [self.policy_name_from_zones(zone, "ANY"),
                       self.policy_name_from_zones(zone, "HOST"),
                       self.policy_name_from_zones("ANY", zone)]:
            ret.update(set(self._fw.policy.list_rules(p_name)))
        return list(ret)

    def add_protocol(self, zone, protocol, timeout=0, sender=None):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.add_protocol(p_name, protocol, timeout, sender)
        return zone

    def remove_protocol(self, zone, protocol):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.remove_protocol(p_name, protocol)
        return zone

    def query_protocol(self, zone, protocol):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        return self._fw.policy.query_protocol(p_name, protocol)

    def list_protocols(self, zone):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        return self._fw.policy.list_protocols(p_name)

    def add_masquerade(self, zone, timeout=0, sender=None):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones("ANY", zone)
        self._fw.policy.add_masquerade(p_name, timeout, sender)
        return zone

    def remove_masquerade(self, zone):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones("ANY", zone)
        self._fw.policy.remove_masquerade(p_name)
        return zone

    def query_masquerade(self, zone):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones("ANY", zone)
        return self._fw.policy.query_masquerade(p_name)

    def add_forward_port(self, zone, port, protocol, toport=None,
                         toaddr=None, timeout=0, sender=None):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "ANY")
        self._fw.policy.add_forward_port(p_name, port, protocol, toport, toaddr,
                                         timeout, sender)
        return zone

    def remove_forward_port(self, zone, port, protocol, toport=None,
                            toaddr=None):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "ANY")
        self._fw.policy.remove_forward_port(p_name, port, protocol, toport, toaddr)
        return zone

    def query_forward_port(self, zone, port, protocol, toport=None,
                           toaddr=None):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "ANY")
        return self._fw.policy.query_forward_port(p_name, port, protocol, toport,
                                                  toaddr)

    def list_forward_ports(self, zone):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "ANY")
        return self._fw.policy.list_forward_ports(p_name)

    def add_icmp_block(self, zone, icmp, timeout=0, sender=None):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.add_icmp_block(p_name, icmp, timeout, sender)

        p_name = self.policy_name_from_zones(zone, "ANY")
        self._fw.policy.add_icmp_block(p_name, icmp, timeout, sender)
        return zone

    def remove_icmp_block(self, zone, icmp):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.remove_icmp_block(p_name, icmp)

        p_name = self.policy_name_from_zones(zone, "ANY")
        self._fw.policy.remove_icmp_block(p_name, icmp)
        return zone

    def query_icmp_block(self, zone, icmp):
        zone = self._fw.check_zone(zone)
        p_name_host = self.policy_name_from_zones(zone, "HOST")
        p_name_fwd = self.policy_name_from_zones(zone, "ANY")
        return self._fw.policy.query_icmp_block(p_name_host, icmp) and \
               self._fw.policy.query_icmp_block(p_name_fwd, icmp)

    def list_icmp_blocks(self, zone):
        zone = self._fw.check_zone(zone)
        p_name_host = self.policy_name_from_zones(zone, "HOST")
        p_name_fwd = self.policy_name_from_zones(zone, "ANY")
        return sorted(set(self._fw.policy.list_icmp_blocks(p_name_host) +
                          self._fw.policy.list_icmp_blocks(p_name_fwd)))

    def add_icmp_block_inversion(self, zone, sender=None):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.add_icmp_block_inversion(p_name, sender)

        p_name = self.policy_name_from_zones(zone, "ANY")
        self._fw.policy.add_icmp_block_inversion(p_name, sender)
        return zone

    def _icmp_block_inversion(self, enable, zone, transaction):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy._icmp_block_inversion(enable, p_name, transaction)

        p_name = self.policy_name_from_zones(zone, "ANY")
        self._fw.policy._icmp_block_inversion(enable, p_name, transaction)

    def remove_icmp_block_inversion(self, zone):
        zone = self._fw.check_zone(zone)
        p_name = self.policy_name_from_zones(zone, "HOST")
        self._fw.policy.remove_icmp_block_inversion(p_name)

        p_name = self.policy_name_from_zones(zone, "ANY")
        self._fw.policy.remove_icmp_block_inversion(p_name)
        return zone

    def query_icmp_block_inversion(self, zone):
        zone = self._fw.check_zone(zone)
        p_name_host = self.policy_name_from_zones(zone, "HOST")
        p_name_fwd = self.policy_name_from_zones(zone, "ANY")
        return self._fw.policy.query_icmp_block_inversion(p_name_host) and \
               self._fw.policy.query_icmp_block_inversion(p_name_fwd)

    def _forward(self, enable, zone, transaction):
        p_name = self.policy_name_from_zones(zone, "ANY")

        for interface in self._zones[zone].settings["interfaces"]:
            for backend in self._fw.enabled_backends():
                if not backend.policies_supported:
                    continue
                rules = backend.build_zone_forward_rules(enable, zone, p_name, "filter", interface=interface)
                transaction.add_rules(backend, rules)

        for ipv,source in self._zones[zone].settings["sources"]:
            for backend in [self._fw.get_backend_by_ipv(ipv)] if ipv else self._fw.enabled_backends():
                if not backend.policies_supported:
                    continue
                rules = backend.build_zone_forward_rules(enable, zone, p_name, "filter", source=source)
                transaction.add_rules(backend, rules)

    def __forward_id(self):
        return True

    def add_forward(self, zone, timeout=0, sender=None,
                    use_transaction=None):
        _zone = self._fw.check_zone(zone)
        self._fw.check_timeout(timeout)
        self._fw.check_panic()
        _obj = self._zones[_zone]

        forward_id = self.__forward_id()
        if forward_id in _obj.settings["forward"]:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "forward already enabled in '%s'" % _zone)

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._forward(True, _zone, transaction)

        self.__register_forward(_obj, forward_id, timeout, sender)
        transaction.add_fail(self.__unregister_forward, _obj, forward_id)

        if use_transaction is None:
            transaction.execute(True)

        return _zone

    def __register_forward(self, _obj, forward_id, timeout, sender):
        _obj.settings["forward"][forward_id] = \
            self.__gen_settings(timeout, sender)

    def remove_forward(self, zone, use_transaction=None):
        _zone = self._fw.check_zone(zone)
        self._fw.check_panic()
        _obj = self._zones[_zone]

        forward_id = self.__forward_id()
        if forward_id not in _obj.settings["forward"]:
            raise FirewallError(errors.NOT_ENABLED,
                                "forward not enabled in '%s'" % _zone)

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._forward(False, _zone, transaction)

        transaction.add_post(self.__unregister_forward, _obj, forward_id)

        if use_transaction is None:
            transaction.execute(True)

        return _zone

    def __unregister_forward(self, _obj, forward_id):
        if forward_id in _obj.settings["forward"]:
            del _obj.settings["forward"][forward_id]

    def query_forward(self, zone):
        return self.__forward_id() in self.get_settings(zone)["forward"]
core/ipXtables.py000064400000170666150351351720010023 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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.path
import copy

from firewall.core.prog import runProg
from firewall.core.logger import log
from firewall.functions import tempFile, readfile, splitArgs, check_mac, portStr, \
                               check_single_address, check_address, normalizeIP6
from firewall import config
from firewall.errors import FirewallError, INVALID_PASSTHROUGH, INVALID_RULE, UNKNOWN_ERROR, INVALID_ADDR
from firewall.core.rich import Rich_Accept, Rich_Reject, Rich_Drop, Rich_Mark, \
                               Rich_Masquerade, Rich_ForwardPort, Rich_IcmpBlock
import string

POLICY_CHAIN_PREFIX = ""

BUILT_IN_CHAINS = {
    "security": [ "INPUT", "OUTPUT", "FORWARD" ],
    "raw": [ "PREROUTING", "OUTPUT" ],
    "mangle": [ "PREROUTING", "POSTROUTING", "INPUT", "OUTPUT", "FORWARD" ],
    "nat": [ "PREROUTING", "POSTROUTING", "OUTPUT" ],
    "filter": [ "INPUT", "OUTPUT", "FORWARD" ],
}

DEFAULT_REJECT_TYPE = {
    "ipv4": "icmp-host-prohibited",
    "ipv6": "icmp6-adm-prohibited",
}

ICMP = {
    "ipv4": "icmp",
    "ipv6": "ipv6-icmp",
}

# ipv ebtables also uses this
#
def common_reverse_rule(args):
    """ Inverse valid rule """

    replace_args = {
        # Append
        "-A": "-D",
        "--append": "--delete",
        # Insert
        "-I": "-D",
        "--insert": "--delete",
        # New chain
        "-N": "-X",
        "--new-chain": "--delete-chain",
    }

    ret_args = args[:]

    for arg in replace_args:
        try:
            idx = ret_args.index(arg)
        except Exception:
            continue

        if arg in [ "-I", "--insert" ]:
            # With insert rulenum, then remove it if it is a number
            # Opt at position idx, chain at position idx+1, [rulenum] at
            # position idx+2
            try:
                int(ret_args[idx+2])
            except Exception:
                pass
            else:
                ret_args.pop(idx+2)

        ret_args[idx] = replace_args[arg]
    return ret_args

def common_reverse_passthrough(args):
    """ Reverse valid passthough rule """

    replace_args = {
        # Append
        "-A": "-D",
        "--append": "--delete",
        # Insert
        "-I": "-D",
        "--insert": "--delete",
        # New chain
        "-N": "-X",
        "--new-chain": "--delete-chain",
    }

    ret_args = args[:]

    for x in replace_args:
        try:
            idx = ret_args.index(x)
        except ValueError:
            continue

        if x in [ "-I", "--insert" ]:
            # With insert rulenum, then remove it if it is a number
            # Opt at position idx, chain at position idx+1, [rulenum] at
            # position idx+2
            try:
                int(ret_args[idx+2])
            except ValueError:
                pass
            else:
                ret_args.pop(idx+2)

        ret_args[idx] = replace_args[x]
        return ret_args

    raise FirewallError(INVALID_PASSTHROUGH,
                        "no '-A', '-I' or '-N' arg")

# ipv ebtables also uses this
#
def common_check_passthrough(args):
    """ Check if passthough rule is valid (only add, insert and new chain
    rules are allowed) """

    args = set(args)
    not_allowed = set(["-C", "--check",           # check rule
                       "-D", "--delete",          # delete rule
                       "-R", "--replace",         # replace rule
                       "-L", "--list",            # list rule
                       "-S", "--list-rules",      # print rules
                       "-F", "--flush",           # flush rules
                       "-Z", "--zero",            # zero rules
                       "-X", "--delete-chain",    # delete chain
                       "-P", "--policy",          # policy
                       "-E", "--rename-chain"])   # rename chain)
    # intersection of args and not_allowed is not empty, i.e.
    # something from args is not allowed
    if len(args & not_allowed) > 0:
        raise FirewallError(INVALID_PASSTHROUGH,
                            "arg '%s' is not allowed" %
                            list(args & not_allowed)[0])

    # args need to contain one of -A, -I, -N
    needed = set(["-A", "--append",
                  "-I", "--insert",
                  "-N", "--new-chain"])
    # empty intersection of args and needed, i.e.
    # none from args contains any needed command
    if len(args & needed) == 0:
        raise FirewallError(INVALID_PASSTHROUGH,
                            "no '-A', '-I' or '-N' arg")

class ip4tables(object):
    ipv = "ipv4"
    name = "ip4tables"
    policies_supported = True

    def __init__(self, fw):
        self._fw = fw
        self._command = config.COMMANDS[self.ipv]
        self._restore_command = config.COMMANDS["%s-restore" % self.ipv]
        self.wait_option = self._detect_wait_option()
        self.restore_wait_option = self._detect_restore_wait_option()
        self.fill_exists()
        self.available_tables = []
        self.rich_rule_priority_counts = {}
        self.policy_priority_counts = {}
        self.zone_source_index_cache = []
        self.our_chains = {} # chains created by firewalld

    def fill_exists(self):
        self.command_exists = os.path.exists(self._command)
        self.restore_command_exists = os.path.exists(self._restore_command)

    def __run(self, args):
        # convert to string list
        if self.wait_option and self.wait_option not in args:
            _args = [self.wait_option] + ["%s" % item for item in args]
        else:
            _args = ["%s" % item for item in args]
        log.debug2("%s: %s %s", self.__class__, self._command, " ".join(_args))
        (status, ret) = runProg(self._command, _args)
        if status != 0:
            raise ValueError("'%s %s' failed: %s" % (self._command,
                                                     " ".join(_args), ret))
        return ret

    def _rule_replace(self, rule, pattern, replacement):
        try:
            i = rule.index(pattern)
        except ValueError:
            return False
        else:
            rule[i:i+1] = replacement
            return True

    def is_chain_builtin(self, ipv, table, chain):
        return table in BUILT_IN_CHAINS and \
               chain in BUILT_IN_CHAINS[table]

    def build_chain_rules(self, add, table, chain):
        rule = [ "-t", table ]
        if add:
            rule.append("-N")
        else:
            rule.append("-X")
        rule.append(chain)
        return [rule]

    def build_rule(self, add, table, chain, index, args):
        rule = [ "-t", table ]
        if add:
            rule += [ "-I", chain, str(index) ]
        else:
            rule += [ "-D", chain ]
        rule += args
        return rule

    def reverse_rule(self, args):
        return common_reverse_rule(args)

    def check_passthrough(self, args):
        common_check_passthrough(args)

    def reverse_passthrough(self, args):
        return common_reverse_passthrough(args)

    def passthrough_parse_table_chain(self, args):
        table = "filter"
        try:
            i = args.index("-t")
        except ValueError:
            pass
        else:
            if len(args) >= i+1:
                table = args[i+1]
        chain = None
        for opt in [ "-A", "--append",
                     "-I", "--insert",
                     "-N", "--new-chain" ]:
            try:
                i = args.index(opt)
            except ValueError:
                pass
            else:
                if len(args) >= i+1:
                    chain = args[i+1]
        return (table, chain)

    def _run_replace_zone_source(self, rule, zone_source_index_cache):
        try:
            i = rule.index("%%ZONE_SOURCE%%")
            rule.pop(i)
            zone = rule.pop(i)
            if "-m" == rule[4]: # ipset/mac
                zone_source = (zone, rule[7]) # (zone, address)
            else:
                zone_source = (zone, rule[5]) # (zone, address)
        except ValueError:
            try:
                i = rule.index("%%ZONE_INTERFACE%%")
                rule.pop(i)
                zone_source = None
            except ValueError:
                return

        rule_add = True
        if rule[0] in ["-D", "--delete"]:
            rule_add = False

        if zone_source and not rule_add:
            if zone_source in zone_source_index_cache:
                zone_source_index_cache.remove(zone_source)
        elif rule_add:
            if zone_source:
                # order source based dispatch by zone name
                if zone_source not in zone_source_index_cache:
                    zone_source_index_cache.append(zone_source)
                    zone_source_index_cache.sort(key=lambda x: x[0])

                index = zone_source_index_cache.index(zone_source)
            else:
                if self._fw._allow_zone_drifting:
                    index = 0
                else:
                    index = len(zone_source_index_cache)

            rule[0] = "-I"
            rule.insert(2, "%d" % (index + 1))

    def _set_rule_replace_priority(self, rule, priority_counts, token):
        """
        Change something like
          -t filter -I public_IN %%RICH_RULE_PRIORITY%% 123
        or
          -t filter -A public_IN %%RICH_RULE_PRIORITY%% 321
        into
          -t filter -I public_IN 4
        or
          -t filter -I public_IN
        """
        try:
            i = rule.index(token)
        except ValueError:
            pass
        else:
            rule_add = True
            insert = False
            insert_add_index = -1
            rule.pop(i)
            priority = rule.pop(i)
            if type(priority) != int:
                raise FirewallError(INVALID_RULE, "priority must be followed by a number")

            table = "filter"
            for opt in [ "-t", "--table" ]:
                try:
                    j = rule.index(opt)
                except ValueError:
                    pass
                else:
                    if len(rule) >= j+1:
                        table = rule[j+1]
            for opt in [ "-A", "--append",
                         "-I", "--insert",
                         "-D", "--delete" ]:
                try:
                    insert_add_index = rule.index(opt)
                except ValueError:
                    pass
                else:
                    if len(rule) >= insert_add_index+1:
                        chain = rule[insert_add_index+1]

                    if opt in [ "-I", "--insert" ]:
                        insert = True
                    if opt in [ "-D", "--delete" ]:
                        rule_add = False

            chain = (table, chain)

            # Add the rule to the priority counts. We don't need to store the
            # rule, just bump the ref count for the priority value.
            if not rule_add:
                if chain not in priority_counts or \
                   priority not in priority_counts[chain] or \
                   priority_counts[chain][priority] <= 0:
                    raise FirewallError(UNKNOWN_ERROR, "nonexistent or underflow of priority count")

                priority_counts[chain][priority] -= 1
            else:
                if chain not in priority_counts:
                    priority_counts[chain] = {}
                if priority not in priority_counts[chain]:
                    priority_counts[chain][priority] = 0

                # calculate index of new rule
                index = 1
                for p in sorted(priority_counts[chain].keys()):
                    if p == priority and insert:
                        break
                    index += priority_counts[chain][p]
                    if p == priority:
                        break

                priority_counts[chain][priority] += 1

                rule[insert_add_index] = "-I"
                rule.insert(insert_add_index+2, "%d" % index)

    def set_rules(self, rules, log_denied):
        temp_file = tempFile()

        table_rules = { }
        rich_rule_priority_counts = copy.deepcopy(self.rich_rule_priority_counts)
        policy_priority_counts = copy.deepcopy(self.policy_priority_counts)
        zone_source_index_cache = copy.deepcopy(self.zone_source_index_cache)
        for _rule in rules:
            rule = _rule[:]

            # replace %%REJECT%%
            self._rule_replace(rule, "%%REJECT%%", \
                    ["REJECT", "--reject-with", DEFAULT_REJECT_TYPE[self.ipv]])

            # replace %%ICMP%%
            self._rule_replace(rule, "%%ICMP%%", [ICMP[self.ipv]])

            # replace %%LOGTYPE%%
            try:
                i = rule.index("%%LOGTYPE%%")
            except ValueError:
                pass
            else:
                if log_denied == "off":
                    continue
                if log_denied in [ "unicast", "broadcast", "multicast" ]:
                    rule[i:i+1] = [ "-m", "pkttype", "--pkt-type", log_denied ]
                else:
                    rule.pop(i)

            self._set_rule_replace_priority(rule, rich_rule_priority_counts, "%%RICH_RULE_PRIORITY%%")
            self._set_rule_replace_priority(rule, policy_priority_counts, "%%POLICY_PRIORITY%%")
            self._run_replace_zone_source(rule, zone_source_index_cache)

            table = "filter"
            # get table form rule
            for opt in [ "-t", "--table" ]:
                try:
                    i = rule.index(opt)
                except ValueError:
                    pass
                else:
                    if len(rule) >= i+1:
                        rule.pop(i)
                        table = rule.pop(i)

            # we can not use joinArgs here, because it would use "'" instead
            # of '"' for the start and end of the string, this breaks
            # iptables-restore
            for i in range(len(rule)):
                for c in string.whitespace:
                    if c in rule[i] and not (rule[i].startswith('"') and
                                             rule[i].endswith('"')):
                        rule[i] = '"%s"' % rule[i]

            table_rules.setdefault(table, []).append(rule)

        for table in table_rules:
            rules = table_rules[table]

            temp_file.write("*%s\n" % table)
            for rule in rules:
                temp_file.write(" ".join(rule) + "\n")
            temp_file.write("COMMIT\n")

        temp_file.close()

        stat = os.stat(temp_file.name)
        log.debug2("%s: %s %s", self.__class__, self._restore_command,
                   "%s: %d" % (temp_file.name, stat.st_size))
        args = [ ]
        if self.restore_wait_option:
            args.append(self.restore_wait_option)
        args.append("-n")

        (status, ret) = runProg(self._restore_command, args,
                                stdin=temp_file.name)

        if log.getDebugLogLevel() > 2:
            lines = readfile(temp_file.name)
            if lines is not None:
                i = 1
                for line in lines:
                    log.debug3("%8d: %s" % (i, line), nofmt=1, nl=0)
                    if not line.endswith("\n"):
                        log.debug3("", nofmt=1)
                    i += 1

        os.unlink(temp_file.name)

        if status != 0:
            raise ValueError("'%s %s' failed: %s" % (self._restore_command,
                                                     " ".join(args), ret))
        self.rich_rule_priority_counts = rich_rule_priority_counts
        self.policy_priority_counts = policy_priority_counts
        self.zone_source_index_cache = zone_source_index_cache

    def set_rule(self, rule, log_denied):
        # replace %%REJECT%%
        self._rule_replace(rule, "%%REJECT%%", \
                ["REJECT", "--reject-with", DEFAULT_REJECT_TYPE[self.ipv]])

        # replace %%ICMP%%
        self._rule_replace(rule, "%%ICMP%%", [ICMP[self.ipv]])

        # replace %%LOGTYPE%%
        try:
            i = rule.index("%%LOGTYPE%%")
        except ValueError:
            pass
        else:
            if log_denied == "off":
                return ""
            if log_denied in [ "unicast", "broadcast", "multicast" ]:
                rule[i:i+1] = [ "-m", "pkttype", "--pkt-type", log_denied ]
            else:
                rule.pop(i)

        rich_rule_priority_counts = copy.deepcopy(self.rich_rule_priority_counts)
        policy_priority_counts = copy.deepcopy(self.policy_priority_counts)
        zone_source_index_cache = copy.deepcopy(self.zone_source_index_cache)
        self._set_rule_replace_priority(rule, rich_rule_priority_counts, "%%RICH_RULE_PRIORITY%%")
        self._set_rule_replace_priority(rule, policy_priority_counts, "%%POLICY_PRIORITY%%")
        self._run_replace_zone_source(rule, zone_source_index_cache)

        output = self.__run(rule)

        self.rich_rule_priority_counts = rich_rule_priority_counts
        self.policy_priority_counts = policy_priority_counts
        self.zone_source_index_cache = zone_source_index_cache
        return output

    def get_available_tables(self, table=None):
        ret = []
        tables = [ table ] if table else BUILT_IN_CHAINS.keys()
        for table in tables:
            if table in self.available_tables:
                ret.append(table)
            else:
                try:
                    self.__run(["-t", table, "-L", "-n"])
                    self.available_tables.append(table)
                    ret.append(table)
                except ValueError:
                    log.debug1("%s table '%s' does not exist (or not enough permission to check)." % (self.ipv, table))

        return ret

    def _detect_wait_option(self):
        wait_option = ""
        ret = runProg(self._command, ["-w", "-L", "-n"])  # since iptables-1.4.20
        if ret[0] == 0:
            wait_option = "-w"  # wait for xtables lock
            ret = runProg(self._command, ["-w10", "-L", "-n"])  # since iptables > 1.4.21
            if ret[0] == 0:
                wait_option = "-w10"  # wait max 10 seconds
            log.debug2("%s: %s will be using %s option.", self.__class__, self._command, wait_option)

        return wait_option

    def _detect_restore_wait_option(self):
        temp_file = tempFile()
        temp_file.write("#foo")
        temp_file.close()

        wait_option = ""
        for test_option in ["-w", "--wait=2"]:
            ret = runProg(self._restore_command, [test_option], stdin=temp_file.name)
            if ret[0] == 0 and "invalid option" not in ret[1] \
                           and "unrecognized option" not in ret[1]:
                wait_option = test_option
                break

        log.debug2("%s: %s will be using %s option.", self.__class__, self._restore_command, wait_option)

        os.unlink(temp_file.name)

        return wait_option

    def build_flush_rules(self):
        self.rich_rule_priority_counts = {}
        self.policy_priority_counts = {}
        self.zone_source_index_cache = []
        rules = []
        for table in BUILT_IN_CHAINS.keys():
            if not self.get_available_tables(table):
                continue
            # Flush firewall rules: -F
            # Delete firewall chains: -X
            # Set counter to zero: -Z
            for flag in [ "-F", "-X", "-Z" ]:
                rules.append(["-t", table, flag])
        return rules

    def build_set_policy_rules(self, policy):
        rules = []
        _policy = "DROP" if policy == "PANIC" else policy
        for table in BUILT_IN_CHAINS.keys():
            if not self.get_available_tables(table):
                continue
            if table == "nat":
                continue
            for chain in BUILT_IN_CHAINS[table]:
                rules.append(["-t", table, "-P", chain, _policy])
        return rules

    def supported_icmp_types(self, ipv=None):
        """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

    def build_default_tables(self):
        # nothing to do, they always exist
        return []

    def build_default_rules(self, log_denied="off"):
        default_rules = {}

        if self.get_available_tables("security"):
            default_rules["security"] = [ ]
            self.our_chains["security"] = set()
            for chain in BUILT_IN_CHAINS["security"]:
                default_rules["security"].append("-N %s_direct" % chain)
                default_rules["security"].append("-A %s -j %s_direct" % (chain, chain))
                self.our_chains["security"].add("%s_direct" % chain)

        if self.get_available_tables("raw"):
            default_rules["raw"] = [ ]
            self.our_chains["raw"] = set()
            for chain in BUILT_IN_CHAINS["raw"]:
                default_rules["raw"].append("-N %s_direct" % chain)
                default_rules["raw"].append("-A %s -j %s_direct" % (chain, chain))
                self.our_chains["raw"].add("%s_direct" % chain)

                if chain == "PREROUTING":
                    for dispatch_suffix in ["POLICIES_pre", "ZONES_SOURCE", "ZONES", "POLICIES_post"] if self._fw._allow_zone_drifting else ["POLICIES_pre", "ZONES", "POLICIES_post"]:
                        default_rules["raw"].append("-N %s_%s" % (chain, dispatch_suffix))
                        default_rules["raw"].append("-A %s -j %s_%s" % (chain, chain, dispatch_suffix))
                        self.our_chains["raw"].update(set(["%s_%s" % (chain, dispatch_suffix)]))

        if self.get_available_tables("mangle"):
            default_rules["mangle"] = [ ]
            self.our_chains["mangle"] = set()
            for chain in BUILT_IN_CHAINS["mangle"]:
                default_rules["mangle"].append("-N %s_direct" % chain)
                default_rules["mangle"].append("-A %s -j %s_direct" % (chain, chain))
                self.our_chains["mangle"].add("%s_direct" % chain)

                if chain == "PREROUTING":
                    for dispatch_suffix in ["POLICIES_pre", "ZONES_SOURCE", "ZONES", "POLICIES_post"] if self._fw._allow_zone_drifting else ["POLICIES_pre", "ZONES", "POLICIES_post"]:
                        default_rules["mangle"].append("-N %s_%s" % (chain, dispatch_suffix))
                        default_rules["mangle"].append("-A %s -j %s_%s" % (chain, chain, dispatch_suffix))
                        self.our_chains["mangle"].update(set(["%s_%s" % (chain, dispatch_suffix)]))

        if self.get_available_tables("nat"):
            default_rules["nat"] = [ ]
            self.our_chains["nat"] = set()
            for chain in BUILT_IN_CHAINS["nat"]:
                default_rules["nat"].append("-N %s_direct" % chain)
                default_rules["nat"].append("-A %s -j %s_direct" % (chain, chain))
                self.our_chains["nat"].add("%s_direct" % chain)

                if chain in [ "PREROUTING", "POSTROUTING" ]:
                    for dispatch_suffix in ["POLICIES_pre", "ZONES_SOURCE", "ZONES", "POLICIES_post"] if self._fw._allow_zone_drifting else ["POLICIES_pre", "ZONES", "POLICIES_post"]:
                        default_rules["nat"].append("-N %s_%s" % (chain, dispatch_suffix))
                        default_rules["nat"].append("-A %s -j %s_%s" % (chain, chain, dispatch_suffix))
                        self.our_chains["nat"].update(set(["%s_%s" % (chain, dispatch_suffix)]))

        default_rules["filter"] = []
        self.our_chains["filter"] = set()
        default_rules["filter"].append("-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT")
        default_rules["filter"].append("-A INPUT -i lo -j ACCEPT")
        default_rules["filter"].append("-N INPUT_direct")
        default_rules["filter"].append("-A INPUT -j INPUT_direct")
        self.our_chains["filter"].update(set("INPUT_direct"))
        for dispatch_suffix in ["POLICIES_pre", "ZONES_SOURCE", "ZONES", "POLICIES_post"] if self._fw._allow_zone_drifting else ["POLICIES_pre", "ZONES", "POLICIES_post"]:
            default_rules["filter"].append("-N INPUT_%s" % (dispatch_suffix))
            default_rules["filter"].append("-A INPUT -j INPUT_%s" % (dispatch_suffix))
            self.our_chains["filter"].update(set("INPUT_%s" % (dispatch_suffix)))
        if log_denied != "off":
            default_rules["filter"].append("-A INPUT -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: '")
        default_rules["filter"].append("-A INPUT -m conntrack --ctstate INVALID -j DROP")
        if log_denied != "off":
            default_rules["filter"].append("-A INPUT %%LOGTYPE%% -j LOG --log-prefix 'FINAL_REJECT: '")
        default_rules["filter"].append("-A INPUT -j %%REJECT%%")

        default_rules["filter"].append("-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT")
        default_rules["filter"].append("-A FORWARD -i lo -j ACCEPT")
        default_rules["filter"].append("-N FORWARD_direct")
        default_rules["filter"].append("-A FORWARD -j FORWARD_direct")
        self.our_chains["filter"].update(set("FORWARD_direct"))
        for dispatch_suffix in ["POLICIES_pre"]:
            default_rules["filter"].append("-N FORWARD_%s" % (dispatch_suffix))
            default_rules["filter"].append("-A FORWARD -j FORWARD_%s" % (dispatch_suffix))
            self.our_chains["filter"].update(set("FORWARD_%s" % (dispatch_suffix)))
        for direction in ["IN", "OUT"]:
            for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]:
                default_rules["filter"].append("-N FORWARD_%s_%s" % (direction, dispatch_suffix))
                default_rules["filter"].append("-A FORWARD -j FORWARD_%s_%s" % (direction, dispatch_suffix))
                self.our_chains["filter"].update(set("FORWARD_%s_%s" % (direction, dispatch_suffix)))
        for dispatch_suffix in ["POLICIES_post"]:
            default_rules["filter"].append("-N FORWARD_%s" % (dispatch_suffix))
            default_rules["filter"].append("-A FORWARD -j FORWARD_%s" % (dispatch_suffix))
            self.our_chains["filter"].update(set("FORWARD_%s" % (dispatch_suffix)))
        if log_denied != "off":
            default_rules["filter"].append("-A FORWARD -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: '")
        default_rules["filter"].append("-A FORWARD -m conntrack --ctstate INVALID -j DROP")
        if log_denied != "off":
            default_rules["filter"].append("-A FORWARD %%LOGTYPE%% -j LOG --log-prefix 'FINAL_REJECT: '")
        default_rules["filter"].append("-A FORWARD -j %%REJECT%%")

        default_rules["filter"] += [
            "-N OUTPUT_direct",

            "-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT",
            "-A OUTPUT -o lo -j ACCEPT",
            "-A OUTPUT -j OUTPUT_direct",
        ]
        self.our_chains["filter"].update(set("OUTPUT_direct"))
        for dispatch_suffix in ["POLICIES_pre"]:
            default_rules["filter"].append("-N OUTPUT_%s" % (dispatch_suffix))
            default_rules["filter"].append("-A OUTPUT -j OUTPUT_%s" % (dispatch_suffix))
            self.our_chains["filter"].update(set("OUTPUT_%s" % (dispatch_suffix)))
        for dispatch_suffix in ["POLICIES_post"]:
            default_rules["filter"].append("-N OUTPUT_%s" % (dispatch_suffix))
            default_rules["filter"].append("-A OUTPUT -j OUTPUT_%s" % (dispatch_suffix))
            self.our_chains["filter"].update(set("OUTPUT_%s" % (dispatch_suffix)))

        final_default_rules = []
        for table in default_rules:
            if table not in self.get_available_tables():
                continue
            for rule in default_rules[table]:
                final_default_rules.append(["-t", table] + splitArgs(rule))

        return final_default_rules

    def get_zone_table_chains(self, table):
        if table == "filter":
            return { "INPUT", "FORWARD_IN", "FORWARD_OUT" }
        if table == "mangle":
            if "mangle" in self.get_available_tables():
                return { "PREROUTING" }
        if table == "nat":
            if "nat" in self.get_available_tables():
                return { "PREROUTING", "POSTROUTING" }
        if table == "raw":
            if "raw" in self.get_available_tables():
                return { "PREROUTING" }

        return {}

    def build_policy_ingress_egress_rules(self, enable, policy, table, chain,
                                          ingress_interfaces, egress_interfaces,
                                          ingress_sources, egress_sources):
        p_obj = self._fw.policy.get_policy(policy)
        chain_suffix = "pre" if p_obj.priority < 0 else "post"
        isSNAT = True if (table == "nat" and chain == "POSTROUTING") else False
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX, isSNAT)

        ingress_fragments = []
        egress_fragments = []
        for interface in ingress_interfaces:
            ingress_fragments.append(["-i", interface])
        for interface in egress_interfaces:
            egress_fragments.append(["-o", interface])
        for addr in ingress_sources:
            ipv = self._fw.zone.check_source(addr)
            if ipv in ["ipv4", "ipv6"] and not self.is_ipv_supported(ipv):
                continue
            ingress_fragments.append(self._rule_addr_fragment("-s", addr))
        for addr in egress_sources:
            ipv = self._fw.zone.check_source(addr)
            if ipv in ["ipv4", "ipv6"] and not self.is_ipv_supported(ipv):
                continue
            # iptables can not match destination MAC
            if check_mac(addr) and chain in ["POSTROUTING", "FORWARD_OUT", "OUTPUT"]:
                continue

            egress_fragments.append(self._rule_addr_fragment("-d", addr))

        def _generate_policy_dispatch_rule(ingress_fragment, egress_fragment):
            add_del = {True: "-A", False: "-D" }[enable]
            rule = ["-t", table, add_del, "%s_POLICIES_%s" % (chain, chain_suffix),
                    "%%POLICY_PRIORITY%%", p_obj.priority]
            if ingress_fragment:
                rule.extend(ingress_fragment)
            if egress_fragment:
                rule.extend(egress_fragment)
            rule.extend(["-j", _policy])

            return rule

        rules = []
        if ingress_fragments:
            # zone --> [zone, ANY, HOST]
            for ingress_fragment in ingress_fragments:
                # zone --> zone
                if egress_fragments:
                    for egress_fragment in egress_fragments:
                        rules.append(_generate_policy_dispatch_rule(ingress_fragment, egress_fragment))
                elif egress_sources:
                    # if the egress source is not for the current family (there
                    # are no egress fragments), then avoid creating an invalid
                    # catch all rule.
                    pass
                else:
                    rules.append(_generate_policy_dispatch_rule(ingress_fragment, None))
        elif ingress_sources:
            # if the ingress source is not for the current family (there are no
            # ingress fragments), then avoid creating an invalid catch all
            # rule.
            pass
        else: # [ANY, HOST] --> [zone, ANY, HOST]
            # [ANY, HOST] --> zone
            if egress_fragments:
                for egress_fragment in egress_fragments:
                    rules.append(_generate_policy_dispatch_rule(None, egress_fragment))
            elif egress_sources:
                # if the egress source is not for the current family (there
                # are no egress fragments), then avoid creating an invalid
                # catch all rule.
                pass
            else:
                # [ANY, HOST] --> [ANY, HOST]
                rules.append(_generate_policy_dispatch_rule(None, None))

        return rules

    def build_zone_source_interface_rules(self, enable, zone, policy, interface,
                                          table, chain, append=False):
        isSNAT = True if (table == "nat" and chain == "POSTROUTING") else False
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX, isSNAT=isSNAT)
        opt = {
            "PREROUTING": "-i",
            "POSTROUTING": "-o",
            "INPUT": "-i",
            "FORWARD_IN": "-i",
            "FORWARD_OUT": "-o",
            "OUTPUT": "-o",
        }[chain]

        action = "-g"

        if enable and not append:
            rule = [ "-I", "%s_ZONES" % chain, "%%ZONE_INTERFACE%%" ]
        elif enable:
            rule = [ "-A", "%s_ZONES" % chain ]
        else:
            rule = [ "-D", "%s_ZONES" % chain ]
            if not append:
                rule += ["%%ZONE_INTERFACE%%"]
        rule += [ "-t", table, opt, interface, action, _policy ]
        return [rule]

    def _rule_addr_fragment(self, opt, address, invert=False):
        if address.startswith("ipset:"):
            name = address[6:]
            if opt == "-d":
                opt = "dst"
            else:
                opt = "src"
            flags = ",".join([opt] * self._fw.ipset.get_dimension(name))
            return ["-m", "set", "--match-set", name, flags]
        elif check_mac(address):
            # outgoing can not be set
            if opt == "-d":
                raise FirewallError(INVALID_ADDR, "Can't match a destination MAC.")
            return ["-m", "mac", "--mac-source", address.upper()]
        else:
            if check_single_address("ipv6", address):
                address = normalizeIP6(address)
            elif check_address("ipv6", address):
                addr_split = address.split("/")
                address = normalizeIP6(addr_split[0]) + "/" + addr_split[1]
            return [opt, address]

    def build_zone_source_address_rules(self, enable, zone, policy,
                                        address, table, chain):
        add_del = { True: "-I", False: "-D" }[enable]

        isSNAT = True if (table == "nat" and chain == "POSTROUTING") else False
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX, isSNAT=isSNAT)
        opt = {
            "PREROUTING": "-s",
            "POSTROUTING": "-d",
            "INPUT": "-s",
            "FORWARD_IN": "-s",
            "FORWARD_OUT": "-d",
            "OUTPUT": "-d",
        }[chain]

        if self._fw._allow_zone_drifting:
            zone_dispatch_chain = "%s_ZONES_SOURCE" % (chain)
        else:
            zone_dispatch_chain = "%s_ZONES" % (chain)

        # iptables can not match destination MAC
        if check_mac(address) and chain in ["POSTROUTING", "FORWARD_OUT", "OUTPUT"]:
            return []

        rule = [add_del, zone_dispatch_chain, "%%ZONE_SOURCE%%", zone, "-t", table]
        rule.extend(self._rule_addr_fragment(opt, address))
        rule.extend(["-g", _policy])

        return [rule]

    def build_policy_chain_rules(self, enable, policy, table, chain):
        add_del_chain = { True: "-N", False: "-X" }[enable]
        add_del_rule = { True: "-A", False: "-D" }[enable]
        isSNAT = True if (table == "nat" and chain == "POSTROUTING") else False
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX, isSNAT=isSNAT)

        self.our_chains[table].update(set([_policy,
                                      "%s_log" % _policy,
                                      "%s_deny" % _policy,
                                      "%s_pre" % _policy,
                                      "%s_post" % _policy,
                                      "%s_allow" % _policy]))

        rules = []
        rules.append([ add_del_chain, _policy, "-t", table ])
        rules.append([ add_del_chain, "%s_pre" % _policy, "-t", table ])
        rules.append([ add_del_chain, "%s_log" % _policy, "-t", table ])
        rules.append([ add_del_chain, "%s_deny" % _policy, "-t", table ])
        rules.append([ add_del_chain, "%s_allow" % _policy, "-t", table ])
        rules.append([ add_del_chain, "%s_post" % _policy, "-t", table ])
        rules.append([ add_del_rule, _policy, "-t", table, "-j", "%s_pre" % _policy ])
        rules.append([ add_del_rule, _policy, "-t", table, "-j", "%s_log" % _policy ])
        rules.append([ add_del_rule, _policy, "-t", table, "-j", "%s_deny" % _policy ])
        rules.append([ add_del_rule, _policy, "-t", table, "-j", "%s_allow" % _policy ])
        rules.append([ add_del_rule, _policy, "-t", table, "-j", "%s_post" % _policy ])

        target = self._fw.policy._policies[policy].target

        if self._fw.get_log_denied() != "off":
            if table == "filter":
                if target in [ "REJECT", "%%REJECT%%" ]:
                    rules.append([ add_del_rule, _policy, "-t", table, "%%LOGTYPE%%",
                                   "-j", "LOG", "--log-prefix",
                                   "\"%s_REJECT: \"" % _policy ])
                if target == "DROP":
                    rules.append([ add_del_rule, _policy, "-t", table, "%%LOGTYPE%%",
                                   "-j", "LOG", "--log-prefix",
                                   "\"%s_DROP: \"" % _policy ])

        if table == "filter" and \
           target in [ "ACCEPT", "REJECT", "%%REJECT%%", "DROP" ]:
            rules.append([ add_del_rule, _policy, "-t", table, "-j", target ])

        if not enable:
            rules.reverse()

        return rules

    def _rule_limit(self, limit):
        if not limit:
            return []
        s = ["-m", "limit", "--limit", limit.value]
        if limit.burst is not None:
            s += ["--limit-burst", limit.burst]
        return s

    def _rich_rule_chain_suffix(self, rich_rule):
        if type(rich_rule.element) in [Rich_Masquerade, Rich_ForwardPort, Rich_IcmpBlock]:
            # These are special and don't have an explicit action
            pass
        elif rich_rule.action:
            if type(rich_rule.action) not in [Rich_Accept, Rich_Reject, Rich_Drop, Rich_Mark]:
                raise FirewallError(INVALID_RULE, "Unknown action %s" % type(rich_rule.action))
        else:
            raise FirewallError(INVALID_RULE, "No rule action specified.")

        if rich_rule.priority == 0:
            if type(rich_rule.element) in [Rich_Masquerade, Rich_ForwardPort] or \
               type(rich_rule.action) in [Rich_Accept, Rich_Mark]:
                return "allow"
            elif type(rich_rule.element) in [Rich_IcmpBlock] or \
                 type(rich_rule.action) in [Rich_Reject, Rich_Drop]:
                return "deny"
        elif rich_rule.priority < 0:
            return "pre"
        else:
            return "post"

    def _rich_rule_chain_suffix_from_log(self, rich_rule):
        if not rich_rule.log and not rich_rule.audit:
            raise FirewallError(INVALID_RULE, "Not log or audit")

        if rich_rule.priority == 0:
            return "log"
        elif rich_rule.priority < 0:
            return "pre"
        else:
            return "post"

    def _rich_rule_priority_fragment(self, rich_rule):
        if rich_rule.priority == 0:
            return []
        return ["%%RICH_RULE_PRIORITY%%", rich_rule.priority]

    def _rich_rule_log(self, policy, rich_rule, enable, table, rule_fragment):
        if not rich_rule.log:
            return []

        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        add_del = { True: "-A", False: "-D" }[enable]

        chain_suffix = self._rich_rule_chain_suffix_from_log(rich_rule)
        rule = ["-t", table, add_del, "%s_%s" % (_policy, chain_suffix)]
        rule += self._rich_rule_priority_fragment(rich_rule)
        rule += rule_fragment + [ "-j", "LOG" ]
        if rich_rule.log.prefix:
            rule += [ "--log-prefix", "'%s'" % rich_rule.log.prefix ]
        if rich_rule.log.level:
            rule += [ "--log-level", "%s" % rich_rule.log.level ]
        rule += self._rule_limit(rich_rule.log.limit)

        return rule

    def _rich_rule_audit(self, policy, rich_rule, enable, table, rule_fragment):
        if not rich_rule.audit:
            return []

        add_del = { True: "-A", False: "-D" }[enable]

        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        chain_suffix = self._rich_rule_chain_suffix_from_log(rich_rule)
        rule = ["-t", table, add_del, "%s_%s" % (_policy, chain_suffix)]
        rule += self._rich_rule_priority_fragment(rich_rule)
        rule += rule_fragment
        if type(rich_rule.action) == Rich_Accept:
            _type = "accept"
        elif type(rich_rule.action) == Rich_Reject:
            _type = "reject"
        elif type(rich_rule.action) ==  Rich_Drop:
            _type = "drop"
        else:
            _type = "unknown"
        rule += [ "-j", "AUDIT", "--type", _type ]
        rule += self._rule_limit(rich_rule.audit.limit)

        return rule

    def _rich_rule_action(self, policy, rich_rule, enable, table, rule_fragment):
        if not rich_rule.action:
            return []

        add_del = { True: "-A", False: "-D" }[enable]

        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        chain_suffix = self._rich_rule_chain_suffix(rich_rule)
        chain = "%s_%s" % (_policy, chain_suffix)
        if type(rich_rule.action) == Rich_Accept:
            rule_action = [ "-j", "ACCEPT" ]
        elif type(rich_rule.action) == Rich_Reject:
            rule_action = [ "-j", "REJECT" ]
            if rich_rule.action.type:
                rule_action += [ "--reject-with", rich_rule.action.type ]
        elif type(rich_rule.action) ==  Rich_Drop:
            rule_action = [ "-j", "DROP" ]
        elif type(rich_rule.action) == Rich_Mark:
            table = "mangle"
            _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
            chain = "%s_%s" % (_policy, chain_suffix)
            rule_action = [ "-j", "MARK", "--set-xmark", rich_rule.action.set ]
        else:
            raise FirewallError(INVALID_RULE,
                                "Unknown action %s" % type(rich_rule.action))

        rule = ["-t", table, add_del, chain]
        rule += self._rich_rule_priority_fragment(rich_rule)
        rule += rule_fragment + rule_action
        rule += self._rule_limit(rich_rule.action.limit)

        return rule

    def _rich_rule_destination_fragment(self, rich_dest):
        if not rich_dest:
            return []

        rule_fragment = []
        if rich_dest.addr:
            if rich_dest.invert:
                rule_fragment.append("!")
            if check_single_address("ipv6", rich_dest.addr):
                rule_fragment += [ "-d", normalizeIP6(rich_dest.addr) ]
            elif check_address("ipv6", rich_dest.addr):
                addr_split = rich_dest.addr.split("/")
                rule_fragment += [ "-d", normalizeIP6(addr_split[0]) + "/" + addr_split[1] ]
            else:
                rule_fragment += [ "-d", rich_dest.addr ]
        elif rich_dest.ipset:
            rule_fragment += [ "-m", "set" ]
            if rich_dest.invert:
                rule_fragment.append("!")
            flags = self._fw.zone._ipset_match_flags(rich_dest.ipset, "dst")
            rule_fragment += [ "--match-set", rich_dest.ipset, flags ]

        return rule_fragment

    def _rich_rule_source_fragment(self, rich_source):
        if not rich_source:
            return []

        rule_fragment = []
        if rich_source.addr:
            if rich_source.invert:
                rule_fragment.append("!")
            if check_single_address("ipv6", rich_source.addr):
                rule_fragment += [ "-s", normalizeIP6(rich_source.addr) ]
            elif check_address("ipv6", rich_source.addr):
                addr_split = rich_source.addr.split("/")
                rule_fragment += [ "-s", normalizeIP6(addr_split[0]) + "/" + addr_split[1] ]
            else:
                rule_fragment += [ "-s", rich_source.addr ]
        elif hasattr(rich_source, "mac") and rich_source.mac:
            rule_fragment += [ "-m", "mac" ]
            if rich_source.invert:
                rule_fragment.append("!")
            rule_fragment += [ "--mac-source", rich_source.mac ]
        elif hasattr(rich_source, "ipset") and rich_source.ipset:
            rule_fragment += [ "-m", "set" ]
            if rich_source.invert:
                rule_fragment.append("!")
            flags = self._fw.zone._ipset_match_flags(rich_source.ipset, "src")
            rule_fragment += [ "--match-set", rich_source.ipset, flags ]

        return rule_fragment

    def build_policy_ports_rules(self, enable, policy, proto, port, destination=None, rich_rule=None):
        add_del = { True: "-A", False: "-D" }[enable]
        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        rule_fragment = [ "-p", proto ]
        if port:
            rule_fragment += [ "--dport", "%s" % portStr(port) ]
        if destination:
            rule_fragment += [ "-d", destination ]
        if rich_rule:
            rule_fragment += self._rich_rule_destination_fragment(rich_rule.destination)
            rule_fragment += self._rich_rule_source_fragment(rich_rule.source)
        if not rich_rule or type(rich_rule.action) != Rich_Mark:
            rule_fragment += [ "-m", "conntrack", "--ctstate", "NEW,UNTRACKED" ]

        rules = []
        if rich_rule:
            rules.append(self._rich_rule_log(policy, rich_rule, enable, table, rule_fragment))
            rules.append(self._rich_rule_audit(policy, rich_rule, enable, table, rule_fragment))
            rules.append(self._rich_rule_action(policy, rich_rule, enable, table, rule_fragment))
        else:
            rules.append([add_del, "%s_allow" % (_policy), "-t", table] +
                         rule_fragment + [ "-j", "ACCEPT" ])

        return rules

    def build_policy_protocol_rules(self, enable, policy, protocol, destination=None, rich_rule=None):
        add_del = { True: "-A", False: "-D" }[enable]
        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        rule_fragment = [ "-p", protocol ]
        if destination:
            rule_fragment += [ "-d", destination ]
        if rich_rule:
            rule_fragment += self._rich_rule_destination_fragment(rich_rule.destination)
            rule_fragment += self._rich_rule_source_fragment(rich_rule.source)
        if not rich_rule or type(rich_rule.action) != Rich_Mark:
            rule_fragment += [ "-m", "conntrack", "--ctstate", "NEW,UNTRACKED" ]

        rules = []
        if rich_rule:
            rules.append(self._rich_rule_log(policy, rich_rule, enable, table, rule_fragment))
            rules.append(self._rich_rule_audit(policy, rich_rule, enable, table, rule_fragment))
            rules.append(self._rich_rule_action(policy, rich_rule, enable, table, rule_fragment))
        else:
            rules.append([add_del, "%s_allow" % (_policy), "-t", table] +
                         rule_fragment + [ "-j", "ACCEPT" ])

        return rules

    def build_policy_source_ports_rules(self, enable, policy, proto, port,
                                     destination=None, rich_rule=None):
        add_del = { True: "-A", False: "-D" }[enable]
        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        rule_fragment = [ "-p", proto ]
        if port:
            rule_fragment += [ "--sport", "%s" % portStr(port) ]
        if destination:
            rule_fragment += [ "-d", destination ]
        if rich_rule:
            rule_fragment += self._rich_rule_destination_fragment(rich_rule.destination)
            rule_fragment += self._rich_rule_source_fragment(rich_rule.source)
        if not rich_rule or type(rich_rule.action) != Rich_Mark:
            rule_fragment += [ "-m", "conntrack", "--ctstate", "NEW,UNTRACKED" ]

        rules = []
        if rich_rule:
            rules.append(self._rich_rule_log(policy, rich_rule, enable, table, rule_fragment))
            rules.append(self._rich_rule_audit(policy, rich_rule, enable, table, rule_fragment))
            rules.append(self._rich_rule_action(policy, rich_rule, enable, table, rule_fragment))
        else:
            rules.append([add_del, "%s_allow" % (_policy), "-t", table] +
                         rule_fragment + [ "-j", "ACCEPT" ])

        return rules

    def build_policy_helper_ports_rules(self, enable, policy, proto, port,
                                      destination, helper_name, module_short_name):
        table = "raw"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
        add_del = { True: "-A", False: "-D" }[enable]

        rule = [ add_del, "%s_allow" % (_policy), "-t", "raw", "-p", proto ]
        if port:
            rule += [ "--dport", "%s" % portStr(port) ]
        if destination:
            rule += [ "-d",  destination ]
        rule += [ "-j", "CT", "--helper", module_short_name ]

        return [rule]

    def build_zone_forward_rules(self, enable, zone, policy, table, interface=None, source=None):
        add_del = { True: "-A", False: "-D" }[enable]
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        rules = []
        if interface:
            rules.append(["-t", "filter", add_del, "%s_allow" % _policy,
                          "-o", interface, "-j", "ACCEPT"])
        else: # source
            # iptables can not match destination MAC
            if check_mac(source):
                return []

            rules.append(["-t", "filter", add_del, "%s_allow" % _policy]
                         + self._rule_addr_fragment("-d", source) +
                         ["-j", "ACCEPT"])
        return rules

    def build_policy_masquerade_rules(self, enable, policy, rich_rule=None):
        table = "nat"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX, isSNAT=True)

        add_del = { True: "-A", False: "-D" }[enable]

        rule_fragment = []
        if rich_rule:
            chain_suffix = self._rich_rule_chain_suffix(rich_rule)
            rule_fragment += self._rich_rule_priority_fragment(rich_rule)
            rule_fragment += self._rich_rule_destination_fragment(rich_rule.destination)
            rule_fragment += self._rich_rule_source_fragment(rich_rule.source)
        else:
            chain_suffix = "allow"

        rules = []
        rules.append(["-t", "nat", add_del, "%s_%s" % (_policy, chain_suffix)]
                     + rule_fragment +
                     [ "!", "-o", "lo", "-j", "MASQUERADE" ])

        rule_fragment = []
        if rich_rule:
            chain_suffix = self._rich_rule_chain_suffix(rich_rule)
            rule_fragment += self._rich_rule_priority_fragment(rich_rule)
            rule_fragment += self._rich_rule_destination_fragment(rich_rule.destination)
            rule_fragment += self._rich_rule_source_fragment(rich_rule.source)
        else:
            chain_suffix = "allow"

        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
        rules.append(["-t", "filter", add_del, "%s_%s" % (_policy, chain_suffix)]
                     + rule_fragment +
                     ["-m", "conntrack", "--ctstate", "NEW,UNTRACKED", "-j", "ACCEPT" ])

        return rules

    def build_policy_forward_port_rules(self, enable, policy, port,
                                      protocol, toport, toaddr, rich_rule=None):
        table = "nat"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
        add_del = { True: "-A", False: "-D" }[enable]

        to = ""
        if toaddr:
            if check_single_address("ipv6", toaddr):
                to += "[%s]" % normalizeIP6(toaddr)
            else:
                to += toaddr
        if toport and toport != "":
            to += ":%s" % portStr(toport, "-")

        rule_fragment = []
        if rich_rule:
            chain_suffix = self._rich_rule_chain_suffix(rich_rule)
            rule_fragment = self._rich_rule_priority_fragment(rich_rule)
            rule_fragment += self._rich_rule_destination_fragment(rich_rule.destination)
            rule_fragment += self._rich_rule_source_fragment(rich_rule.source)
        else:
            chain_suffix = "allow"

        rules = []
        if rich_rule:
            rules.append(self._rich_rule_log(policy, rich_rule, enable, "nat", rule_fragment))
        rules.append(["-t", "nat", add_del, "%s_%s" % (_policy, chain_suffix)]
                     + rule_fragment +
                     ["-p", protocol, "--dport", portStr(port),
                      "-j", "DNAT", "--to-destination", to])

        return rules

    def build_policy_icmp_block_rules(self, enable, policy, ict, rich_rule=None):
        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
        add_del = { True: "-A", False: "-D" }[enable]

        if self.ipv == "ipv4":
            proto = [ "-p", "icmp" ]
            match = [ "-m", "icmp", "--icmp-type", ict.name ]
        else:
            proto = [ "-p", "ipv6-icmp" ]
            match = [ "-m", "icmp6", "--icmpv6-type", ict.name ]

        rules = []
        if self._fw.policy.query_icmp_block_inversion(policy):
            final_chain = "%s_allow" % (_policy)
            final_target = "ACCEPT"
        else:
            final_chain = "%s_deny" % (_policy)
            final_target = "%%REJECT%%"

        rule_fragment = []
        if rich_rule:
            rule_fragment += self._rich_rule_destination_fragment(rich_rule.destination)
            rule_fragment += self._rich_rule_source_fragment(rich_rule.source)
        rule_fragment += proto + match

        if rich_rule:
            rules.append(self._rich_rule_log(policy, rich_rule, enable, table, rule_fragment))
            rules.append(self._rich_rule_audit(policy, rich_rule, enable, table, rule_fragment))
            if rich_rule.action:
                rules.append(self._rich_rule_action(policy, rich_rule, enable, table, rule_fragment))
            else:
                chain_suffix = self._rich_rule_chain_suffix(rich_rule)
                rules.append(["-t", table, add_del, "%s_%s" % (_policy, chain_suffix)]
                             + self._rich_rule_priority_fragment(rich_rule)
                             + rule_fragment +
                             [ "-j", "%%REJECT%%" ])
        else:
            if self._fw.get_log_denied() != "off" and final_target != "ACCEPT":
                rules.append([ add_del, final_chain, "-t", table ]
                             + rule_fragment +
                             [ "%%LOGTYPE%%", "-j", "LOG",
                               "--log-prefix", "\"%s_ICMP_BLOCK: \"" % policy ])
            rules.append([ add_del, final_chain, "-t", table ]
                         + rule_fragment +
                         [ "-j", final_target ])

        return rules

    def build_policy_icmp_block_inversion_rules(self, enable, policy):
        table = "filter"
        _policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)

        rules = []
        rule_idx = 6

        if self._fw.policy.query_icmp_block_inversion(policy):
            ibi_target = "%%REJECT%%"

            if self._fw.get_log_denied() != "off":
                if enable:
                    rule = [ "-I", _policy, str(rule_idx) ]
                else:
                    rule = [ "-D", _policy ]

                rule = rule + [ "-t", table, "-p", "%%ICMP%%",
                              "%%LOGTYPE%%",
                              "-j", "LOG", "--log-prefix",
                              "\"%s_ICMP_BLOCK: \"" % _policy ]
                rules.append(rule)
                rule_idx += 1
        else:
            ibi_target = "ACCEPT"

        if enable:
            rule = [ "-I", _policy, str(rule_idx) ]
        else:
            rule = [ "-D", _policy ]
        rule = rule + [ "-t", table, "-p", "%%ICMP%%", "-j", ibi_target ]
        rules.append(rule)

        return rules

    def build_policy_rich_source_destination_rules(self, enable, policy, rich_rule):
        table = "filter"

        rule_fragment = []
        rule_fragment += self._rich_rule_destination_fragment(rich_rule.destination)
        rule_fragment += self._rich_rule_source_fragment(rich_rule.source)

        rules = []
        rules.append(self._rich_rule_log(policy, rich_rule, enable, table, rule_fragment))
        rules.append(self._rich_rule_audit(policy, rich_rule, enable, table, rule_fragment))
        rules.append(self._rich_rule_action(policy, rich_rule, enable, table, rule_fragment))

        return rules

    def is_ipv_supported(self, ipv):
        return ipv == self.ipv

class ip6tables(ip4tables):
    ipv = "ipv6"
    name = "ip6tables"

    def build_rpfilter_rules(self, log_denied=False):
        rules = []
        rules.append([ "-I", "PREROUTING", "-t", "mangle",
                       "-m", "rpfilter", "--invert", "--validmark",
                       "-j", "DROP" ])
        if log_denied != "off":
            rules.append([ "-I", "PREROUTING", "-t", "mangle",
                           "-m", "rpfilter", "--invert", "--validmark",
                           "-j", "LOG",
                           "--log-prefix", "rpfilter_DROP: " ])
        rules.append([ "-I", "PREROUTING", "-t", "mangle",
                       "-p", "ipv6-icmp",
                       "--icmpv6-type=neighbour-solicitation",
                       "-j", "ACCEPT" ]) # RHBZ#1575431, kernel bug in 4.16-4.17
        rules.append([ "-I", "PREROUTING", "-t", "mangle",
                       "-p", "ipv6-icmp",
                       "--icmpv6-type=router-advertisement",
                       "-j", "ACCEPT" ]) # RHBZ#1058505
        return rules

    def build_rfc3964_ipv4_rules(self):
        daddr_list = [
                     "::0.0.0.0/96", # IPv4 compatible
                     "::ffff:0.0.0.0/96", # IPv4 mapped
                     "2002:0000::/24", # 0.0.0.0/8 (the system has no address assigned yet)
                     "2002:0a00::/24", # 10.0.0.0/8 (private)
                     "2002:7f00::/24", # 127.0.0.0/8 (loopback)
                     "2002:ac10::/28", # 172.16.0.0/12 (private)
                     "2002:c0a8::/32", # 192.168.0.0/16 (private)
                     "2002:a9fe::/32", # 169.254.0.0/16 (IANA Assigned DHCP link-local)
                     "2002:e000::/19", # 224.0.0.0/4 (multicast), 240.0.0.0/4 (reserved and broadcast)
                     ]

        chain_name = "RFC3964_IPv4"
        self.our_chains["filter"].add(chain_name)

        rules = []
        rules.append(["-t", "filter", "-N", chain_name])
        for daddr in daddr_list:
            rules.append(["-t", "filter", "-I", chain_name,
                          "-d", daddr, "-j", "REJECT", "--reject-with",
                          "addr-unreach"])
            if self._fw._log_denied in ["unicast", "all"]:
                rules.append(["-t", "filter", "-I", chain_name,
                              "-d", daddr, "-j", "LOG",
                              "--log-prefix", "\"RFC3964_IPv4_REJECT: \""])

        # Inject into FORWARD and OUTPUT chains
        rules.append(["-t", "filter", "-I", "OUTPUT", "4",
                      "-j", chain_name])
        rules.append(["-t", "filter", "-I", "FORWARD", "4",
                      "-j", chain_name])
        return rules
core/modules.py000064400000007356150351351730007534 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""modules backend"""

__all__ = [ "modules" ]

from firewall.core.prog import runProg
from firewall.core.logger import log
from firewall.config import COMMANDS

class modules(object):
    def __init__(self):
        self._load_command = COMMANDS["modprobe"]
        # Use rmmod instead of modprobe -r (RHBZ#1031102)
        self._unload_command = COMMANDS["rmmod"]

    def __repr__(self):
        return '%s' % (self.__class__)

    def loaded_modules(self):
        """ get all loaded kernel modules and their dependencies """
        mods = [ ]
        deps = { }
        try:
            with open("/proc/modules", "r") as f:
                for line in f:
                    if not line:
                        break
                    line = line.strip()
                    splits = line.split()
                    mods.append(splits[0])
                    if splits[3] != "-":
                        deps[splits[0]] = splits[3].split(",")[:-1]
                    else:
                        deps[splits[0]] = [ ]
        except FileNotFoundError:
            pass

        return mods, deps # [loaded modules], {module:[dependants]}

    def load_module(self, module):
        log.debug2("%s: %s %s", self.__class__, self._load_command, module)
        return runProg(self._load_command, [ module ])

    def unload_module(self, module):
        log.debug2("%s: %s %s", self.__class__, self._unload_command, module)
        return runProg(self._unload_command, [ module ])

    def get_deps(self, module, deps, ret):
        """ get all dependants of a module """
        if module not in deps:
            return
        for mod in deps[module]:
            self.get_deps(mod, deps, ret)
            if mod not in ret:
                ret.append(mod)
        if module not in ret:
            ret.append(module)

    def get_firewall_modules(self):
        """ get all loaded firewall-related modules """
        mods = [ ]
        (mods2, deps) = self.loaded_modules()

        self.get_deps("nf_conntrack", deps, mods)
        # these modules don't have dependants listed in /proc/modules
        for bad_bad_module in ["nf_conntrack_ipv4", "nf_conntrack_ipv6"]:
            if bad_bad_module in mods:
                # move them to end of list, so we'll remove them later
                mods.remove(bad_bad_module)
                mods.insert(-1, bad_bad_module)

        for mod in mods2:
            if mod in [ "ip_tables", "ip6_tables", "ebtables" ] or \
               mod.startswith("iptable_") or mod.startswith("ip6table_") or \
               mod.startswith("nf_") or mod.startswith("xt_") or \
               mod.startswith("ipt_") or mod.startswith("ip6t_") :
                self.get_deps(mod, deps, mods)
        return mods

    def unload_firewall_modules(self):
        """ unload all firewall-related modules """
        for module in self.get_firewall_modules():
            (status, ret) = self.unload_module(module)
            if status != 0:
                log.debug1("Failed to unload module '%s': %s" %(module, ret))
core/__pycache__/fw_config.cpython-36.opt-1.pyc000064400000077161150351351730015251 0ustar003

��g��@s�dgZddlZddlZddlZddlZddlmZddlmZddl	m
Z
mZmZddl
mZmZmZddlmZmZmZddlmZmZmZdd	lmZmZmZdd
lmZmZm Z ddlm!Z!ddl"m#Z#Gd
d�de$�Z%dS)�FirewallConfig�N)�config)�log)�IcmpType�icmptype_reader�icmptype_writer)�Service�service_reader�service_writer)�Zone�zone_reader�zone_writer)�IPSet�ipset_reader�ipset_writer)�Helper�
helper_reader�
helper_writer)�Policy�
policy_reader�
policy_writer)�errors)�
FirewallErrorc@s$eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Zd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Z d=d>�Z!d?d@�Z"dAdB�Z#dCdD�Z$dEdF�Z%dGdH�Z&dIdJ�Z'dKdL�Z(dMdN�Z)dOdP�Z*dQdR�Z+dSdT�Z,dUdV�Z-dWdX�Z.dYdZ�Z/d[d\�Z0d]d^�Z1d_d`�Z2dadb�Z3dcdd�Z4dedf�Z5dgdh�Z6didj�Z7dkdl�Z8dmdn�Z9dodp�Z:dqdr�Z;dsdt�Z<dudv�Z=dwdx�Z>dydz�Z?d{d|�Z@d}d~�ZAdd��ZBd�d��ZCd�d��ZDd�d��ZEd�d��ZFd�d��ZGd�d��ZHd�d��ZId�d��ZJd�d��ZKd�d��ZLd�d��ZMd�d��ZNd�d��ZOd�d��ZPd�d��ZQd�d��ZRd�d��ZSd�d��ZTd�d��ZUd�d��ZVd�d��ZWd�d��ZXd�d��ZYd�d��ZZd�d��Z[d�d��Z\d�d��Z]d�d��Z^d�d��Z_d�d��Z`d�d��Zad�d��Zbd�d„Zcd�dĄZdd�dƄZed�S)�rcCs||_|j�dS)N)�_fw�_FirewallConfig__init_vars)�self�fw�r�/usr/lib/python3.6/fw_config.py�__init__(szFirewallConfig.__init__cCsHd|j|j|j|j|j|j|j|j|j|j	|j
|j|j|j
|j|jfS)Nz>%s(%r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r))�	__class__�_ipsets�
_icmptypes�	_services�_zones�_helpersZpolicy_objects�_builtin_ipsets�_builtin_icmptypes�_builtin_services�_builtin_zones�_builtin_helpers�_builtin_policy_objects�_firewalld_conf�	_policies�_direct)rrrr�__repr__,szFirewallConfig.__repr__cCs^i|_i|_i|_i|_i|_i|_i|_i|_i|_i|_	i|_
i|_d|_d|_
d|_dS)N)r!r"r#r$r%�_policy_objectsr&r'r(r)r*r+r,r-r.)rrrrZ__init_vars6szFirewallConfig.__init_varscCs4x,t|jj��D]}|j|j�|j|=qWx,t|jj��D]}|j|j�|j|=q>Wx,t|jj��D]}|j|j�|j|=qlWx,t|jj��D]}|j|j�|j|=q�Wx,t|jj��D]}|j|j�|j|=q�Wx,t|jj��D]}|j|j�|j|=q�Wx.t|j	j��D]}|j	|j�|j	|=�q$Wx.t|j
j��D]}|j
|j�|j
|=�qTWx.t|jj��D]}|j|j�|j|=�q�Wx.t|jj��D]}|j|j�|j|=�q�W|j
�r�|j
j�|`
d|_
|j�r|jj�|`d|_|j�r(|jj�|`d|_|j�dS)N)�listr&�keys�cleanupr!r'r"r(r#r)r$r*r%r,r-r.r)r�xrrrr3GsV


zFirewallConfig.cleanupcCs|jjj�S)N)r�policiesZquery_lockdown)rrrr�lockdown_enabled~szFirewallConfig.lockdown_enabledcCs|jjj||�S)N)rr5�access_check)r�key�valuerrrr7�szFirewallConfig.access_checkcCs
||_dS)N)r,)r�confrrr�set_firewalld_conf�sz!FirewallConfig.set_firewalld_confcCs|jS)N)r,)rrrr�get_firewalld_conf�sz!FirewallConfig.get_firewalld_confcCs(tjjtj�s|jj�n
|jj�dS)N)�os�path�existsrZFIREWALLD_CONFr,�clear�read)rrrr�update_firewalld_conf�sz$FirewallConfig.update_firewalld_confcCs
||_dS)N)r-)rr5rrr�set_policies�szFirewallConfig.set_policiescCs|jS)N)r-)rrrr�get_policies�szFirewallConfig.get_policiescCs,tjjtj�s|jjj�n|jjj�dS)N)	r=r>r?rZLOCKDOWN_WHITELISTr-Zlockdown_whitelistr3rA)rrrr�update_lockdown_whitelist�sz(FirewallConfig.update_lockdown_whitelistcCs
||_dS)N)r.)rZdirectrrr�
set_direct�szFirewallConfig.set_directcCs|jS)N)r.)rrrr�
get_direct�szFirewallConfig.get_directcCs(tjjtj�s|jj�n
|jj�dS)N)r=r>r?rZFIREWALLD_DIRECTr.r3rA)rrrr�
update_direct�szFirewallConfig.update_directcCs$ttt|jj��t|jj����S)N)�sorted�setr1r!r2r&)rrrr�
get_ipsets�szFirewallConfig.get_ipsetscCs$|jr||j|j<n||j|j<dS)N)�builtinr&�namer!)r�objrrr�	add_ipset�szFirewallConfig.add_ipsetcCs8||jkr|j|S||jkr(|j|Sttj|��dS)N)r!r&rr�
INVALID_IPSET)rrMrrr�	get_ipset�s




zFirewallConfig.get_ipsetcCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._ipsets[%s] != objz'%s' not a built-in ipset)rMr!rr�NO_DEFAULTSr&�
_remove_ipset)rrNrrr�load_ipset_defaults�s
z"FirewallConfig.load_ipset_defaultscCs|j�S)N)�
export_config)rrNrrr�get_ipset_config�szFirewallConfig.get_ipset_configcCsj|jrPtj|�}|j|�tj|_d|_|j|jkr:d|_|j|�t|�|S|j|�t|�|SdS)NF)	rL�copy�
import_configr�ETC_FIREWALLD_IPSETSr>�defaultrOr)rrNr:r4rrr�set_ipset_config�s



zFirewallConfig.set_ipset_configcCsx||jks||jkr$ttjd|��t�}|j|�|j|�||_d||_	t
j|_d|_
d|_t|�|j|�|S)Nznew_ipset(): '%s'z%s.xmlFT)r!r&rr�
NAME_CONFLICTr�
check_namerXrM�filenamerrYr>rLrZrrO)rrMr:r4rrr�	new_ipset�s




zFirewallConfig.new_ipsetcCs�tjj|�}tjj|�}tjj|�s�|tjkr�x�|jj�D]D}|j|}|j	|kr:|j|=|j
|jkrvd|j|j
fSd|fSq:WnHxF|jj�D]8}|j|}|j	|kr�|j|=|j
|jkr�d|fSdSq�WdStj
d|�yt||�}Wn0tk
�r}ztjd||�dSd}~XnX|j
|jk�rJ|j
|jk�rJ|j|�d|fS|tjk�r�|j
|jk�r�|j|j
j|_||j|j
<d|fS|j
|jk�r�|j|j
=||j|j
<|j
|jk�r�d|fSd	Sd
S)N�update�removezLoading ipset file '%s'z"Failed to load ipset file '%s': %s�new)NN)NN)NN)NN)NN)r=r>�basename�dirnamer?rrYr!r2r^rMr&r�debug1r�	Exception�errorrOrZ)rrMr^r>r4rN�msgrrr�update_ipset_from_path�sP






z%FirewallConfig.update_ipset_from_pathcCs�|j|jkrttj|j��|jtjkr>ttjd|jtjf��d|j|jf}yt	j
|d|�Wn:tk
r�}ztj
d||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' != '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr!rrrPr>rrY�INVALID_DIRECTORY�shutil�moverfrrgr=ra)rrNrMrhrrrrS8szFirewallConfig._remove_ipsetcCs$|js|jr ttjd|j��dS)Nz'%s' is built-in ipset)rLrZrrZ
BUILTIN_IPSETrM)rrNrrr�check_builtin_ipsetIsz"FirewallConfig.check_builtin_ipsetcCs|j|�|j|�dS)N)rmrS)rrNrrr�remove_ipsetNs
zFirewallConfig.remove_ipsetcCs$|j|�|j||�}|j|�|S)N)rm�_copy_ipsetrS)rrNrMr_rrr�rename_ipsetRs

zFirewallConfig.rename_ipsetcCs|j||j��S)N)r_rU)rrNrMrrrroXszFirewallConfig._copy_ipsetcCs$ttt|jj��t|jj����S)N)rIrJr1r"r2r')rrrr�
get_icmptypes]szFirewallConfig.get_icmptypescCs$|jr||j|j<n||j|j<dS)N)rLr'rMr")rrNrrr�add_icmptypeaszFirewallConfig.add_icmptypecCs8||jkr|j|S||jkr(|j|Sttj|��dS)N)r"r'rr�INVALID_ICMPTYPE)rrMrrr�get_icmptypegs




zFirewallConfig.get_icmptypecCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._icmptypes[%s] != objz'%s' not a built-in icmptype)rMr"rrrRr'�_remove_icmptype)rrNrrr�load_icmptype_defaultsns
z%FirewallConfig.load_icmptype_defaultscCs|j�S)N)rU)rrNrrr�get_icmptype_configzsz"FirewallConfig.get_icmptype_configcCsj|jrPtj|�}|j|�tj|_d|_|j|jkr:d|_|j|�t|�|S|j|�t|�|SdS)NF)	rLrWrXr�ETC_FIREWALLD_ICMPTYPESr>rZrrr)rrNr:r4rrr�set_icmptype_config}s



z"FirewallConfig.set_icmptype_configcCsx||jks||jkr$ttjd|��t�}|j|�|j|�||_d||_	t
j|_d|_
d|_t|�|j|�|S)Nznew_icmptype(): '%s'z%s.xmlFT)r"r'rrr\rr]rXrMr^rrxr>rLrZrrr)rrMr:r4rrr�new_icmptype�s




zFirewallConfig.new_icmptypecCs�tjj|�}tjj|�}tjj|�s�|tjkr�x�|jj�D]D}|j|}|j	|kr:|j|=|j
|jkrvd|j|j
fSd|fSq:WnHxF|jj�D]8}|j|}|j	|kr�|j|=|j
|jkr�d|fSdSq�WdStj
d|�yt||�}Wn0tk
�r}ztjd||�dSd}~XnX|j
|jk�rJ|j
|jk�rJ|j|�d|fS|tjk�r�|j
|jk�r�|j|j
j|_||j|j
<d|fS|j
|jk�r�|j|j
=||j|j
<|j
|jk�r�d|fSd	Sd
S)Nr`razLoading icmptype file '%s'z%Failed to load icmptype file '%s': %srb)NN)NN)NN)NN)NN)r=r>rcrdr?rrxr"r2r^rMr'rrerrfrgrrrZ)rrMr^r>r4rNrhrrr�update_icmptype_from_path�sP






z(FirewallConfig.update_icmptype_from_pathcCs�|j|jkrttj|j��|jtjkr>ttjd|jtjf��d|j|jf}yt	j
|d|�Wn:tk
r�}ztj
d||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' != '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr"rrrsr>rrxrjrkrlrfrrgr=ra)rrNrMrhrrrru�szFirewallConfig._remove_icmptypecCs$|js|jr ttjd|j��dS)Nz'%s' is built-in icmp type)rLrZrrZBUILTIN_ICMPTYPErM)rrNrrr�check_builtin_icmptype�sz%FirewallConfig.check_builtin_icmptypecCs|j|�|j|�dS)N)r|ru)rrNrrr�remove_icmptype�s
zFirewallConfig.remove_icmptypecCs$|j|�|j||�}|j|�|S)N)r|�_copy_icmptyperu)rrNrMrzrrr�rename_icmptype�s

zFirewallConfig.rename_icmptypecCs|j||j��S)N)rzrU)rrNrMrrrr~szFirewallConfig._copy_icmptypecCs$ttt|jj��t|jj����S)N)rIrJr1r#r2r()rrrr�get_services
szFirewallConfig.get_servicescCs$|jr||j|j<n||j|j<dS)N)rLr(rMr#)rrNrrr�add_serviceszFirewallConfig.add_servicecCs<||jkr|j|S||jkr(|j|Sttjd|��dS)Nzget_service(): '%s')r#r(rr�INVALID_SERVICE)rrMrrr�get_services




zFirewallConfig.get_servicecCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._services[%s] != objz'%s' not a built-in service)rMr#rrrRr(�_remove_service)rrNrrr�load_service_defaultss
z$FirewallConfig.load_service_defaultscCsr|j�}g}x\td�D]P}|j|d|krN|jtjt||j|d���q|j||j|d�qWt|�S)N�r)�export_config_dict�range�IMPORT_EXPORT_STRUCTURE�appendrW�deepcopy�getattr�tuple)rrN�	conf_dict�	conf_list�irrr�get_service_config's"z!FirewallConfig.get_service_configcCs|j�S)N)r�)rrNrrr�get_service_config_dict3sz&FirewallConfig.get_service_config_dictcCs�i}x&t|�D]\}}|||j|d<qW|jr|tj|�}|j|�tj|_d|_|j|jkrfd|_|j	|�t
|�|S|j|�t
|�|SdS)NrF)�	enumerater�rLrW�import_config_dictr�ETC_FIREWALLD_SERVICESr>rZr�r
)rrNr:r�r�r9r4rrr�set_service_config6s 



z!FirewallConfig.set_service_configcCsj|jrPtj|�}|j|�tj|_d|_|j|jkr:d|_|j|�t|�|S|j|�t|�|SdS)NF)	rLrWr�rr�r>rZr�r
)rrNr:r4rrr�set_service_config_dictJs



z&FirewallConfig.set_service_config_dictcCs�||jks||jkr$ttjd|��i}x&t|�D]\}}||tj|d<q2Wt�}|j|�|j	|�||_
d||_tj
|_d|_d|_t|�|j|�|S)Nznew_service(): '%s'rz%s.xmlFT)r#r(rrr\r�rr�r]r�rMr^rr�r>rLrZr
r�)rrMr:r�r�r9r4rrr�new_serviceZs"




zFirewallConfig.new_servicecCsx||jks||jkr$ttjd|��t�}|j|�|j|�||_d||_	t
j|_d|_
d|_t|�|j|�|S)Nznew_service(): '%s'z%s.xmlFT)r#r(rrr\rr]r�rMr^rr�r>rLrZr
r�)rrMr:r4rrr�new_service_dictqs




zFirewallConfig.new_service_dictcCs�tjj|�}tjj|�}tjj|�s�|tjkr�x�|jj�D]D}|j|}|j	|kr:|j|=|j
|jkrvd|j|j
fSd|fSq:WnHxF|jj�D]8}|j|}|j	|kr�|j|=|j
|jkr�d|fSdSq�WdStj
d|�yt||�}Wn0tk
�r}ztjd||�dSd}~XnX|j
|jk�rJ|j
|jk�rJ|j|�d|fS|tjk�r�|j
|jk�r�|j|j
j|_||j|j
<d|fS|j
|jk�r�|j|j
=||j|j
<|j
|jk�r�d|fSd	Sd
S)Nr`razLoading service file '%s'z$Failed to load service file '%s': %srb)NN)NN)NN)NN)NN)r=r>rcrdr?rr�r#r2r^rMr(rrer	rfrgr�rZ)rrMr^r>r4rNrhrrr�update_service_from_path�sP






z'FirewallConfig.update_service_from_pathcCs�|j|jkrttj|j��|jtjkr>ttjd|jtjf��d|j|jf}yt	j
|d|�Wn:tk
r�}ztj
d||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' != '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr#rrr�r>rr�rjrkrlrfrrgr=ra)rrNrMrhrrrr��szFirewallConfig._remove_servicecCs$|js|jr ttjd|j��dS)Nz'%s' is built-in service)rLrZrrZBUILTIN_SERVICErM)rrNrrr�check_builtin_service�sz$FirewallConfig.check_builtin_servicecCs|j|�|j|�dS)N)r�r�)rrNrrr�remove_service�s
zFirewallConfig.remove_servicecCs$|j|�|j||�}|j|�|S)N)r��
_copy_servicer�)rrNrMr�rrr�rename_service�s

zFirewallConfig.rename_servicecCs|j||j��S)N)r�r�)rrNrMrrrr��szFirewallConfig._copy_servicecCs$ttt|jj��t|jj����S)N)rIrJr1r$r2r))rrrr�	get_zones�szFirewallConfig.get_zonescCs$|jr||j|j<n||j|j<dS)N)rLr)rMr$)rrNrrr�add_zone�szFirewallConfig.add_zonecCs(||jkr|j|=||jkr$|j|=dS)N)r)r$)rrMrrr�forget_zone�s

zFirewallConfig.forget_zonecCs<||jkr|j|S||jkr(|j|Sttjd|��dS)Nzget_zone(): %s)r$r)rr�INVALID_ZONE)rrMrrr�get_zone�s




zFirewallConfig.get_zonecCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._zones[%s] != objz'%s' not a built-in zone)rMr$rrrRr)�_remove_zone)rrNrrr�load_zone_defaultss
z!FirewallConfig.load_zone_defaultscCsr|j�}g}x\td�D]P}|j|d|krN|jtjt||j|d���q|j||j|d�qWt|�S)N�r)r�r�r�r�rWr�r�r�)rrNr�r�r�rrr�get_zone_configs"zFirewallConfig.get_zone_configcCs|j�S)N)r�)rrNrrr�get_zone_config_dictsz#FirewallConfig.get_zone_config_dictcCs�i}x&t|�D]\}}|||j|d<qW|jr�tj|�}||_|j|�tj|_d|_|j|jkrld|_	|j
|�t|�|S||_|j|�t|�|SdS)NrF)r�r�rLrW�	fw_configr�r�ETC_FIREWALLD_ZONESr>rZr�r
)rrNr:r�r�r9r4rrr�set_zone_config s$



zFirewallConfig.set_zone_configcCsv|jrVtj|�}||_|j|�tj|_d|_|j|jkr@d|_|j|�t	|�|S||_|j|�t	|�|SdS)NF)
rLrWr�r�rr�r>rZr�r
)rrNr:r4rrr�set_zone_config_dict6s



z#FirewallConfig.set_zone_config_dictcCs�||jks||jkr$ttjd|��i}x&t|�D]\}}||tj|d<q2Wt�}||_|j	|�|j
|�||_d||_t
j|_d|_d|_t|�|j|�|S)Nznew_zone(): '%s'rz%s.xmlFT)r$r)rrr\r�rr�r�r]r�rMr^rr�r>rLrZr
r�)rrMr:r�r�r9r4rrr�new_zoneHs"



zFirewallConfig.new_zonecCs~||jks||jkr$ttjd|��t�}||_|j|�|j|�||_	d||_
tj|_
d|_d|_t|�|j|�|S)Nznew_zone(): '%s'z%s.xmlFT)r$r)rrr\rr�r]r�rMr^rr�r>rLrZr
r�)rrMr:r4rrr�
new_zone_dict_s



zFirewallConfig.new_zone_dictcCstjj|�}tjj|�}tjj|�s�|jtj�r�x�|jj	�D]D}|j|}|j
|kr<|j|=|j|jkrxd|j|jfSd|fSq<WnHxF|jj	�D]8}|j|}|j
|kr�|j|=|j|jkr�d|fSd	Sq�Wd
St
jd|�yt||�}Wn0tk
�r}zt
jd||�dSd}~XnX||_|jtj��rlt|�ttj�k�rldtjj|�tjj|�dd�f|_|j|jk�r�|j|jk�r�|j|�d|fS|jtj��r�|j|jk�r�|j|jj|_||j|j<d|fS|j|jk�r|j|j=||j|j<|j|jk�rd|fSd
SdS)Nr`razLoading zone file '%s'z!Failed to load zone file '%s': %sz%s/%sr�rb)NN)NN)NN���)NN)NN)r=r>rcrdr?�
startswithrr�r$r2r^rMr)rrerrfrgr��lenr�rZ)rrMr^r>r4rNrhrrr�update_zone_from_pathrsZ





z$FirewallConfig.update_zone_from_pathcCs�|j|jkrttj|j��|jjtj�s@ttj	d|jtjf��d|j|jf}yt
j|d|�Wn:tk
r�}zt
jd||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' doesn't start with '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr$rrr�r>r�rr�rjrkrlrfrrgr=ra)rrNrMrhrrrr��szFirewallConfig._remove_zonecCs$|js|jr ttjd|j��dS)Nz'%s' is built-in zone)rLrZrrZBUILTIN_ZONErM)rrNrrr�check_builtin_zone�sz!FirewallConfig.check_builtin_zonecCs|j|�|j|�dS)N)r�r�)rrNrrr�remove_zone�s
zFirewallConfig.remove_zonec	CsN|j|�|j�}|j|�y|j||�}Wn|j|j|��YnX|S)N)r�r�r�r�rM)rrNrMZobj_confr�rrr�rename_zone�s

zFirewallConfig.rename_zonecCs$ttt|jj��t|jj����S)N)rIrJr1r0r2r+)rrrr�get_policy_objects�sz!FirewallConfig.get_policy_objectscCs$|jr||j|j<n||j|j<dS)N)rLr+rMr0)rrNrrr�add_policy_object�sz FirewallConfig.add_policy_objectcCs<||jkr|j|S||jkr(|j|Sttjd|��dS)Nzget_policy_object(): %s)r0r+rr�INVALID_POLICY)rrMrrr�get_policy_object�s




z FirewallConfig.get_policy_objectcCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._policy_objects[%s] != objz'%s' not a built-in policy)rMr0rrrRr+�_remove_policy_object)rrNrrr�load_policy_object_defaults�s
z*FirewallConfig.load_policy_object_defaultscCs|j�S)N)r�)rrNrrr�get_policy_object_config_dictsz,FirewallConfig.get_policy_object_config_dictcCsv|jrVtj|�}||_|j|�tj|_d|_|j|jkr@d|_|j|�t	|�|S||_|j|�t	|�|SdS)NF)
rLrWr�r�r�ETC_FIREWALLD_POLICIESr>rZr�r)rrNr:r4rrr�set_policy_object_config_dicts



z,FirewallConfig.set_policy_object_config_dictcCs~||jks||jkr$ttjd|��t�}||_|j|�|j|�||_	d||_
tj|_
d|_d|_t|�|j|�|S)Nznew_policy_object(): '%s'z%s.xmlFT)r0r+rrr\rr�r]r�rMr^rr�r>rLrZrr�)rrMr:r4rrr�new_policy_object_dicts



z%FirewallConfig.new_policy_object_dictcCstjj|�}tjj|�}tjj|�s�|jtj�r�x�|jj	�D]D}|j|}|j
|kr<|j|=|j|jkrxd|j|jfSd|fSq<WnHxF|jj	�D]8}|j|}|j
|kr�|j|=|j|jkr�d|fSd	Sq�Wd
St
jd|�yt||�}Wn0tk
�r}zt
jd||�dSd}~XnX||_|jtj��rlt|�ttj�k�rldtjj|�tjj|�dd�f|_|j|jk�r�|j|jk�r�|j|�d|fS|jtj��r�|j|jk�r�|j|jj|_||j|j<d|fS|j|jk�r|j|j=||j|j<|j|jk�rd|fSd
SdS)Nr`razLoading policy file '%s'z#Failed to load policy file '%s': %sz%s/%srr�rb)NN)NN)NNr�)NN)NN)r=r>rcrdr?r�rr�r0r2r^rMr+rrerrfrgr�r�r�rZ)rrMr^r>r4rNrhrrr�update_policy_object_from_path,sZ





z-FirewallConfig.update_policy_object_from_pathcCs�|j|jkrttj|j��|jjtj�s@ttj	d|jtjf��d|j|jf}yt
j|d|�Wn:tk
r�}zt
jd||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' doesn't start with '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr0rrr�r>r�rr�rjrkrlrfrrgr=ra)rrNrMrhrrrr�ysz$FirewallConfig._remove_policy_objectcCs$|js|jr ttjd|j��dS)Nz'%s' is built-in policy)rLrZrrZBUILTIN_POLICYrM)rrNrrr�check_builtin_policy_object�sz*FirewallConfig.check_builtin_policy_objectcCs|j|�|j|�dS)N)r�r�)rrNrrr�remove_policy_object�s
z#FirewallConfig.remove_policy_objectcCs$|j|�|j||�}|j|�|S)N)r��_copy_policy_objectr�)rrNrMZnew_policy_objectrrr�rename_policy_object�s

z#FirewallConfig.rename_policy_objectcCs|j||j��S)N)r�r�)rrNrMrrrr��sz"FirewallConfig._copy_policy_objectcCs$ttt|jj��t|jj����S)N)rIrJr1r%r2r*)rrrr�get_helpers�szFirewallConfig.get_helperscCs$|jr||j|j<n||j|j<dS)N)rLr*rMr%)rrNrrr�
add_helper�szFirewallConfig.add_helpercCs8||jkr|j|S||jkr(|j|Sttj|��dS)N)r%r*rr�INVALID_HELPER)rrMrrr�
get_helper�s




zFirewallConfig.get_helpercCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._helpers[%s] != objz'%s' not a built-in helper)rMr%rrrRr*�_remove_helper)rrNrrr�load_helper_defaults�s
z#FirewallConfig.load_helper_defaultscCs|j�S)N)rU)rrNrrr�get_helper_config�sz FirewallConfig.get_helper_configcCsj|jrPtj|�}|j|�tj|_d|_|j|jkr:d|_|j|�t|�|S|j|�t|�|SdS)NF)	rLrWrXr�ETC_FIREWALLD_HELPERSr>rZr�r)rrNr:r4rrr�set_helper_config�s



z FirewallConfig.set_helper_configcCsx||jks||jkr$ttjd|��t�}|j|�|j|�||_d||_	t
j|_d|_
d|_t|�|j|�|S)Nznew_helper(): '%s'z%s.xmlFT)r%r*rrr\rr]rXrMr^rr�r>rLrZrr�)rrMr:r4rrr�
new_helper�s




zFirewallConfig.new_helpercCs�tjj|�}tjj|�}tjj|�s�|tjkr�x�|jj�D]D}|j|}|j	|kr:|j|=|j
|jkrvd|j|j
fSd|fSq:WnHxF|jj�D]8}|j|}|j	|kr�|j|=|j
|jkr�d|fSdSq�WdStj
d|�yt||�}Wn0tk
�r}ztjd||�dSd}~XnX|j
|jk�rJ|j
|jk�rJ|j|�d|fS|tjk�r�|j
|jk�r�|j|j
j|_||j|j
<d|fS|j
|jk�r�|j|j
=||j|j
<|j
|jk�r�d|fSd	Sd
S)Nr`razLoading helper file '%s'z#Failed to load helper file '%s': %srb)NN)NN)NN)NN)NN)r=r>rcrdr?rr�r%r2r^rMr*rrerrfrgr�rZ)rrMr^r>r4rNrhrrr�update_helper_from_path�sP






z&FirewallConfig.update_helper_from_pathcCs�|j|jkrttj|j��|jtjkr>ttjd|jtjf��d|j|jf}yt	j
|d|�Wn:tk
r�}ztj
d||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' != '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr%rrr�r>rr�rjrkrlrfrrgr=ra)rrNrMrhrrrr�&szFirewallConfig._remove_helpercCs$|js|jr ttjd|j��dS)Nz'%s' is built-in helper)rLrZrrZBUILTIN_HELPERrM)rrNrrr�check_builtin_helper7sz#FirewallConfig.check_builtin_helpercCs|j|�|j|�dS)N)r�r�)rrNrrr�
remove_helper<s
zFirewallConfig.remove_helpercCs$|j|�|j||�}|j|�|S)N)r��_copy_helperr�)rrNrMr�rrr�
rename_helper@s

zFirewallConfig.rename_helpercCs|j||j��S)N)r�rU)rrNrMrrrr�FszFirewallConfig._copy_helperN)f�__name__�
__module__�__qualname__rr/rr3r6r7r;r<rBrCrDrErFrGrHrKrOrQrTrVr[r_rirSrmrnrprorqrrrtrvrwryrzr{rur|r}rr~r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrrr's�
7EEEMME)&�__all__rWr=Zos.pathrkZfirewallrZfirewall.core.loggerrZfirewall.core.io.icmptyperrrZfirewall.core.io.servicerr	r
Zfirewall.core.io.zonerrr
Zfirewall.core.io.ipsetrrrZfirewall.core.io.helperrrrZfirewall.core.io.policyrrrrZfirewall.errorsr�objectrrrrr�<module>score/__pycache__/ipXtables.cpython-36.opt-1.pyc000064400000104137150351351730015235 0ustar003

��g���@s(ddlZddlZddlmZddlmZddlmZm	Z	m
Z
mZmZm
Z
mZmZddlmZddlmZmZmZmZmZddlmZmZmZmZmZmZmZddl Z dZ!d	d
dgdd
gdd
d	d
dgdd
d
gd	d
dgd�Z"ddd�Z#ddd�Z$dd�Z%dd�Z&dd�Z'Gdd�de(�Z)Gdd�de)�Z*dS)�N)�runProg)�log)�tempFile�readfile�	splitArgs�	check_mac�portStr�check_single_address�
check_address�normalizeIP6)�config)�
FirewallError�INVALID_PASSTHROUGH�INVALID_RULE�
UNKNOWN_ERROR�INVALID_ADDR)�Rich_Accept�Rich_Reject�	Rich_Drop�	Rich_Mark�Rich_Masquerade�Rich_ForwardPort�Rich_IcmpBlock��INPUT�OUTPUT�FORWARD�
PREROUTING�POSTROUTING)�security�raw�mangle�nat�filterzicmp-host-prohibitedzicmp6-adm-prohibited)�ipv4�ipv6�icmpz	ipv6-icmpcCs�ddddddd�}|dd�}x~|D]v}y|j|�}Wntk
rLw$YnX|d
kr�yt||d	�Wntk
r~YnX|j|d	�||||<q$W|S)z Inverse valid rule z-Dz--deletez-Xz--delete-chain)z-Az--appendz-Iz--insertz-Nz--new-chainN�-I�--insert�)r'r()�index�	Exception�int�pop)�args�replace_args�ret_args�arg�idx�r3�/usr/lib/python3.6/ipXtables.py�common_reverse_rule9s(
r5cCs�ddddddd�}|dd�}x�|D]x}y|j|�}Wntk
rLw$YnX|dkr�yt||d	�Wntk
r~YnX|j|d	�||||<|SWttd
��dS)z Reverse valid passthough rule z-Dz--deletez-Xz--delete-chain)z-Az--appendz-Iz--insertz-Nz--new-chainN�-I�--insertr)zno '-A', '-I' or '-N' arg)r6r7)r*�
ValueErrorr,r-r
r)r.r/r0�xr2r3r3r4�common_reverse_passthrough^s,
r:cCs�t|�}tddddddddd	d
ddd
dddddddg�}t||@�dkrbttdt||@�d��tddddddg�}t||@�dkr�ttd��dS)zZ Check if passthough rule is valid (only add, insert and new chain
    rules are allowed) z-Cz--checkz-Dz--deletez-Rz	--replacez-Lz--listz-Sz--list-rulesz-Fz--flushz-Zz--zeroz-Xz--delete-chainz-Pz--policyz-Ez--rename-chainrzarg '%s' is not allowedz-Az--appendz-Iz--insertz-Nz--new-chainzno '-A', '-I' or '-N' argN)�set�lenr
r�list)r.Znot_allowedZneededr3r3r4�common_check_passthrough�s*

r>c@s�eZdZdZdZdZdd�Zdd�Zdd�Zd	d
�Z	dd�Z
d
d�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �Zdhd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zdid,d-�Zd.d/�Zdjd1d2�Zd3d4�Zd5d6�Zdkd8d9�Zdld:d;�Z d<d=�Z!d>d?�Z"d@dA�Z#dBdC�Z$dDdE�Z%dFdG�Z&dHdI�Z'dJdK�Z(dLdM�Z)dNdO�Z*dPdQ�Z+dmdRdS�Z,dndTdU�Z-dodVdW�Z.dXdY�Z/dpdZd[�Z0dqd\d]�Z1drd^d_�Z2dsd`da�Z3dbdc�Z4ddde�Z5dfdg�Z6d!S)t�	ip4tablesr$TcCsd||_tj|j|_tjd|j|_|j�|_|j�|_	|j
�g|_i|_i|_
g|_i|_dS)Nz
%s-restore)�_fwrZCOMMANDS�ipv�_command�_restore_command�_detect_wait_option�wait_option�_detect_restore_wait_option�restore_wait_option�fill_exists�available_tables�rich_rule_priority_counts�policy_priority_counts�zone_source_index_cache�
our_chains)�self�fwr3r3r4�__init__�s

zip4tables.__init__cCs$tjj|j�|_tjj|j�|_dS)N)�os�path�existsrBZcommand_existsrCZrestore_command_exists)rNr3r3r4rH�szip4tables.fill_existscCs�|jr(|j|kr(|jgdd�|D�}ndd�|D�}tjd|j|jdj|��t|j|�\}}|dkr�td|jdj|�|f��|S)NcSsg|]}d|�qS)z%sr3)�.0�itemr3r3r4�
<listcomp>�sz#ip4tables.__run.<locals>.<listcomp>cSsg|]}d|�qS)z%sr3)rTrUr3r3r4rV�sz	%s: %s %s� rz'%s %s' failed: %s)rEr�debug2�	__class__rB�joinrr8)rNr.Z_args�status�retr3r3r4Z__run�szip4tables.__runc
Cs<y|j|�}Wntk
r"dSX||||d�<dSdS)NF�T)r*r8)rN�rule�patternZreplacement�ir3r3r4�
_rule_replace�szip4tables._rule_replacecCs|tko|t|kS)N)�BUILT_IN_CHAINS)rNrA�table�chainr3r3r4�is_chain_builtin�szip4tables.is_chain_builtincCs2d|g}|r|jd�n
|jd�|j|�|gS)Nz-tz-Nz-X)�append)rN�addrcrdr^r3r3r4�build_chain_rules�s

zip4tables.build_chain_rulescCs8d|g}|r |d|t|�g7}n|d|g7}||7}|S)Nz-tz-Iz-D)�str)rNrgrcrdr*r.r^r3r3r4�
build_rule�szip4tables.build_rulecCst|�S)N)r5)rNr.r3r3r4�reverse_rule�szip4tables.reverse_rulecCst|�dS)N)r>)rNr.r3r3r4�check_passthrough�szip4tables.check_passthroughcCst|�S)N)r:)rNr.r3r3r4�reverse_passthrough�szip4tables.reverse_passthroughcCs�d}y|jd�}Wntk
r&YnXt|�|dkrD||d}d}xLd
D]D}y|j|�}Wntk
rtYqNXt|�|dkrN||d}qNW||fS)Nr#z-tr]�-A�--append�-I�--insert�-N�--new-chain)rnrorprqrrrs)r*r8r<)rNr.rcr`rd�optr3r3r4�passthrough_parse_table_chain�s$z'ip4tables.passthrough_parse_table_chaincCs4yH|jd�}|j|�|j|�}d|dkr:||df}n||df}WnFtk
r�y|jd�}|j|�d}Wntk
r�dSXYnXd}|ddkr�d}|r�|r�||kr�|j|�nn|�r0|�r�||kr�|j|�|jdd
�d�|j|�}n|jj�rd}nt|�}d|d<|j	dd|d�dS)Nz%%ZONE_SOURCE%%z-m���z%%ZONE_INTERFACE%%Tr�-D�--deleteFcSs|dS)Nrr3)r9r3r3r4�<lambda>&sz4ip4tables._run_replace_zone_source.<locals>.<lambda>)�keyz-Ir)z%dr])ryrz)
r*r-r8�removerf�sortr@�_allow_zone_driftingr<�insert)rNr^rLr`�zoneZzone_source�rule_addr*r3r3r4�_run_replace_zone_source	s>







z"ip4tables._run_replace_zone_sourcecCsy|j|�}Wntk
r$Y�n�Xd}d}d}|j|�|j|�}t|�tkr\ttd��d}	xLdD]D}
y|j|
�}Wntk
r�YqfXt|�|dkrf||d}	qfWxhdD]`}
y|j|
�}Wntk
r�Yq�Xt|�|dk�r�||d}|
dk�rd}|
dkr�d}q�W|	|f}|�sp||k�sP|||k�sP|||dk�rZttd��|||d8<n�||k�r�i||<|||k�r�d|||<d}
xHt	||j
��D]4}||k�r�|�r�P|
|||7}
||k�r�P�q�W|||d7<d
||<|j|dd|
�dS)a
        Change something like
          -t filter -I public_IN %%RICH_RULE_PRIORITY%% 123
        or
          -t filter -A public_IN %%RICH_RULE_PRIORITY%% 321
        into
          -t filter -I public_IN 4
        or
          -t filter -I public_IN
        TFr]z%priority must be followed by a numberr#�-t�--table�-A�--append�-I�--insert�-D�--deleterz*nonexistent or underflow of priority countr)z%dN���)r�r�)r�r�r�r�r�r�)r�r�)r�r�)r*r8r-�typer,r
rr<r�sorted�keysr�)rNr^Zpriority_counts�tokenr`r�r�Zinsert_add_index�priorityrcrt�jrdr*�pr3r3r4�_set_rule_replace_priority2sj








z$ip4tables._set_rule_replace_prioritycCsPt�}i}tj|j�}tj|j�}tj|j�}�x�|D�]�}|dd�}	|j|	dddt|jg�|j|	dt	|jg�y|	j
d�}
Wntk
r�Yn8X|dkr�q6|d$kr�d
dd|g|	|
|
d
�<n
|	j|
�|j
|	|d�|j
|	|d�|j|	|�d}xZd%D]R}y|	j
|�}
Wntk
�r,Yn(Xt|	�|
d
k�r|	j|
�|	j|
�}�qWxhtt|	��D]X}
xPtjD]F}
|
|	|
k�rt|	|
jd��o�|	|
jd��rtd|	|
|	|
<�qtW�qhW|j|g�j|	�q6WxR|D]J}||}|jd|�x"|D]}	|jdj|	�d��qW|jd��q�W|j�tj|j�}tjd|j|j d|j|j!f�g}|j"�rz|j|j"�|jd�t#|j ||jd�\}}tj$�dk�r
t%|j�}|dk	�r
d
}
xH|D]@}tj&d|
|fd
dd �|jd��s�tj&d!d
d"�|
d
7}
�q�Wtj'|j�|dk�r:td#|j dj|�|f��||_||_||_dS)&Nz
%%REJECT%%�REJECTz
--reject-withz%%ICMP%%z%%LOGTYPE%%�off�unicast�	broadcast�	multicastz-m�pkttypez
--pkt-typer]z%%RICH_RULE_PRIORITY%%z%%POLICY_PRIORITY%%r#�-t�--table�"z"%s"z*%s
rW�
zCOMMIT
z	%s: %s %sz%s: %dz-n)�stdinr)z%8d: %sr)�nofmt�nlr)r�z'%s %s' failed: %s)r�r�r�)r�r�)(r�copy�deepcopyrJrKrLra�DEFAULT_REJECT_TYPErA�ICMPr*r8r-r�r�r<�range�stringZ
whitespace�
startswith�endswith�
setdefaultrf�writerZ�closerQ�stat�namerrXrYrC�st_sizerGrZgetDebugLogLevelrZdebug3�unlink)rN�rules�
log_denied�	temp_fileZtable_rulesrJrKrLZ_ruler^r`rcrt�cr�r.r[r\�lines�liner3r3r4�	set_rules�s�









zip4tables.set_rulesc
Cs�|j|dddt|jg�|j|dt|jg�y|jd�}Wntk
rRYn:X|dkr`dS|dkr�ddd
|g|||d�<n
|j|�tj|j	�}tj|j
�}tj|j�}|j||d�|j||d�|j
||�|j|�}||_	||_
||_|S)Nz
%%REJECT%%r�z
--reject-withz%%ICMP%%z%%LOGTYPE%%r�rr�r�r�z-mr�z
--pkt-typer]z%%RICH_RULE_PRIORITY%%z%%POLICY_PRIORITY%%)r�r�r�)rar�rAr�r*r8r-r�r�rJrKrLr�r��_ip4tables__run)rNr^r�r`rJrKrL�outputr3r3r4�set_rule�s.

zip4tables.set_ruleNcCs�g}|r|gntj�}xx|D]p}||jkr6|j|�qy,|jd|ddg�|jj|�|j|�Wqtk
r�tjd|j|f�YqXqW|S)Nz-tz-Lz-nzA%s table '%s' does not exist (or not enough permission to check).)	rbr�rIrfr�r8r�debug1rA)rNrcr\Ztablesr3r3r4�get_available_tabless

zip4tables.get_available_tablescCs`d}t|jdddg�}|ddkr\d}t|jdddg�}|ddkrHd}tjd|j|j|�|S)Nrz-wz-Lz-nrz-w10z%s: %s will be using %s option.)rrBrrXrY)rNrEr\r3r3r4rDszip4tables._detect_wait_optioncCs�t�}|jd�|j�d}xJdD]B}t|j|g|jd�}|ddkr"d|dkr"d	|dkr"|}Pq"Wtjd
|j|j|�t	j
|j�|S)Nz#foor�-w�--wait=2)r�rzinvalid optionr]zunrecognized optionz%s: %s will be using %s option.)r�r�)rr�r�rrCr�rrXrYrQr�)rNr�rEZtest_optionr\r3r3r4rF"s

z%ip4tables._detect_restore_wait_optioncCsVi|_i|_g|_g}x:tj�D].}|j|�s0q xdD]}|jd||g�q6Wq W|S)N�-F�-X�-Zz-t)r�r�r�)rJrKrLrbr�r�rf)rNr�rc�flagr3r3r4�build_flush_rules5s

zip4tables.build_flush_rulescCsfg}|dkrdn|}xLtj�D]@}|j|�s.q|dkr8qx$t|D]}|jd|d||g�qBWqW|S)NZPANIC�DROPr"z-tz-P)rbr�r�rf)rN�policyr��_policyrcrdr3r3r4�build_set_policy_rulesDs
z ip4tables.build_set_policy_rulescCs g}d}y"|jd|jdkrdnddg�}WnJtk
rt}z.|jdkrVtjd|�ntjd|�WYd	d	}~XnX|j�}d
}x�|D]�}|r�|j�j�}|j�}xD|D]<}	|	j	d�r�|	j
d�r�|	d
d�}
n|	}
|
|kr�|j|
�q�W|jdko�|j	d��s|jdkr�|j	d�r�d}q�W|S)zQReturn ICMP types that are supported by the iptables/ip6tables command and kernelrz-pr$r&z	ipv6-icmpz--helpziptables error: %szip6tables error: %sNF�(�)r]zValid ICMP Types:r%zValid ICMPv6 Types:Tr�)r�rAr8rr��
splitlines�strip�lower�splitr�r�rf)rNrAr\r�Zexr�Zin_typesr�Zsplitsr�r9r3r3r4�supported_icmp_typesPs4
 

zip4tables.supported_icmp_typescCsgS)Nr3)rNr3r3r4�build_default_tablesqszip4tables.build_default_tablesr�c	Csi}|jd�rpg|d<t�|jd<xLtdD]@}|djd|�|djd||f�|jdjd|�q,W|jd��r\g|d<t�|jd<x�tdD]�}|djd|�|djd||f�|jdjd|�|dkr�xt|jjr�ddd	d
gndd	d
gD]R}|djd||f�|djd|||f�|jdjtd
||fg���qWq�W|jd��rNg|d<t�|jd<x�tdD]�}|djd|�|djd||f�|jdjd|�|dk�r�xv|jj�r�ddd	d
gndd	d
gD]R}|djd||f�|djd|||f�|jdjtd
||fg���q�W�q�W|jd��r@g|d<t�|jd<x�tdD]�}|djd|�|djd||f�|jdjd|�|d9k�rxxv|jj�r�ddd	d
gndd	d
gD]R}|djd||f�|djd|||f�|jdjtd
||fg���q�W�qxWg|d<t�|jd<|djd�|djd�|djd�|djd�|jdjtd��xf|jj�r�ddd	d
gndd	d
gD]B}|djd|�|djd|�|jdjtd|���q�W|dk�r |djd�|djd�|dk�rF|djd�|djd�|djd�|djd �|djd!�|djd"�|jdjtd#��xJd:D]B}|djd$|�|djd%|�|jdjtd&|���q�Wxzd;D]r}xj|jj�r
dd	gnd	gD]N}|djd)||f�|djd*||f�|jdjtd+||f���qW�q�WxJd<D]B}|djd$|�|djd%|�|jdjtd&|���qnW|dk�r�|djd,�|djd-�|dk�r�|djd.�|djd/�|dd0d1d2d3g7<|jdjtd4��xJd=D]B}|djd5|�|djd6|�|jdjtd7|���q2WxJd>D]B}|djd5|�|djd6|�|jdjtd7|���q~Wg}xJ|D]B}||j�k�r�q�x(||D]}|jd8|gt	|���q�W�q�W|S)?Nrz-N %s_directz-A %s -j %s_directz	%s_directr r�POLICIES_preZZONES_SOURCEZZONES�
POLICIES_postz-N %s_%sz-A %s -j %s_%sz%s_%sr!r"rr#zB-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPTz-A INPUT -i lo -j ACCEPTz-N INPUT_directz-A INPUT -j INPUT_directZINPUT_directz-N INPUT_%sz-A INPUT -j INPUT_%szINPUT_%sr�z^-A INPUT -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: 'z/-A INPUT -m conntrack --ctstate INVALID -j DROPz9-A INPUT %%LOGTYPE%% -j LOG --log-prefix 'FINAL_REJECT: 'z-A INPUT -j %%REJECT%%zD-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPTz-A FORWARD -i lo -j ACCEPTz-N FORWARD_directz-A FORWARD -j FORWARD_directZFORWARD_directz
-N FORWARD_%sz-A FORWARD -j FORWARD_%sz
FORWARD_%s�IN�OUTz-N FORWARD_%s_%sz-A FORWARD -j FORWARD_%s_%sz
FORWARD_%s_%sz`-A FORWARD -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: 'z1-A FORWARD -m conntrack --ctstate INVALID -j DROPz;-A FORWARD %%LOGTYPE%% -j LOG --log-prefix 'FINAL_REJECT: 'z-A FORWARD -j %%REJECT%%z-N OUTPUT_directz>-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPTz-A OUTPUT -o lo -j ACCEPTz-A OUTPUT -j OUTPUT_directZ
OUTPUT_directz-N OUTPUT_%sz-A OUTPUT -j OUTPUT_%sz	OUTPUT_%sz-t)rr)r�)r�r�)r�)r�)r�)
r�r;rMrbrfrgr@r�updater)	rNr�Z
default_rulesrdZdispatch_suffix�	directionZfinal_default_rulesrcr^r3r3r4�build_default_rulesus�
$(
&*
&*&



(






"zip4tables.build_default_rulescCsf|dkrdddhS|dkr,d|j�kr,dhS|dkrHd|j�krHddhS|d	krbd	|j�krbdhSiS)
Nr#r�
FORWARD_IN�FORWARD_OUTr!rr"rr )r�)rNrcr3r3r4�get_zone_table_chains�s
zip4tables.get_zone_table_chainsc	s�|jjj|���jdkrdnd��dkr4�dkr4dnd}	|jjj|�t|	��g}
g}x|D]}|
jd|g�qZWx|D]}|jd	|g�qvWxB|D]:}
|jjj|
�}|dkr�|j	|�r�q�|
j|j
d|
��q�Wx\|D]T}
|jjj|
�}|dk�r|j	|��rq�t|
��r�dk�rq�|j|j
d|
��q�W������fdd�}g}|
�r�x�|
D]F}|�r�x8|D]}|j|||���qdWn|�r�n|j||d���qTWnH|�r�n@|�r�x8|D]}|j|d|���q�Wn|�r�n|j|dd��|S)Nr�pre�postr"rTFz-iz-or$r%z-sr�rz-dcsVddd��}d�|d��fd�jg}|r6|j|�|rD|j|�|jd�g�|S)Nz-Az-D)TFz-tz%s_POLICIES_%sz%%POLICY_PRIORITY%%z-j)r��extend)�ingress_fragment�egress_fragment�add_delr^)r�rd�chain_suffix�enable�p_objrcr3r4�_generate_policy_dispatch_rules


zSip4tables.build_policy_ingress_egress_rules.<locals>._generate_policy_dispatch_rule)r$r%)r$r%)rr�r)r@r�Z
get_policyr��policy_base_chain_name�POLICY_CHAIN_PREFIXrfr�Zcheck_source�is_ipv_supported�_rule_addr_fragmentr)rNr�r�rcrdZingress_interfacesZegress_interfacesZingress_sourcesZegress_sources�isSNATZingress_fragmentsZegress_fragments�	interface�addrrAr�r�r�r�r3)r�rdr�r�r�rcr4�!build_policy_ingress_egress_rules�sR






z+ip4tables.build_policy_ingress_egress_rulesFc
Cs�|dkr|dkrdnd}|jjj||t|d�}	ddddddd�|}
d	}|rb|rbd
d|dg}n,|rtd
d|g}ndd|g}|s�|dg7}|d||
|||	g7}|gS)Nr"rTF)r�z-iz-o)rrrr�r�rz-gz-Iz%s_ZONESz%%ZONE_INTERFACE%%z-Az-Dz-t)r@r�r�r�)
rNr�r�r�r�rcrdrfr�r�rt�actionr^r3r3r4�!build_zone_source_interface_rulesKs&

z+ip4tables.build_zone_source_interface_rulescCs�|jd�rP|dd�}|dkr$d}nd}dj|g|jjj|��}ddd	||gSt|�rz|dkrjttd
��ddd|j�gSt	d
|�r�t
|�}n,td
|�r�|jd�}t
|d�d|d}||gSdS)Nzipset:�z-d�dst�src�,z-mr;z--match-setzCan't match a destination MAC.�macz--mac-sourcer%�/rr])
r�rZr@�ipsetZ
get_dimensionrr
r�upperr	rr
r�)rNrt�address�invertr��flags�
addr_splitr3r3r4r�es"





zip4tables._rule_addr_fragmentc
Cs�ddd�|}|dkr"|dkr"dnd}|jjj||t|d�}	d	d
d	d	d
d
d�|}
|jjrdd|}nd
|}t|�r�|dkr�gS||d|d|g}|j|j|
|��|jd|	g�|gS)Nz-Iz-D)TFr"rTF)r�z-sz-d)rrrr�r�rz%s_ZONES_SOURCEz%s_ZONESr�rz%%ZONE_SOURCE%%z-tz-g)rr�r)r@r�r�r�rrr�r�)
rNr�r�r�r�rcrdr�r�r�rtZzone_dispatch_chainr^r3r3r4�build_zone_source_address_rules{s&
z)ip4tables.build_zone_source_address_rulescCs>ddd�|}ddd�|}|dkr0|dkr0dnd	}|jjj||t|d
�}|j|jt|d|d|d
|d|d|g��g}	|	j||d|g�|	j|d
|d|g�|	j|d|d|g�|	j|d|d|g�|	j|d|d|g�|	j|d|d|g�|	j||d|dd
|g�|	j||d|dd|g�|	j||d|dd|g�|	j||d|dd|g�|	j||d|dd|g�|jjj|j	}
|jj
�dk�r|dk�r|
dk�r�|	j||d|ddddd|g	�|
dk�r|	j||d|ddddd|g	�|dk�r,|
dk�r,|	j||d|d|
g�|�s:|	j�|	S)Nz-Nz-X)TFz-Az-Dr"rTF)r�z%s_logz%s_denyz%s_prez%s_postz%s_allowz-tz-jr�r#r��
%%REJECT%%z%%LOGTYPE%%�LOGz--log-prefixz
"%s_REJECT: "r�z"%s_DROP: "�ACCEPT)r�r�)r�r�r�r�)r@r�r�r�rMr�r;rfZ	_policies�target�get_log_denied�reverse)rNr�r�rcrdZ
add_del_chainZadd_del_ruler�r�r�r�r3r3r4�build_policy_chain_rules�sN




z"ip4tables.build_policy_chain_rulescCs2|sgSddd|jg}|jdk	r.|d|jg7}|S)Nz-m�limitz--limitz
--limit-burst)�valueZburst)rNr�sr3r3r4�_rule_limit�s
zip4tables._rule_limitcCs�t|j�tttgkrn<|jrHt|j�tttt	gkrRt
tdt|j���n
t
td��|jdkr�t|j�ttgks�t|j�tt	gkr�dSt|j�tgks�t|j�ttgkr�dSn|jdkr�dSdSdS)NzUnknown action %szNo rule action specified.r�allowZdenyr�r�)
r��elementrrrr�rrrrr
rr�)rN�	rich_ruler3r3r4�_rich_rule_chain_suffix�s 


z!ip4tables._rich_rule_chain_suffixcCs>|jr|jrttd��|jdkr(dS|jdkr6dSdSdS)NzNot log or auditrrr�r�)r�auditr
rr�)rNrr3r3r4� _rich_rule_chain_suffix_from_log�s


z*ip4tables._rich_rule_chain_suffix_from_logcCs|jdkrgSd|jgS)Nrz%%RICH_RULE_PRIORITY%%)r�)rNrr3r3r4�_rich_rule_priority_fragment�s
z&ip4tables._rich_rule_priority_fragmentc
Cs�|js
gS|jjj||t�}ddd�|}|j|�}d||d||fg}	|	|j|�7}	|	|ddg7}	|jjr�|	dd	|jjg7}	|jjr�|	d
d|jjg7}	|	|j	|jj
�7}	|	S)Nz-Az-D)TFz-tz%s_%sz-jr�z--log-prefixz'%s'z--log-levelz%s)rr@r�r�r�rr�prefix�levelrr)
rNr�rr�rc�
rule_fragmentr�r�r�r^r3r3r4�_rich_rule_log�s
zip4tables._rich_rule_logcCs�|js
gSddd�|}|jjj||t�}|j|�}d||d||fg}	|	|j|�7}	|	|7}	t|j�t	krrd}
n,t|j�t
kr�d}
nt|j�tkr�d}
nd	}
|	d
dd|
g7}	|	|j|jj
�7}	|	S)
Nz-Az-D)TFz-tz%s_%sZacceptZrejectZdrop�unknownz-jZAUDITz--type)r
r@r�r�r�rrr�r�rrrrr)rNr�rr�rcrr�r�r�r^Z_typer3r3r4�_rich_rule_audits$
zip4tables._rich_rule_auditcCs2|js
gSddd�|}|jjj||t�}|j|�}d||f}	t|j�tkrXddg}
n�t|j�tkr�ddg}
|jjr�|
d|jjg7}
nnt|j�t	kr�dd	g}
nVt|j�t
kr�d
}|jjj||t�}d||f}	ddd|jjg}
ntt
d
t|j���d|||	g}||j|�7}|||
7}||j|jj�7}|S)Nz-Az-D)TFz%s_%sz-jr�r�z
--reject-withr�r!�MARKz--set-xmarkzUnknown action %sz-t)r�r@r�r�r�r	r�rrrrr;r
rrrr)rNr�rr�rcrr�r�r�rdZrule_actionr^r3r3r4�_rich_rule_action$s4


zip4tables._rich_rule_actioncCs�|sgSg}|jr�|jr"|jd�td|j�rB|dt|j�g7}q�td|j�r||jjd�}|dt|d�d|dg7}q�|d|jg7}nD|jr�|ddg7}|jr�|jd�|jj	j
|jd	�}|d
|j|g7}|S)N�!r%z-dr�rr]z-mr;r�z--match-set)r�r�rfr	rr
r�r�r@r��_ipset_match_flags)rNZ	rich_destrr�r�r3r3r4�_rich_rule_destination_fragmentFs&
"
z)ip4tables._rich_rule_destination_fragmentcCs|sgSg}|jr�|jr"|jd�td|j�rB|dt|j�g7}nHtd|j�r||jjd�}|dt|d�d|dg7}n|d|jg7}n�t|d�r�|jr�|ddg7}|jr�|jd�|d	|jg7}nPt|d
�o�|j	�r|ddg7}|jr�|jd�|j
jj|j	d�}|d
|j	|g7}|S)Nrr%z-sr�rr]r�z-mz--mac-sourcer�r;r�z--match-set)
r�r�rfr	rr
r��hasattrr�r�r@r�r)rNZrich_sourcerr�r�r3r3r4�_rich_rule_source_fragment^s0
"

z$ip4tables._rich_rule_source_fragmentcCsddd�|}d}|jjj||t�}	d|g}
|rD|
ddt|�g7}
|rT|
d|g7}
|rx|
|j|j�7}
|
|j|j�7}
|s�t	|j
�tkr�|
d	d
ddg7}
g}|r�|j|j
|||||
��|j|j|||||
��|j|j|||||
��n"|j|d
|	d|g|
ddg�|S)Nz-Az-D)TFr#z-pz--dportz%sz-dz-m�	conntrackz	--ctstatez
NEW,UNTRACKEDz%s_allowz-tz-jr�)r@r�r�r�rr�destinationr�sourcer�r�rrfrrr)rNr�r��proto�portrrr�rcr�rr�r3r3r4�build_policy_ports_rules{s*z"ip4tables.build_policy_ports_rulescCs�ddd�|}d}|jjj||t�}d|g}	|r<|	d|g7}	|r`|	|j|j�7}	|	|j|j�7}	|stt|j	�t
kr�|	ddd	d
g7}	g}
|r�|
j|j|||||	��|
j|j
|||||	��|
j|j|||||	��n"|
j|d|d|g|	d
dg�|
S)Nz-Az-D)TFr#z-pz-dz-mrz	--ctstatez
NEW,UNTRACKEDz%s_allowz-tz-jr�)r@r�r�r�rrrrr�r�rrfrrr)rNr�r��protocolrrr�rcr�rr�r3r3r4�build_policy_protocol_rules�s&z%ip4tables.build_policy_protocol_rulescCsddd�|}d}|jjj||t�}	d|g}
|rD|
ddt|�g7}
|rT|
d|g7}
|rx|
|j|j�7}
|
|j|j�7}
|s�t	|j
�tkr�|
d	d
ddg7}
g}|r�|j|j
|||||
��|j|j|||||
��|j|j|||||
��n"|j|d
|	d|g|
ddg�|S)Nz-Az-D)TFr#z-pz--sportz%sz-dz-mrz	--ctstatez
NEW,UNTRACKEDz%s_allowz-tz-jr�)r@r�r�r�rrrrrr�r�rrfrrr)rNr�r�rrrrr�rcr�rr�r3r3r4�build_policy_source_ports_rules�s*z)ip4tables.build_policy_source_ports_rulescCsvd}|jjj||t�}	ddd�|}
|
d|	ddd|g}|rP|dd	t|�g7}|r`|d
|g7}|ddd
|g7}|gS)Nr z-Az-D)TFz%s_allowz-tz-pz--dportz%sz-dz-jZCTz--helper)r@r�r�r�r)rNr�r�rrrZhelper_nameZmodule_short_namercr�r�r^r3r3r4�build_policy_helper_ports_rules�sz)ip4tables.build_policy_helper_ports_rulesc
	Cs�ddd�|}|jjj||t�}g}	|rH|	jdd|d|d|dd	g�n6t|�rTgS|	jdd|d|g|jd
|�dd	g�|	S)Nz-Az-D)TFz-tr#z%s_allowz-oz-jr�z-d)r@r�r�r�rfrr�)
rNr�r�r�rcr�rr�r�r�r3r3r4�build_zone_forward_rules�sz"ip4tables.build_zone_forward_rulesc
Cs,d}|jjj||tdd�}ddd�|}g}|rj|j|�}||j|�7}||j|j�7}||j|j	�7}nd}g}	|	j
dd|d	||fg|d
ddd
dg�g}|r�|j|�}||j|�7}||j|j�7}||j|j	�7}nd}d}|jjj||t�}|	j
dd|d	||fg|ddddd
dg�|	S)Nr"T)r�z-Az-D)TFrz-tz%s_%srz-o�loz-jZ
MASQUERADEr#z-mrz	--ctstatez
NEW,UNTRACKEDr�)r@r�r�r�r	rrrrrrf)
rNr�r�rrcr�r�rr�r�r3r3r4�build_policy_masquerade_rules�s6

z'ip4tables.build_policy_masquerade_rulesc
Cs
d}|jjj||t�}	ddd�|}
d}|rPtd|�rH|dt|�7}n||7}|rn|dkrn|dt|d	�7}g}|r�|j|�}
|j|�}||j	|j
�7}||j|j�7}nd
}
g}|r�|j
|j|||d|��|j
dd|
d|	|
fg|d
|dt|�ddd|g�|S)Nr"z-Az-D)TFrr%z[%s]z:%s�-rz-tz%s_%sz-pz--dportz-jZDNATz--to-destination)r@r�r�r�r	rrr	rrrrrrfr)rNr�r�rr ZtoportZtoaddrrrcr�r�Ztorr�r�r3r3r4�build_policy_forward_port_ruless2


z)ip4tables.build_policy_forward_port_rulescCs�d}|jjj||t�}ddd�|}|jdkrFddg}ddd	|jg}	ndd
g}ddd|jg}	g}
|jjj|�r|d
|}d}nd|}d}g}
|r�|
|j|j�7}
|
|j	|j
�7}
|
||	7}
|�rP|
j|j|||||
��|
j|j
|||||
��|j�r|
j|j|||||
��n:|j|�}|
jd||d||fg|j|�|
ddg�n`|jj�dk�r�|dk�r�|
j||d|g|
ddddd|g�|
j||d|g|
d|g�|
S)Nr#z-Az-D)TFr$z-pr&z-mz--icmp-typez	ipv6-icmpZicmp6z
--icmpv6-typez%s_allowr�z%s_denyz
%%REJECT%%z-tz%s_%sz-jr�z%%LOGTYPE%%r�z--log-prefixz"%s_ICMP_BLOCK: ")r@r�r�r�rAr��query_icmp_block_inversionrrrrrfrrr�rr	rr�)rNr�r�Zictrrcr�r�r�matchr�Zfinal_chainZfinal_targetrr�r3r3r4�build_policy_icmp_block_rules3sJ

 z'ip4tables.build_policy_icmp_block_rulesc	Cs�d}|jjj||t�}g}d}|jjj|�r�d}|jj�dkr�|rRd|t|�g}nd|g}|d|dd	d
ddd
d|g	}|j|�|d7}nd}|r�d|t|�g}nd|g}|d|dd	d|g}|j|�|S)Nr#r�z
%%REJECT%%r�z-Iz-Dz-tz-pz%%ICMP%%z%%LOGTYPE%%z-jr�z--log-prefixz"%s_ICMP_BLOCK: "r]r�)r@r�r�r�r)r�rirf)	rNr�r�rcr�r�Zrule_idxZ
ibi_targetr^r3r3r4�'build_policy_icmp_block_inversion_rulesds.



z1ip4tables.build_policy_icmp_block_inversion_rulescCsxd}g}||j|j�7}||j|j�7}g}|j|j|||||��|j|j|||||��|j|j|||||��|S)Nr#)rrrrrfrrr)rNr�r�rrcrr�r3r3r4�*build_policy_rich_source_destination_rules�sz4ip4tables.build_policy_rich_source_destination_rulescCs
||jkS)N)rA)rNrAr3r3r4r��szip4tables.is_ipv_supported)N)N)r�)F)F)NN)NN)NN)NN)N)N)N)7�__name__�
__module__�__qualname__rAr�Zpolicies_supportedrPrHr�rarerhrjrkrlrmrur�r�r�r�r�rDrFr�r�r�r�r�r�r�r�r�r�rrr	rrrrrrrrr!r"r#r$r&r(r+r,r-r�r3r3r3r4r?�sh

			)Pa#

!
zN

0"




&
!
1"r?c@s&eZdZdZdZddd�Zdd�ZdS)	�	ip6tablesr%Fc
Cs�g}|jddddddddd	d
g
�|dkrL|jddddddddd	dd
dg�|jdddddddd	dg	�|jdddddddd	dg	�|S)Nz-Irz-tr!z-mZrpfilterz--invertz--validmarkz-jr�r�r�z--log-prefixzrpfilter_DROP: z-pz	ipv6-icmpz$--icmpv6-type=neighbour-solicitationr�z"--icmpv6-type=router-advertisement)rf)rNr�r�r3r3r4�build_rpfilter_rules�s$



zip6tables.build_rpfilter_rulescCs�ddddddddd	g	}d
}|jdj|�g}|jddd
|g�xT|D]L}|jddd|d|ddddg
�|jjdkrF|jddd|d|ddddg
�qFW|jdddddd|g�|jdddddd|g�|S)Nz::0.0.0.0/96z::ffff:0.0.0.0/96z2002:0000::/24z2002:0a00::/24z2002:7f00::/24z2002:ac10::/28z2002:c0a8::/32z2002:a9fe::/32z2002:e000::/19ZRFC3964_IPv4r#z-tz-Nz-Iz-dz-jr�z
--reject-withzaddr-unreachr��allr�z--log-prefixz"RFC3964_IPv4_REJECT: "r�4r)r�r3)rMrgrfr@Z_log_denied)rNZ
daddr_listZ
chain_namer�Zdaddrr3r3r4�build_rfc3964_ipv4_rules�s4



z"ip6tables.build_rfc3964_ipv4_rulesN)F)r.r/r0rAr�r2r5r3r3r3r4r1�s
r1)+Zos.pathrQr�Zfirewall.core.progrZfirewall.core.loggerrZfirewall.functionsrrrrrr	r
rZfirewallrZfirewall.errorsr
rrrrZfirewall.core.richrrrrrrrr�r�rbr�r�r5r:r>�objectr?r1r3r3r3r4�<module>s@($%* xcore/__pycache__/fw_config.cpython-36.pyc000064400000077161150351351730014312 0ustar003

��g��@s�dgZddlZddlZddlZddlZddlmZddlmZddl	m
Z
mZmZddl
mZmZmZddlmZmZmZddlmZmZmZdd	lmZmZmZdd
lmZmZm Z ddlm!Z!ddl"m#Z#Gd
d�de$�Z%dS)�FirewallConfig�N)�config)�log)�IcmpType�icmptype_reader�icmptype_writer)�Service�service_reader�service_writer)�Zone�zone_reader�zone_writer)�IPSet�ipset_reader�ipset_writer)�Helper�
helper_reader�
helper_writer)�Policy�
policy_reader�
policy_writer)�errors)�
FirewallErrorc@s$eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Zd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Z d=d>�Z!d?d@�Z"dAdB�Z#dCdD�Z$dEdF�Z%dGdH�Z&dIdJ�Z'dKdL�Z(dMdN�Z)dOdP�Z*dQdR�Z+dSdT�Z,dUdV�Z-dWdX�Z.dYdZ�Z/d[d\�Z0d]d^�Z1d_d`�Z2dadb�Z3dcdd�Z4dedf�Z5dgdh�Z6didj�Z7dkdl�Z8dmdn�Z9dodp�Z:dqdr�Z;dsdt�Z<dudv�Z=dwdx�Z>dydz�Z?d{d|�Z@d}d~�ZAdd��ZBd�d��ZCd�d��ZDd�d��ZEd�d��ZFd�d��ZGd�d��ZHd�d��ZId�d��ZJd�d��ZKd�d��ZLd�d��ZMd�d��ZNd�d��ZOd�d��ZPd�d��ZQd�d��ZRd�d��ZSd�d��ZTd�d��ZUd�d��ZVd�d��ZWd�d��ZXd�d��ZYd�d��ZZd�d��Z[d�d��Z\d�d��Z]d�d��Z^d�d��Z_d�d��Z`d�d��Zad�d��Zbd�d„Zcd�dĄZdd�dƄZed�S)�rcCs||_|j�dS)N)�_fw�_FirewallConfig__init_vars)�self�fw�r�/usr/lib/python3.6/fw_config.py�__init__(szFirewallConfig.__init__cCsHd|j|j|j|j|j|j|j|j|j|j	|j
|j|j|j
|j|jfS)Nz>%s(%r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r))�	__class__�_ipsets�
_icmptypes�	_services�_zones�_helpersZpolicy_objects�_builtin_ipsets�_builtin_icmptypes�_builtin_services�_builtin_zones�_builtin_helpers�_builtin_policy_objects�_firewalld_conf�	_policies�_direct)rrrr�__repr__,szFirewallConfig.__repr__cCs^i|_i|_i|_i|_i|_i|_i|_i|_i|_i|_	i|_
i|_d|_d|_
d|_dS)N)r!r"r#r$r%�_policy_objectsr&r'r(r)r*r+r,r-r.)rrrrZ__init_vars6szFirewallConfig.__init_varscCs4x,t|jj��D]}|j|j�|j|=qWx,t|jj��D]}|j|j�|j|=q>Wx,t|jj��D]}|j|j�|j|=qlWx,t|jj��D]}|j|j�|j|=q�Wx,t|jj��D]}|j|j�|j|=q�Wx,t|jj��D]}|j|j�|j|=q�Wx.t|j	j��D]}|j	|j�|j	|=�q$Wx.t|j
j��D]}|j
|j�|j
|=�qTWx.t|jj��D]}|j|j�|j|=�q�Wx.t|jj��D]}|j|j�|j|=�q�W|j
�r�|j
j�|`
d|_
|j�r|jj�|`d|_|j�r(|jj�|`d|_|j�dS)N)�listr&�keys�cleanupr!r'r"r(r#r)r$r*r%r,r-r.r)r�xrrrr3GsV


zFirewallConfig.cleanupcCs|jjj�S)N)r�policiesZquery_lockdown)rrrr�lockdown_enabled~szFirewallConfig.lockdown_enabledcCs|jjj||�S)N)rr5�access_check)r�key�valuerrrr7�szFirewallConfig.access_checkcCs
||_dS)N)r,)r�confrrr�set_firewalld_conf�sz!FirewallConfig.set_firewalld_confcCs|jS)N)r,)rrrr�get_firewalld_conf�sz!FirewallConfig.get_firewalld_confcCs(tjjtj�s|jj�n
|jj�dS)N)�os�path�existsrZFIREWALLD_CONFr,�clear�read)rrrr�update_firewalld_conf�sz$FirewallConfig.update_firewalld_confcCs
||_dS)N)r-)rr5rrr�set_policies�szFirewallConfig.set_policiescCs|jS)N)r-)rrrr�get_policies�szFirewallConfig.get_policiescCs,tjjtj�s|jjj�n|jjj�dS)N)	r=r>r?rZLOCKDOWN_WHITELISTr-Zlockdown_whitelistr3rA)rrrr�update_lockdown_whitelist�sz(FirewallConfig.update_lockdown_whitelistcCs
||_dS)N)r.)rZdirectrrr�
set_direct�szFirewallConfig.set_directcCs|jS)N)r.)rrrr�
get_direct�szFirewallConfig.get_directcCs(tjjtj�s|jj�n
|jj�dS)N)r=r>r?rZFIREWALLD_DIRECTr.r3rA)rrrr�
update_direct�szFirewallConfig.update_directcCs$ttt|jj��t|jj����S)N)�sorted�setr1r!r2r&)rrrr�
get_ipsets�szFirewallConfig.get_ipsetscCs$|jr||j|j<n||j|j<dS)N)�builtinr&�namer!)r�objrrr�	add_ipset�szFirewallConfig.add_ipsetcCs8||jkr|j|S||jkr(|j|Sttj|��dS)N)r!r&rr�
INVALID_IPSET)rrMrrr�	get_ipset�s




zFirewallConfig.get_ipsetcCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._ipsets[%s] != objz'%s' not a built-in ipset)rMr!rr�NO_DEFAULTSr&�
_remove_ipset)rrNrrr�load_ipset_defaults�s
z"FirewallConfig.load_ipset_defaultscCs|j�S)N)�
export_config)rrNrrr�get_ipset_config�szFirewallConfig.get_ipset_configcCsj|jrPtj|�}|j|�tj|_d|_|j|jkr:d|_|j|�t|�|S|j|�t|�|SdS)NF)	rL�copy�
import_configr�ETC_FIREWALLD_IPSETSr>�defaultrOr)rrNr:r4rrr�set_ipset_config�s



zFirewallConfig.set_ipset_configcCsx||jks||jkr$ttjd|��t�}|j|�|j|�||_d||_	t
j|_d|_
d|_t|�|j|�|S)Nznew_ipset(): '%s'z%s.xmlFT)r!r&rr�
NAME_CONFLICTr�
check_namerXrM�filenamerrYr>rLrZrrO)rrMr:r4rrr�	new_ipset�s




zFirewallConfig.new_ipsetcCs�tjj|�}tjj|�}tjj|�s�|tjkr�x�|jj�D]D}|j|}|j	|kr:|j|=|j
|jkrvd|j|j
fSd|fSq:WnHxF|jj�D]8}|j|}|j	|kr�|j|=|j
|jkr�d|fSdSq�WdStj
d|�yt||�}Wn0tk
�r}ztjd||�dSd}~XnX|j
|jk�rJ|j
|jk�rJ|j|�d|fS|tjk�r�|j
|jk�r�|j|j
j|_||j|j
<d|fS|j
|jk�r�|j|j
=||j|j
<|j
|jk�r�d|fSd	Sd
S)N�update�removezLoading ipset file '%s'z"Failed to load ipset file '%s': %s�new)NN)NN)NN)NN)NN)r=r>�basename�dirnamer?rrYr!r2r^rMr&r�debug1r�	Exception�errorrOrZ)rrMr^r>r4rN�msgrrr�update_ipset_from_path�sP






z%FirewallConfig.update_ipset_from_pathcCs�|j|jkrttj|j��|jtjkr>ttjd|jtjf��d|j|jf}yt	j
|d|�Wn:tk
r�}ztj
d||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' != '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr!rrrPr>rrY�INVALID_DIRECTORY�shutil�moverfrrgr=ra)rrNrMrhrrrrS8szFirewallConfig._remove_ipsetcCs$|js|jr ttjd|j��dS)Nz'%s' is built-in ipset)rLrZrrZ
BUILTIN_IPSETrM)rrNrrr�check_builtin_ipsetIsz"FirewallConfig.check_builtin_ipsetcCs|j|�|j|�dS)N)rmrS)rrNrrr�remove_ipsetNs
zFirewallConfig.remove_ipsetcCs$|j|�|j||�}|j|�|S)N)rm�_copy_ipsetrS)rrNrMr_rrr�rename_ipsetRs

zFirewallConfig.rename_ipsetcCs|j||j��S)N)r_rU)rrNrMrrrroXszFirewallConfig._copy_ipsetcCs$ttt|jj��t|jj����S)N)rIrJr1r"r2r')rrrr�
get_icmptypes]szFirewallConfig.get_icmptypescCs$|jr||j|j<n||j|j<dS)N)rLr'rMr")rrNrrr�add_icmptypeaszFirewallConfig.add_icmptypecCs8||jkr|j|S||jkr(|j|Sttj|��dS)N)r"r'rr�INVALID_ICMPTYPE)rrMrrr�get_icmptypegs




zFirewallConfig.get_icmptypecCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._icmptypes[%s] != objz'%s' not a built-in icmptype)rMr"rrrRr'�_remove_icmptype)rrNrrr�load_icmptype_defaultsns
z%FirewallConfig.load_icmptype_defaultscCs|j�S)N)rU)rrNrrr�get_icmptype_configzsz"FirewallConfig.get_icmptype_configcCsj|jrPtj|�}|j|�tj|_d|_|j|jkr:d|_|j|�t|�|S|j|�t|�|SdS)NF)	rLrWrXr�ETC_FIREWALLD_ICMPTYPESr>rZrrr)rrNr:r4rrr�set_icmptype_config}s



z"FirewallConfig.set_icmptype_configcCsx||jks||jkr$ttjd|��t�}|j|�|j|�||_d||_	t
j|_d|_
d|_t|�|j|�|S)Nznew_icmptype(): '%s'z%s.xmlFT)r"r'rrr\rr]rXrMr^rrxr>rLrZrrr)rrMr:r4rrr�new_icmptype�s




zFirewallConfig.new_icmptypecCs�tjj|�}tjj|�}tjj|�s�|tjkr�x�|jj�D]D}|j|}|j	|kr:|j|=|j
|jkrvd|j|j
fSd|fSq:WnHxF|jj�D]8}|j|}|j	|kr�|j|=|j
|jkr�d|fSdSq�WdStj
d|�yt||�}Wn0tk
�r}ztjd||�dSd}~XnX|j
|jk�rJ|j
|jk�rJ|j|�d|fS|tjk�r�|j
|jk�r�|j|j
j|_||j|j
<d|fS|j
|jk�r�|j|j
=||j|j
<|j
|jk�r�d|fSd	Sd
S)Nr`razLoading icmptype file '%s'z%Failed to load icmptype file '%s': %srb)NN)NN)NN)NN)NN)r=r>rcrdr?rrxr"r2r^rMr'rrerrfrgrrrZ)rrMr^r>r4rNrhrrr�update_icmptype_from_path�sP






z(FirewallConfig.update_icmptype_from_pathcCs�|j|jkrttj|j��|jtjkr>ttjd|jtjf��d|j|jf}yt	j
|d|�Wn:tk
r�}ztj
d||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' != '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr"rrrsr>rrxrjrkrlrfrrgr=ra)rrNrMrhrrrru�szFirewallConfig._remove_icmptypecCs$|js|jr ttjd|j��dS)Nz'%s' is built-in icmp type)rLrZrrZBUILTIN_ICMPTYPErM)rrNrrr�check_builtin_icmptype�sz%FirewallConfig.check_builtin_icmptypecCs|j|�|j|�dS)N)r|ru)rrNrrr�remove_icmptype�s
zFirewallConfig.remove_icmptypecCs$|j|�|j||�}|j|�|S)N)r|�_copy_icmptyperu)rrNrMrzrrr�rename_icmptype�s

zFirewallConfig.rename_icmptypecCs|j||j��S)N)rzrU)rrNrMrrrr~szFirewallConfig._copy_icmptypecCs$ttt|jj��t|jj����S)N)rIrJr1r#r2r()rrrr�get_services
szFirewallConfig.get_servicescCs$|jr||j|j<n||j|j<dS)N)rLr(rMr#)rrNrrr�add_serviceszFirewallConfig.add_servicecCs<||jkr|j|S||jkr(|j|Sttjd|��dS)Nzget_service(): '%s')r#r(rr�INVALID_SERVICE)rrMrrr�get_services




zFirewallConfig.get_servicecCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._services[%s] != objz'%s' not a built-in service)rMr#rrrRr(�_remove_service)rrNrrr�load_service_defaultss
z$FirewallConfig.load_service_defaultscCsr|j�}g}x\td�D]P}|j|d|krN|jtjt||j|d���q|j||j|d�qWt|�S)N�r)�export_config_dict�range�IMPORT_EXPORT_STRUCTURE�appendrW�deepcopy�getattr�tuple)rrN�	conf_dict�	conf_list�irrr�get_service_config's"z!FirewallConfig.get_service_configcCs|j�S)N)r�)rrNrrr�get_service_config_dict3sz&FirewallConfig.get_service_config_dictcCs�i}x&t|�D]\}}|||j|d<qW|jr|tj|�}|j|�tj|_d|_|j|jkrfd|_|j	|�t
|�|S|j|�t
|�|SdS)NrF)�	enumerater�rLrW�import_config_dictr�ETC_FIREWALLD_SERVICESr>rZr�r
)rrNr:r�r�r9r4rrr�set_service_config6s 



z!FirewallConfig.set_service_configcCsj|jrPtj|�}|j|�tj|_d|_|j|jkr:d|_|j|�t|�|S|j|�t|�|SdS)NF)	rLrWr�rr�r>rZr�r
)rrNr:r4rrr�set_service_config_dictJs



z&FirewallConfig.set_service_config_dictcCs�||jks||jkr$ttjd|��i}x&t|�D]\}}||tj|d<q2Wt�}|j|�|j	|�||_
d||_tj
|_d|_d|_t|�|j|�|S)Nznew_service(): '%s'rz%s.xmlFT)r#r(rrr\r�rr�r]r�rMr^rr�r>rLrZr
r�)rrMr:r�r�r9r4rrr�new_serviceZs"




zFirewallConfig.new_servicecCsx||jks||jkr$ttjd|��t�}|j|�|j|�||_d||_	t
j|_d|_
d|_t|�|j|�|S)Nznew_service(): '%s'z%s.xmlFT)r#r(rrr\rr]r�rMr^rr�r>rLrZr
r�)rrMr:r4rrr�new_service_dictqs




zFirewallConfig.new_service_dictcCs�tjj|�}tjj|�}tjj|�s�|tjkr�x�|jj�D]D}|j|}|j	|kr:|j|=|j
|jkrvd|j|j
fSd|fSq:WnHxF|jj�D]8}|j|}|j	|kr�|j|=|j
|jkr�d|fSdSq�WdStj
d|�yt||�}Wn0tk
�r}ztjd||�dSd}~XnX|j
|jk�rJ|j
|jk�rJ|j|�d|fS|tjk�r�|j
|jk�r�|j|j
j|_||j|j
<d|fS|j
|jk�r�|j|j
=||j|j
<|j
|jk�r�d|fSd	Sd
S)Nr`razLoading service file '%s'z$Failed to load service file '%s': %srb)NN)NN)NN)NN)NN)r=r>rcrdr?rr�r#r2r^rMr(rrer	rfrgr�rZ)rrMr^r>r4rNrhrrr�update_service_from_path�sP






z'FirewallConfig.update_service_from_pathcCs�|j|jkrttj|j��|jtjkr>ttjd|jtjf��d|j|jf}yt	j
|d|�Wn:tk
r�}ztj
d||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' != '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr#rrr�r>rr�rjrkrlrfrrgr=ra)rrNrMrhrrrr��szFirewallConfig._remove_servicecCs$|js|jr ttjd|j��dS)Nz'%s' is built-in service)rLrZrrZBUILTIN_SERVICErM)rrNrrr�check_builtin_service�sz$FirewallConfig.check_builtin_servicecCs|j|�|j|�dS)N)r�r�)rrNrrr�remove_service�s
zFirewallConfig.remove_servicecCs$|j|�|j||�}|j|�|S)N)r��
_copy_servicer�)rrNrMr�rrr�rename_service�s

zFirewallConfig.rename_servicecCs|j||j��S)N)r�r�)rrNrMrrrr��szFirewallConfig._copy_servicecCs$ttt|jj��t|jj����S)N)rIrJr1r$r2r))rrrr�	get_zones�szFirewallConfig.get_zonescCs$|jr||j|j<n||j|j<dS)N)rLr)rMr$)rrNrrr�add_zone�szFirewallConfig.add_zonecCs(||jkr|j|=||jkr$|j|=dS)N)r)r$)rrMrrr�forget_zone�s

zFirewallConfig.forget_zonecCs<||jkr|j|S||jkr(|j|Sttjd|��dS)Nzget_zone(): %s)r$r)rr�INVALID_ZONE)rrMrrr�get_zone�s




zFirewallConfig.get_zonecCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._zones[%s] != objz'%s' not a built-in zone)rMr$rrrRr)�_remove_zone)rrNrrr�load_zone_defaultss
z!FirewallConfig.load_zone_defaultscCsr|j�}g}x\td�D]P}|j|d|krN|jtjt||j|d���q|j||j|d�qWt|�S)N�r)r�r�r�r�rWr�r�r�)rrNr�r�r�rrr�get_zone_configs"zFirewallConfig.get_zone_configcCs|j�S)N)r�)rrNrrr�get_zone_config_dictsz#FirewallConfig.get_zone_config_dictcCs�i}x&t|�D]\}}|||j|d<qW|jr�tj|�}||_|j|�tj|_d|_|j|jkrld|_	|j
|�t|�|S||_|j|�t|�|SdS)NrF)r�r�rLrW�	fw_configr�r�ETC_FIREWALLD_ZONESr>rZr�r
)rrNr:r�r�r9r4rrr�set_zone_config s$



zFirewallConfig.set_zone_configcCsv|jrVtj|�}||_|j|�tj|_d|_|j|jkr@d|_|j|�t	|�|S||_|j|�t	|�|SdS)NF)
rLrWr�r�rr�r>rZr�r
)rrNr:r4rrr�set_zone_config_dict6s



z#FirewallConfig.set_zone_config_dictcCs�||jks||jkr$ttjd|��i}x&t|�D]\}}||tj|d<q2Wt�}||_|j	|�|j
|�||_d||_t
j|_d|_d|_t|�|j|�|S)Nznew_zone(): '%s'rz%s.xmlFT)r$r)rrr\r�rr�r�r]r�rMr^rr�r>rLrZr
r�)rrMr:r�r�r9r4rrr�new_zoneHs"



zFirewallConfig.new_zonecCs~||jks||jkr$ttjd|��t�}||_|j|�|j|�||_	d||_
tj|_
d|_d|_t|�|j|�|S)Nznew_zone(): '%s'z%s.xmlFT)r$r)rrr\rr�r]r�rMr^rr�r>rLrZr
r�)rrMr:r4rrr�
new_zone_dict_s



zFirewallConfig.new_zone_dictcCstjj|�}tjj|�}tjj|�s�|jtj�r�x�|jj	�D]D}|j|}|j
|kr<|j|=|j|jkrxd|j|jfSd|fSq<WnHxF|jj	�D]8}|j|}|j
|kr�|j|=|j|jkr�d|fSd	Sq�Wd
St
jd|�yt||�}Wn0tk
�r}zt
jd||�dSd}~XnX||_|jtj��rlt|�ttj�k�rldtjj|�tjj|�dd�f|_|j|jk�r�|j|jk�r�|j|�d|fS|jtj��r�|j|jk�r�|j|jj|_||j|j<d|fS|j|jk�r|j|j=||j|j<|j|jk�rd|fSd
SdS)Nr`razLoading zone file '%s'z!Failed to load zone file '%s': %sz%s/%sr�rb)NN)NN)NN���)NN)NN)r=r>rcrdr?�
startswithrr�r$r2r^rMr)rrerrfrgr��lenr�rZ)rrMr^r>r4rNrhrrr�update_zone_from_pathrsZ





z$FirewallConfig.update_zone_from_pathcCs�|j|jkrttj|j��|jjtj�s@ttj	d|jtjf��d|j|jf}yt
j|d|�Wn:tk
r�}zt
jd||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' doesn't start with '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr$rrr�r>r�rr�rjrkrlrfrrgr=ra)rrNrMrhrrrr��szFirewallConfig._remove_zonecCs$|js|jr ttjd|j��dS)Nz'%s' is built-in zone)rLrZrrZBUILTIN_ZONErM)rrNrrr�check_builtin_zone�sz!FirewallConfig.check_builtin_zonecCs|j|�|j|�dS)N)r�r�)rrNrrr�remove_zone�s
zFirewallConfig.remove_zonec	CsN|j|�|j�}|j|�y|j||�}Wn|j|j|��YnX|S)N)r�r�r�r�rM)rrNrMZobj_confr�rrr�rename_zone�s

zFirewallConfig.rename_zonecCs$ttt|jj��t|jj����S)N)rIrJr1r0r2r+)rrrr�get_policy_objects�sz!FirewallConfig.get_policy_objectscCs$|jr||j|j<n||j|j<dS)N)rLr+rMr0)rrNrrr�add_policy_object�sz FirewallConfig.add_policy_objectcCs<||jkr|j|S||jkr(|j|Sttjd|��dS)Nzget_policy_object(): %s)r0r+rr�INVALID_POLICY)rrMrrr�get_policy_object�s




z FirewallConfig.get_policy_objectcCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._policy_objects[%s] != objz'%s' not a built-in policy)rMr0rrrRr+�_remove_policy_object)rrNrrr�load_policy_object_defaults�s
z*FirewallConfig.load_policy_object_defaultscCs|j�S)N)r�)rrNrrr�get_policy_object_config_dictsz,FirewallConfig.get_policy_object_config_dictcCsv|jrVtj|�}||_|j|�tj|_d|_|j|jkr@d|_|j|�t	|�|S||_|j|�t	|�|SdS)NF)
rLrWr�r�r�ETC_FIREWALLD_POLICIESr>rZr�r)rrNr:r4rrr�set_policy_object_config_dicts



z,FirewallConfig.set_policy_object_config_dictcCs~||jks||jkr$ttjd|��t�}||_|j|�|j|�||_	d||_
tj|_
d|_d|_t|�|j|�|S)Nznew_policy_object(): '%s'z%s.xmlFT)r0r+rrr\rr�r]r�rMr^rr�r>rLrZrr�)rrMr:r4rrr�new_policy_object_dicts



z%FirewallConfig.new_policy_object_dictcCstjj|�}tjj|�}tjj|�s�|jtj�r�x�|jj	�D]D}|j|}|j
|kr<|j|=|j|jkrxd|j|jfSd|fSq<WnHxF|jj	�D]8}|j|}|j
|kr�|j|=|j|jkr�d|fSd	Sq�Wd
St
jd|�yt||�}Wn0tk
�r}zt
jd||�dSd}~XnX||_|jtj��rlt|�ttj�k�rldtjj|�tjj|�dd�f|_|j|jk�r�|j|jk�r�|j|�d|fS|jtj��r�|j|jk�r�|j|jj|_||j|j<d|fS|j|jk�r|j|j=||j|j<|j|jk�rd|fSd
SdS)Nr`razLoading policy file '%s'z#Failed to load policy file '%s': %sz%s/%srr�rb)NN)NN)NNr�)NN)NN)r=r>rcrdr?r�rr�r0r2r^rMr+rrerrfrgr�r�r�rZ)rrMr^r>r4rNrhrrr�update_policy_object_from_path,sZ





z-FirewallConfig.update_policy_object_from_pathcCs�|j|jkrttj|j��|jjtj�s@ttj	d|jtjf��d|j|jf}yt
j|d|�Wn:tk
r�}zt
jd||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' doesn't start with '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr0rrr�r>r�rr�rjrkrlrfrrgr=ra)rrNrMrhrrrr�ysz$FirewallConfig._remove_policy_objectcCs$|js|jr ttjd|j��dS)Nz'%s' is built-in policy)rLrZrrZBUILTIN_POLICYrM)rrNrrr�check_builtin_policy_object�sz*FirewallConfig.check_builtin_policy_objectcCs|j|�|j|�dS)N)r�r�)rrNrrr�remove_policy_object�s
z#FirewallConfig.remove_policy_objectcCs$|j|�|j||�}|j|�|S)N)r��_copy_policy_objectr�)rrNrMZnew_policy_objectrrr�rename_policy_object�s

z#FirewallConfig.rename_policy_objectcCs|j||j��S)N)r�r�)rrNrMrrrr��sz"FirewallConfig._copy_policy_objectcCs$ttt|jj��t|jj����S)N)rIrJr1r%r2r*)rrrr�get_helpers�szFirewallConfig.get_helperscCs$|jr||j|j<n||j|j<dS)N)rLr*rMr%)rrNrrr�
add_helper�szFirewallConfig.add_helpercCs8||jkr|j|S||jkr(|j|Sttj|��dS)N)r%r*rr�INVALID_HELPER)rrMrrr�
get_helper�s




zFirewallConfig.get_helpercCst|j|jkrttj|j��nB|j|j|kr@ttjd|j��n|j|jkr^ttjd|j��|j|�|j|jS)Nzself._helpers[%s] != objz'%s' not a built-in helper)rMr%rrrRr*�_remove_helper)rrNrrr�load_helper_defaults�s
z#FirewallConfig.load_helper_defaultscCs|j�S)N)rU)rrNrrr�get_helper_config�sz FirewallConfig.get_helper_configcCsj|jrPtj|�}|j|�tj|_d|_|j|jkr:d|_|j|�t|�|S|j|�t|�|SdS)NF)	rLrWrXr�ETC_FIREWALLD_HELPERSr>rZr�r)rrNr:r4rrr�set_helper_config�s



z FirewallConfig.set_helper_configcCsx||jks||jkr$ttjd|��t�}|j|�|j|�||_d||_	t
j|_d|_
d|_t|�|j|�|S)Nznew_helper(): '%s'z%s.xmlFT)r%r*rrr\rr]rXrMr^rr�r>rLrZrr�)rrMr:r4rrr�
new_helper�s




zFirewallConfig.new_helpercCs�tjj|�}tjj|�}tjj|�s�|tjkr�x�|jj�D]D}|j|}|j	|kr:|j|=|j
|jkrvd|j|j
fSd|fSq:WnHxF|jj�D]8}|j|}|j	|kr�|j|=|j
|jkr�d|fSdSq�WdStj
d|�yt||�}Wn0tk
�r}ztjd||�dSd}~XnX|j
|jk�rJ|j
|jk�rJ|j|�d|fS|tjk�r�|j
|jk�r�|j|j
j|_||j|j
<d|fS|j
|jk�r�|j|j
=||j|j
<|j
|jk�r�d|fSd	Sd
S)Nr`razLoading helper file '%s'z#Failed to load helper file '%s': %srb)NN)NN)NN)NN)NN)r=r>rcrdr?rr�r%r2r^rMr*rrerrfrgr�rZ)rrMr^r>r4rNrhrrr�update_helper_from_path�sP






z&FirewallConfig.update_helper_from_pathcCs�|j|jkrttj|j��|jtjkr>ttjd|jtjf��d|j|jf}yt	j
|d|�Wn:tk
r�}ztj
d||�tj|�WYdd}~XnX|j|j=dS)Nz'%s' != '%s'z	%s/%s.xmlz%s.oldzBackup of file '%s' failed: %s)rMr%rrr�r>rr�rjrkrlrfrrgr=ra)rrNrMrhrrrr�&szFirewallConfig._remove_helpercCs$|js|jr ttjd|j��dS)Nz'%s' is built-in helper)rLrZrrZBUILTIN_HELPERrM)rrNrrr�check_builtin_helper7sz#FirewallConfig.check_builtin_helpercCs|j|�|j|�dS)N)r�r�)rrNrrr�
remove_helper<s
zFirewallConfig.remove_helpercCs$|j|�|j||�}|j|�|S)N)r��_copy_helperr�)rrNrMr�rrr�
rename_helper@s

zFirewallConfig.rename_helpercCs|j||j��S)N)r�rU)rrNrMrrrr�FszFirewallConfig._copy_helperN)f�__name__�
__module__�__qualname__rr/rr3r6r7r;r<rBrCrDrErFrGrHrKrOrQrTrVr[r_rirSrmrnrprorqrrrtrvrwryrzr{rur|r}rr~r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrrr's�
7EEEMME)&�__all__rWr=Zos.pathrkZfirewallrZfirewall.core.loggerrZfirewall.core.io.icmptyperrrZfirewall.core.io.servicerr	r
Zfirewall.core.io.zonerrr
Zfirewall.core.io.ipsetrrrZfirewall.core.io.helperrrrZfirewall.core.io.policyrrrrZfirewall.errorsr�objectrrrrr�<module>score/__pycache__/fw.cpython-36.pyc000064400000066115150351351730012762 0ustar003

��g���@s�dgZddlZddlZddlZddlZddlZddlmZddlm	Z	ddl
mZddl
mZddl
m
Z
ddl
mZdd	l
mZdd
lmZddlmZddlmZdd
lmZddlmZddlmZddlmZddlmZddl m!Z!ddl"m#Z#ddl$m%Z%m&Z&ddl'm(Z(ddl)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0ddl1m2Z2m3Z3ddl4m5Z5ddl6m7Z7ddl8m9Z9ddl:m;Z;ddlm<Z<dd l=m>Z>Gd!d�de?�Z@dS)"�Firewall�N)�config)�	functions)�	ipXtables)�ebtables)�nftables)�ipset)�modules)�FirewallIcmpType)�FirewallService)�FirewallZone)�FirewallDirect)�FirewallConfig)�FirewallPolicies)�
FirewallIPSet)�FirewallTransaction)�FirewallHelper)�FirewallPolicy)�nm_get_bus_name�nm_get_interfaces_in_zone)�log)�firewalld_conf)�Direct)�service_reader)�icmptype_reader)�zone_reader�Zone)�ipset_reader)�IPSET_TYPES)�
helper_reader)�
policy_reader)�errors)�
FirewallErrorc@s�eZdZdedd�Zdd�Zdd�Zdd	�Zd
d�Zdfdd
�Zdd�Z	dgdd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zdhd)d*�Zdid+d,�Zd-d.�Zdjd/d0�Zdkd1d2�Zdld3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Zd=d>�Z d?d@�Z!dAdB�Z"dCdD�Z#dEdF�Z$dGdH�Z%dIdJ�Z&dKdL�Z'dMdN�Z(dmdOdP�Z)dQdR�Z*dSdT�Z+dUdV�Z,dWdX�Z-dYdZ�Z.d[d\�Z/d]d^�Z0d_d`�Z1dadb�Z2dcdd�Z3d(S)nrFcCsttj�|_||_|jr>d|_d|_d|_d|_t	|_
d|_nrtj
|�|_d|_g|_tj|�|_d|_g|_tj�|_d|_tj�|_d|_g|_
tj|�|_d|_tj�|_t|�|_t|�|_t|�|_ t!|�|_"t#|�|_t$�|_%t&|�|_t'|�|_(t)|�|_*|j+�dS)NFT),rr�FIREWALLD_CONF�_firewalld_conf�_offline�ip4tables_enabled�ip6tables_enabled�ebtables_enabled�
ipset_enabledr�ipset_supported_types�nftables_enabledr�	ip4tables�ip4tables_backend�ipv4_supported_icmp_types�	ip6tables�ip6tables_backend�ipv6_supported_icmp_typesr�ebtables_backendr�
ipset_backendr�nftables_backendr	�modules_backendr
�icmptyper�servicer�zoner
�directrr�policiesrr�helperr�policy�_Firewall__init_vars)�selfZoffline�r?�/usr/lib/python3.6/fw.py�__init__CsB










zFirewall.__init__cCsDd|j|j|j|j|j|j|j|j|j|j	|j
|j|j|j
|jfS)Nz:%s(%r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r))�	__class__r&r'r(�_state�_panic�
_default_zone�_module_refcount�_marks�cleanup_on_exit�cleanup_modules_on_exit�ipv6_rpfilter_enabledr)�_individual_calls�_log_denied)r>r?r?r@�__repr__kszFirewall.__repr__cCsjd|_d|_d|_i|_g|_tj|_tj|_	tj
|_tj|_
tj|_tj|_tj|_tj|_tj|_dS)NZINITF�)rCrDrErFrGrZFALLBACK_CLEANUP_ON_EXITrHZ FALLBACK_CLEANUP_MODULES_ON_EXITrIZFALLBACK_IPV6_RPFILTERrJZFALLBACK_INDIVIDUAL_CALLSrKZFALLBACK_LOG_DENIEDrLZFALLBACK_FIREWALL_BACKEND�_firewall_backendZFALLBACK_FLUSH_ALL_ON_RELOAD�_flush_all_on_reloadZFALLBACK_RFC3964_IPV4�
_rfc3964_ipv4ZFALLBACK_ALLOW_ZONE_DRIFTING�_allow_zone_drifting)r>r?r?r@Z__init_varstszFirewall.__init_varscCs�|jr$d|jj�kr$tjd�d|_|jrHd|jj�krHtjd�d|_|jrld|jj�krltjd�d|_|jr�|jr�|j	r�tj
d�tjd�dS)N�filterziptables is not usable.Fzip6tables is not usable.zebtables is not usable.zNo IPv4 and IPv6 firewall.�)
r&r-�get_available_tablesr�info1r'r0r(r2r+�fatal�sys�exit)r>r?r?r@�
_check_tables�s 



zFirewall._check_tablescCszy|jj�Wn*tk
r8tjd�d|_g|_YnX|jj�|_|jj	�|jj
s||jjrltjd�ntjd�d|_|j
r�|jjd�|_n|jr�|jj�|_ng|_|jj	�|jj
s�|jjr�tjd�ntjd�d|_|j
r�|jjd�|_n|j�r|jj�|_ng|_|jj	�|jj
�sN|jj�r>tjd	�ntjd
�d|_|j�rv|j�rv|jj�rvtjd�dS)Nz4ipset not usable, disabling ipset usage in firewall.FzFiptables-restore is missing, using individual calls for IPv4 firewall.zCiptables-restore and iptables are missing, disabling IPv4 firewall.�ipv4zGip6tables-restore is missing, using individual calls for IPv6 firewall.zEip6tables-restore and ip6tables are missing, disabling IPv6 firewall.�ipv6zHebtables-restore is missing, using individual calls for bridge firewall.zEebtables-restore and ebtables are missing, disabling bridge firewall.zSebtables-restore is not supporting the --noflush option, will therefore not be used)r3Zset_list�
ValueErrorr�warningr)r*Zset_supported_typesr-Zfill_exists�restore_command_existsZcommand_existsr&r+r4Zsupported_icmp_typesr.r0r'r1r2r(rK�restore_noflush_option�debug1)r>r?r?r@�_start_check�sL








zFirewall._start_checkc>Cs�tj}tjdtj�y|jj�Wn8tk
rZ}ztj|�tjd�WYdd}~X�n"X|jj	d�rt|jj	d�}|jj	d�r�|jj	d�}|dk	r�|j
�dBkr�d|_tjd|j�|jj	d	��r|jj	d	�}|dk	r�|j
�dCkr�d|_|dk	�r|j
�dDk�rd|_tjd
|j�|jj	d��rv|jj	d�}|dk	�rv|j
�dEk�rvtjd�y|j
j�Wntk
�rtYnX|jj	d��r�|jj	d�}|dk	�r�|j
�dFk�r�d|_|j
�dGk�r�d|_|j�r�tjd�n
tjd�|jj	d��r"|jj	d�}|dk	�r"|j
�dHk�r"tjd�d|_|jj	d��rt|jj	d�}|dk�sT|j
�dk�r\d|_n|j
�|_tjd|j�|jj	d��r�|jj	d�|_tjd|j�|jj	d��r�|jj	d�}|j
�dIk�r�d|_nd|_tjd|j�|jj	d��r&|jj	d�}|j
�dJk�rd|_nd|_tjd|j�|jj	d��r||jj	d�}|j
�dKk�rVd|_nd|_|j�sntjd�tjd |j�|jjtj|j��|j|j�|j�s�|j�tjd!�y|j
jj�WnZtk
�r }z<|j
j��r�tjd"|j
jj |�ntjd"|j
jj |�WYdd}~XnX|jj!tj|j
��|j"tj#d#�|j"tj$d#�|j"tj%d$�|j"tj&d$�t'|j(j)��d%k�r�tjd&�|j"tj*d'�|j"tj+d'�|j"tj,d(�|j"tj-d(�t'|j.j/��d%k�r�tjd)�|j"tj0d*�|j"tj1d*�t'|j2j3��d%k�r&tj4d+�t5j6d,�|j"tj7d-�|j"tj8d-�d}x.dLD]&}||j2j3�k�rLtj4d1|�d}�qLW|�r�t5j6d,�||j2j3�k�r�d2|j2j3�k�r�d2}nd3|j2j3�k�r�d3}nd.}tjd4||�|}ntjd5|�t9tj:�}	t;j<j=tj:��rRtjd6tj:�y|	j�Wn4tk
�rP}ztjd7tj:|�WYdd}~XnX|j>j?|	�|jj@tj|	��|jA|�|_B|j�r�dS|jC�tjD�d%k�r�tEjE�}
tF|�}|�s�|jG|d8�|�r�|�s�|jH�r�|jIjJ��r�|jKd�|jL�|�r|�rtjd9�|jMjN�|jO|d8�|jKd�|jL�|jH�rX|jIjJ��rXtjd:�|jIjP�tjd;�|jQ|d8�tjd<�|j2jR|d8�|j2jSd|jB|d8�tjd=�|jTjU|d8�|jKd�|jL�|j>jV��rVtjd>�|j>jW|�y|jKd�|jL�WnXtk
�r>}z$t|jXd?|jY�r&|jYnd@��WYdd}~Xntk
�rT�YnX~tjD�d,k�r�tEjE�}
tjZdA|
|
�dS)MNz"Loading firewalld config file '%s'z0Using fallback firewalld configuration settings.�DefaultZoneZ
CleanupOnExit�no�falseFzCleanupOnExit is set to '%s'ZCleanupModulesOnExit�yes�trueTz#CleanupModulesOnExit is set to '%s'ZLockdownzLockdown is enabledZ
IPv6_rpfilterzIPv6 rpfilter is enabledzIPV6 rpfilter is disabledZIndividualCallszIndividualCalls is enabled�	LogDeniedZoffzLogDenied is set to '%s'ZFirewallBackendzFirewallBackend is set to '%s'ZFlushAllOnReloadzFlushAllOnReload is set to '%s'ZRFC3964_IPv4zRFC3964_IPv4 is set to '%s'ZAllowZoneDriftingz�AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a future release. Please consider disabling it now.z AllowZoneDrifting is set to '%s'zLoading lockdown whitelistz*Failed to load lockdown whitelist '%s': %srr6rzNo icmptypes found.r;r7zNo services found.r8zNo zones found.rTr<�block�drop�trustedzZone '%s' is not available.ZpublicZexternalz+Default zone '%s' is not valid. Using '%s'.zUsing default zone '%s'zLoading direct rules file '%s'z)Failed to load direct rules file '%s': %s)�use_transactionzUnloading firewall moduleszApplying ipsetszApplying default rule setzApplying used zoneszApplying used policiesz2Applying direct chains rules and passthrough rulesz
Direct: %srNz%Flushing and applying took %f seconds)rdre)rfrg)rdre)rfrg)rdre)rfrg)rfrg)rdre)rdre)rdre)rirjrk)[rZ
FALLBACK_ZONErrar#r$�read�	Exceptionr^�get�lowerrHrIr:Zenable_lockdownr"rJrKrLrOrPrQrRr%Zset_firewalld_conf�copy�deepcopy�_select_firewall_backendrbZlockdown_whitelistZquery_lockdown�error�filenameZset_policies�_loaderZFIREWALLD_IPSETSZETC_FIREWALLD_IPSETSZFIREWALLD_ICMPTYPESZETC_FIREWALLD_ICMPTYPES�lenr6�
get_icmptypesZFIREWALLD_HELPERSZETC_FIREWALLD_HELPERSZFIREWALLD_SERVICESZETC_FIREWALLD_SERVICESr7�get_servicesZFIREWALLD_ZONESZETC_FIREWALLD_ZONESr8�	get_zonesrWrXrYZFIREWALLD_POLICIESZETC_FIREWALLD_POLICIESrZFIREWALLD_DIRECT�os�path�existsr9Zset_permanent_configZ
set_direct�
check_zonerErZZgetDebugLogLevel�timer�flushr)rZ
has_ipsets�execute�clearr5�unload_firewall_modules�apply_default_tablesZapply_ipsets�apply_default_rulesZapply_zones�change_default_zoner<Zapply_policiesZhas_configurationZapply_direct�code�msgZdebug2)r>�reload�complete_reloadZdefault_zoner��valuert�zr8�objZtm1�transaction�eZtm2r?r?r@�_start�st







 




















.zFirewall._startcCsHy|j�Wn&tk
r2d|_|jd��YnXd|_|jd�dS)N�FAILED�ACCEPT�RUNNING)r�rnrC�
set_policy)r>r?r?r@�start�s
zFirewall.startcCshtjj|�sdS|rZ|jtj�rV|dkrVt�}tjj|�|_|j	|j�||_d|_
nd}�x|ttj|��D�]h}|j
d�s�|jtj�rl|dkrltjjd||f�rl|jd||f|dd�qld||f}tjd||��y�|dk�r�t||�}|j|jj�k�r8|jj|j�}tjd	||j|j|j�|jj|j�n|jjtj��rNd|_
y|jj|�Wn<tk
�r�}	ztjd
|jt|	�f�WYdd}	~	XnX|jjtj|���n�|dk�rFt||�}|j|jj�k�r|jj |j�}tjd	||j|j|j�|jj!|j�n|jjtj��r$d|_
|jj"|�|jj"tj|���n.|dk�rnt#|||d�}|�r�dtjj|�tjj|�d
d�f|_|j	|j�tj|�}
|j|j$j%�k�r|j$j&|j�}|j$j'|j�|j(�r�tjd||j||�|j)|�ntjd	||j|j|j�n|jjtj��r,d|_
d|
_
|jj*|
�|�r^tjd||j||�|j)|�n|j$j*|��n|dk�rDt+||�}|j|j,j-�k�r�|j,j.|j�}tjd	||j|j|j�|j,j/|j�n|jjtj��r�d|_
y|j,j0|�Wn<tk
�r,}	ztj1d
|jt|	�f�WYdd}	~	XnX|jj0tj|���n0|dk�r�t2||�}|j|j3j4�k�r�|j3j5|j�}tjd	||j|j|j�|j3j6|j�n|jjtj��r�d|_
|j3j7|�|jj7tj|��n�|dk�rht8||�}|j|j9j:�k�r2|j9j;|j�}tjd	||j|j|j�|j9j<|j�n|jjtj��rHd|_
|j9j=|�|jj>tj|��ntj?d|�Wqltk
�r�}ztj@d|||�WYdd}~XqltAk
�r�tj@d||�tjB�YqlXqlW|�rd|j(�rd|j|j$j%�k�rX|j$j&|j�}tjd||j|j|j�y|j$j'|j�WntAk
�rHYnX|jjC|j�|j$j*|�dS)Nr8Fz.xmlz%s/%sT)�combinezLoading %s file '%s'r6z  Overloads %s '%s' ('%s/%s')z%s: %s, ignoring for run-time.r7)Z
no_check_namer�z  Combining %s '%s' ('%s/%s')rr;r<zUnknown reader type %szFailed to load %s file '%s': %szFailed to load %s file '%s':z0  Overloading and deactivating %s '%s' ('%s/%s')���)Dr{r|�isdir�
startswithrZ
ETC_FIREWALLDr�basename�nameZ
check_name�default�sorted�listdir�endswithrvrrarr6rxZget_icmptyperuZremove_icmptypeZadd_icmptyper"rV�strrqrrrr7ryZget_serviceZremove_serviceZadd_servicerr8rzZget_zoneZremove_zone�combinedr�Zadd_zonerr�
get_ipsets�	get_ipsetZremove_ipset�	add_ipsetr^rr;Zget_helpersZ
get_helperZ
remove_helperZ
add_helperr r<�get_policiesZ
get_policyZ
remove_policyZ
add_policyZadd_policy_objectrWrtrnZ	exceptionZforget_zone)r>r|Zreader_typer�Z
combined_zonerur�r�Zorig_objrtZ
config_objr�r?r?r@rvs


$







$




zFirewall._loadercCsp|jj�|jj�|jj�|jj�|jj�|jj�|jj�|jj�|j	j�|j
j�|j�dS)N)r6�cleanupr7r8rr;rr9r:r<r$r=)r>r?r?r@r��s









zFirewall.cleanupcCsN|jsB|jr(|j�|jj�|jd�|jrBtjd�|jj	�|j
�dS)Nr�z!Unloading firewall kernel modules)r%rHr�rr�rIrrar5r�r�)r>r?r?r@�stop�s



z
Firewall.stopc	Cs�d}d}x�t|�D]�\}}|r0|jj|�\}}n$|j|dkrDd}n|jj|�\}}|dkrn|d7}||7}q|r�|jj|d�|j|d7<q||jkr|j|d8<|j|dkr|j|=qW||fS)NrrNrT)�	enumerater5�load_modulerFZ
unload_module�
setdefault)	r>Z_modules�enableZ
num_failedZ
error_msgs�i�moduleZstatusr�r?r?r@�handle_modules�s(
zFirewall.handle_modulescCs|dkrd|_dS)NrF)r+)r>�backendr?r?r@rs�sz!Firewall._select_firewall_backendcCs4x|j�D]}|j|kr
|Sq
Wttjd|��dS)Nz'%s' backend does not exist)�all_backendsr�r"r!Z
UNKNOWN_ERROR)r>r�r�r?r?r@�get_backend_by_name�s

zFirewall.get_backend_by_namecCs\|jr|jS|dkr |jr |jS|dkr4|jr4|jS|dkrH|jrH|jStt	j
d|��dS)Nr[r\�ebz-'%s' is not a valid backend or is unavailable)r+r4r&r-r'r0r(r2r"r!�INVALID_IPV)r>�ipvr?r?r@�get_backend_by_ipv�szFirewall.get_backend_by_ipvcCsP|dkr|jr|jS|dkr(|jr(|jS|dkr<|jr<|jSttjd|��dS)Nr[r\r�z-'%s' is not a valid backend or is unavailable)	r&r-r'r0r(r2r"r!r�)r>r�r?r?r@�get_direct_backend_by_ipv�sz"Firewall.get_direct_backend_by_ipvcCs<|dkr|jS|dkr|jS|dkr*|jS|dkr8|jSdS)Nr,r/rrF)r&r'r(r+)r>r�r?r?r@�is_backend_enabled�szFirewall.is_backend_enabledcCs8|jr
dS|dkr|jS|dkr&|jS|dkr4|jSdS)NTr[r\r�F)r+r&r'r()r>r�r?r?r@�is_ipv_enabledszFirewall.is_ipv_enabledcCsRg}|jr|j|j�n6|jr*|j|j�|jr<|j|j�|jrN|j|j�|S)N)	r+�appendr4r&r-r'r0r(r2)r>�backendsr?r?r@�enabled_backendsszFirewall.enabled_backendscCsPg}|jr|j|j�|jr(|j|j�|jr:|j|j�|jrL|j|j�|S)N)	r&r�r-r'r0r(r2r+r4)r>r�r?r?r@r�szFirewall.all_backendsNcCsN|dkrt|�}n|}x |j�D]}|j||j��q W|dkrJ|jd�dS)NT)rr��	add_rulesZbuild_default_tablesr�)r>rlr�r�r?r?r@r�$s
zFirewall.apply_default_tablescCs�|dkrt|�}n|}x(|j�D]}|j|j�}|j||�q W|jd�r~|jd�}d|j�kr~|jr~|j	|j�}|j||�|jd�r�|j
r�|j�}|j||�|dkr�|jd�dS)Nr\�rawT)
rr�Zbuild_default_rulesrLr�r�r�rUrJZbuild_rpfilter_rulesrQZbuild_rfc3964_ipv4_rulesr�)r>rlr�r��rulesZipv6_backendr?r?r@r�0s"


zFirewall.apply_default_rulescCs|jr|jj�rdSdS)NTF)r+r9Zhas_runtime_configuration)r>r?r?r@�may_skip_flush_direct_backendsHsz'Firewall.may_skip_flush_direct_backendscCs`|dkrt|�}n|}x2|j�D]&}||j�kr2q |j�}|j||�q W|dkr\|jd�dS)NT)rr�r��build_flush_rulesr�r�)r>rlr�r�r�r?r?r@�flush_direct_backendsNs
zFirewall.flush_direct_backendscCsp|dkrt|�}n|}tjd�|j�s4|j|d�x$|j�D]}|j�}|j||�q>W|dkrl|jd�dS)NzFlushing rule set)rlT)	rrrar�r�r�r�r�r�)r>rlr�r�r�r?r?r@r�]s

zFirewall.flushcCs`|dkrt|�}n|}tjd|�x&|j�D]}|j|�}|j||�q,W|dkr\|jd�dS)NzSetting policy to '%s'T)rrrar�Zbuild_set_policy_rulesr�r�)r>r<rlr�r�r�r?r?r@r�os

zFirewall.set_policycCsB|sdS|j|�}|s&ttjd|��|j|�s4dS|j||j�S)NrNz'%s' is not a valid backend)r�r"r!r�r��set_rulerL)r>�backend_name�ruler�r?r?r@r��s


z
Firewall.rulecCs"ttd|��}|j|�}|s,ttjd|��|j|�s:dS|js\|js\|dkoX|j	j
�rx�t|�D]�\}}y|j||j
�Wqftk
�r}zjtjtj��tj|�xFt|d|��D]2}y|j|j|�|j
�Wq�tk
r�Yq�Xq�W|�WYdd}~XqfXqfWn|j||j
�dS)Nz'%s' is not a valid backendr)�listrSr�r"r!r�r�rKr_r2r`r�r�rLrnrra�	traceback�
format_excrt�reversedZreverse_ruleZ	set_rules)r>r�r�Z_rulesr�r�r�r�r?r?r@r��s.




zFirewall.rulescCs|jrttj��dS)N)rDr"r!Z
PANIC_MODE)r>r?r?r@�check_panic�szFirewall.check_paniccCs"|}||jj�krttj|��|S)N)r<r�r"r!ZINVALID_POLICY)r>r<Z_policyr?r?r@�check_policy�szFirewall.check_policycCs8|}|s|dkr|j�}||jj�kr4ttj|��|S)NrN)�get_default_zoner8rzr"r!ZINVALID_ZONE)r>r8�_zoner?r?r@r~�szFirewall.check_zonecCstj|�sttj|��dS)N)rZcheckInterfacer"r!ZINVALID_INTERFACE)r>�	interfacer?r?r@�check_interface�s
zFirewall.check_interfacecCs|jj|�dS)N)r7�
check_service)r>r7r?r?r@r��szFirewall.check_servicecCstj|�sttj|��dS)N)r�
check_portr"r!ZINVALID_PORT)r>Zportr?r?r@r��s
zFirewall.check_portcCs*|sttj��|dkr&ttjd|��dS)N�tcp�udp�sctp�dccpz''%s' not in {'tcp'|'udp'|'sctp'|'dccp'})r�r�r�r�)r"r!ZMISSING_PROTOCOLZINVALID_PROTOCOL)r>Zprotocolr?r?r@�check_tcpudp�s
zFirewall.check_tcpudpcCstj|�sttj|��dS)N)rZcheckIPr"r!�INVALID_ADDR)r>Zipr?r?r@�check_ip�s
zFirewall.check_ipcCsP|dkr tj|�sLttj|��n,|dkr@tj|�sLttj|��nttjd��dS)Nr[r\z'%s' not in {'ipv4'|'ipv6'})rZcheckIPnMaskr"r!r�Z
checkIP6nMaskr�)r>r��sourcer?r?r@�
check_address�s

zFirewall.check_addresscCs|jj|�dS)N)r6�check_icmptype)r>Zicmpr?r?r@r��szFirewall.check_icmptypecCs>t|t�std|t|�f��t|�dkr:ttjd|��dS)Nz%s is %s, expected intrz#timeout '%d' is not positive number)�
isinstance�int�	TypeError�typer"r!�
INVALID_VALUE)r>Ztimeoutr?r?r@�
check_timeout�s

zFirewall.check_timeoutc Cs`|j}|j}|sNi}x&|jj�D]}|jj|�d||<q W|jj�}|j�}g}x$|jj	�D]}	|j
|jj|	��q^W|s�|jd�|j
�|j�d}
y|jd|d�Wn&tk
r�}z
|}
WYdd}~XnX|�r(xL|D]D}|jj|j�s�x0|jj�D]"}
|
jdk�r�q�|
j|j��q�Wq�W|�s�|j�}||k�r�||k�rRi||<xFt||j��D]2\}}|d�rd||||||<|||=�qdWxb|jj�D]T}||k�r�x.||D]"}|jj|||||d��q�W||=ntjd|��q�Wt|�d	k�r6x(t|j��D]}tjd
|�||=�qW~x�|D]�}|jj|j��r�xx|jD]R}y|jj|j|�Wn6tk
�r�}z|jt j!k�r�|�WYdd}~XnX�qZWn|jj"|�|jj#|j��q>W|jj$|�t%�}|�r,x@|jj�dgD],}x$t&|�D]}|jj|||d��q
W�q�W||_|j�sD|jd
�|
�rVd|_'|
�nd|_'dS)N�
interfacesZDROPT)r�r�r�__default__�senderzNew zone '%s'.rz(Lost zone '%s', zone interfaces dropped.rN)r�r�r�r�)(rDrPr8rz�get_settingsr9Zget_runtime_configr�rr�r�r�r�r�r�r�rnZquery_ipsetr�r�Zset_destroyr��items�change_zone_of_interfacerrVrw�keysZentriesZ	add_entryr"r�r!�ALREADY_ENABLEDr�Zapply_ipsetZ
set_configrrrC)r>r�rDZ	flush_allZ_zone_interfacesr8Z_direct_config�_old_dzZ_ipset_objs�_nameZstart_exceptionr�r�r�Z_new_dz�iface�settingsZinterface_id�entryr�Znm_bus_namer�r?r?r@r��s�









zFirewall.reloadcCs|jS)N)rC)r>r?r?r@�	get_stateaszFirewall.get_statecCsZ|jrttjd��y|jd�Wn.tk
rN}zttj|��WYdd}~XnXd|_dS)Nzpanic mode already enabledZPANICT)rDr"r!r�r�rn�COMMAND_FAILED)r>r�r?r?r@�enable_panic_modefszFirewall.enable_panic_modecCsZ|jsttjd��y|jd�Wn.tk
rN}zttj|��WYdd}~XnXd|_dS)Nzpanic mode is not enabledr�F)rDr"r!ZNOT_ENABLEDr�rnr�)r>r�r?r?r@�disable_panic_modeqszFirewall.disable_panic_modecCs|jS)N)rD)r>r?r?r@�query_panic_mode|szFirewall.query_panic_modecCs|jS)N)rL)r>r?r?r@�get_log_denied�szFirewall.get_log_deniedcCsb|tjkr&ttjd|djtj�f��||j�krR||_|jj	d|�|jj
�nttj|��dS)Nz'%s', choose from '%s'z','rh)rZLOG_DENIED_VALUESr"r!r��joinr�rLr$�set�writeZALREADY_SET)r>r�r?r?r@�set_log_denied�s
zFirewall.set_log_deniedcCs|jS)N)rE)r>r?r?r@r��szFirewall.get_default_zonecCs�|j|�}||jkr�|j}||_|jjd|�|jj�|jj||�|jj|�}x@t|dj	��D]\}}|drd|jj
d|�qdWnttj
|��dS)Nrcr�r�rN)r~rEr$r�r�r8r�r�r�r�r�r"r!ZZONE_ALREADY_SET)r>r8r�r�Z_old_dz_settingsr�r�r?r?r@�set_default_zone�s


zFirewall.set_default_zonecCsH|j�}x:|j�D].\}}|s(t|t�r2|||<q||kr||=qW|S)N)rqr�r��bool)r>Z	permanentZruntimer��keyr�r?r?r@�'combine_runtime_with_permanent_settings�s

z0Firewall.combine_runtime_with_permanent_settingscCsi}i}x�t|j��t|j��BD]�}||kr"t||t�r�t||krN||ng�}tt||�|�||<t|t||�A|@�||<q"t||t�s�t||t�r�||r�||r�d||<q�||r�||r�d||<q"ttjdj	t
||�|���q"W||fS)NTFz Unhandled setting type {} key {})r�r�r�r�r�r�r"r!ZINVALID_SETTING�formatr�)r>Zold_settingsZnew_settingsZadd_settingsZremove_settingsr��oldr?r?r@�get_added_and_removed_settings�s

 z'Firewall.get_added_and_removed_settings)F)FF)F)N)N)N)N)N)F)4�__name__�
__module__�__qualname__rArMr=rZrbr�r�rvr�r�r�rsr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r~r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r?r?r?r@rBsh
(	;
 








 	
s)A�__all__Zos.pathr{rXrqrr�ZfirewallrrZ
firewall.corerrrrr	Zfirewall.core.fw_icmptyper
Zfirewall.core.fw_servicerZfirewall.core.fw_zonerZfirewall.core.fw_directr
Zfirewall.core.fw_configrZfirewall.core.fw_policiesrZfirewall.core.fw_ipsetrZfirewall.core.fw_transactionrZfirewall.core.fw_helperrZfirewall.core.fw_policyrZfirewall.core.fw_nmrrZfirewall.core.loggerrZfirewall.core.io.firewalld_confrZfirewall.core.io.directrZfirewall.core.io.servicerZfirewall.core.io.icmptyperZfirewall.core.io.zonerrZfirewall.core.io.ipsetrZfirewall.core.ipsetrZfirewall.core.io.helperrZfirewall.core.io.policyr r!Zfirewall.errorsr"�objectrr?r?r?r@�<module>sHcore/__pycache__/fw_icmptype.cpython-36.pyc000064400000004205150351351730014664 0ustar003

��g�	�@s>dgZddlmZddlmZddlmZGdd�de�ZdS)�FirewallIcmpType�)�log)�errors)�
FirewallErrorc@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dS)rcCs||_i|_dS)N)�_fw�
_icmptypes)�self�fw�r
�!/usr/lib/python3.6/fw_icmptype.py�__init__szFirewallIcmpType.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r)rr
r
r�__repr__!szFirewallIcmpType.__repr__cCs|jj�dS)N)r�clear)rr
r
r�cleanup$szFirewallIcmpType.cleanupcCst|jj��S)N)�sortedr�keys)rr
r
r�
get_icmptypes)szFirewallIcmpType.get_icmptypescCs||jkrttj|��dS)N)rrrZINVALID_ICMPTYPE)r�icmptyper
r
r�check_icmptype,s
zFirewallIcmpType.check_icmptypecCs|j|�|j|S)N)rr)rrr
r
r�get_icmptype0s
zFirewallIcmpType.get_icmptypecCs�|j}t|�dkrddg}x�|D]z}|dkrL|jjrB|jjrBq |jj}n,|dkrt|jjrj|jjrjq |jj}ng}|jj	�|kr t
jd|j|f�q W||j|j<dS)NrZipv4Zipv6z5ICMP type '%s' is not supported by the kernel for %s.)
Zdestination�lenrZip4tables_enabledZnftables_enabledZipv4_supported_icmp_typesZip6tables_enabledZipv6_supported_icmp_types�name�lowerrZinfo1r)r�objZ	orig_ipvsZipvZsupported_icmpsr
r
r�add_icmptype4s 


zFirewallIcmpType.add_icmptypecCs|j|�|j|=dS)N)rr)rrr
r
r�remove_icmptypeGs
z FirewallIcmpType.remove_icmptypeN)�__name__�
__module__�__qualname__rrrrrrrrr
r
r
rrsN)	�__all__Zfirewall.core.loggerrZfirewallrZfirewall.errorsr�objectrr
r
r
r�<module>score/__pycache__/fw_helper.cpython-36.opt-1.pyc000064400000003705150351351730015254 0ustar003

��g)�@s6dZdgZddlmZddlmZGdd�de�ZdS)zhelper backend�FirewallHelper�)�errors)�
FirewallErrorc@s\eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�ZdS)rcCs||_i|_dS)N)Z_fw�_helpers)�self�fw�r�/usr/lib/python3.6/fw_helper.py�__init__szFirewallHelper.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r)rrrr	�__repr__"szFirewallHelper.__repr__cCs|jj�dS)N)r�clear)rrrr	�cleanup'szFirewallHelper.cleanupcCs||j�krttj|��dS)N)�get_helpersrr�INVALID_HELPER)r�namerrr	�check_helper*szFirewallHelper.check_helpercCs||j�kS)N)r)rrrrr	�query_helper.szFirewallHelper.query_helpercCst|jj��S)N)�sortedr�keys)rrrr	r1szFirewallHelper.get_helperscCst|j�dkS)Nr)�lenr)rrrr	�has_helpers4szFirewallHelper.has_helperscCs|j|�|j|S)N)rr)rrrrr	�
get_helper7s
zFirewallHelper.get_helpercCs||j|j<dS)N)rr)r�objrrr	�
add_helper;szFirewallHelper.add_helpercCs"||jkrttj|��|j|=dS)N)rrrr)rrrrr	�
remove_helper>s
zFirewallHelper.remove_helperN)
�__name__�
__module__�__qualname__r
rrrrrrrrrrrrr	rsN)�__doc__�__all__ZfirewallrZfirewall.errorsr�objectrrrrr	�<module>score/__pycache__/fw_ipset.cpython-36.pyc000064400000016503150351351730014162 0ustar003

��g�%�@sfdZdgZddlmZddlmZmZmZm	Z	ddl
mZddlm
Z
ddlmZGdd�de�Zd	S)
z
ipset backend�
FirewallIPSet�)�log)�remove_default_create_options�normalize_ipset_entry�check_entry_overlaps_existing�check_for_overlapping_entries)�IPSet)�errors)�
FirewallErrorc@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	d4dd�Z
dd�Zdd�Zd5dd�Z
dd�Zdd�Zdd�Zd6dd �Zd!d"�Zd#d$�Zd%d&�Zd7d'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Zd3S)8rcCs||_i|_dS)N)�_fw�_ipsets)�self�fw�r�/usr/lib/python3.6/fw_ipset.py�__init__#szFirewallIPSet.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r)r
rrr�__repr__'szFirewallIPSet.__repr__cCs|jj�dS)N)r�clear)r
rrr�cleanup,szFirewallIPSet.cleanupcCs||j�krttj|��dS)N)�
get_ipsetsr
r	Z
INVALID_IPSET)r
�namerrr�check_ipset/szFirewallIPSet.check_ipsetcCs||j�kS)N)r)r
rrrr�query_ipset3szFirewallIPSet.query_ipsetcCst|jj��S)N)�sortedr�keys)r
rrrr6szFirewallIPSet.get_ipsetscCst|j�dkS)Nr)�lenr)r
rrr�
has_ipsets9szFirewallIPSet.has_ipsetsFcCs&|j|�|j|}|r"|j|�|S)N)rr�check_applied_obj)r
r�applied�objrrr�	get_ipset<s



zFirewallIPSet.get_ipsetcCs4g}|jjr|j|jj�|jjr0|j|jj�|S)N)rZnftables_enabled�appendZnftables_backendZ
ipset_enabledZ
ipset_backend)r
�backendsrrrr#CszFirewallIPSet.backendscCs0|j|jjkr ttjd|j��||j|j<dS)Nz'%s' is not supported by ipset.)�typerZipset_supported_typesr
r	ZINVALID_TYPErr)r
r rrr�	add_ipsetKszFirewallIPSet.add_ipsetcCs�|j|}|jrh|rhy x|j�D]}|j|�q"WWqttk
rd}zttj|��WYdd}~XqtXntj	d|�|j|=dS)Nz,Keeping ipset '%s' because of timeout option)
rrr#�set_destroy�	Exceptionr
r	�COMMAND_FAILEDr�debug1)r
rZkeepr �backend�msgrrr�remove_ipsetQs
 zFirewallIPSet.remove_ipsetc<Cs$|j|}�x|j�D�]}|jdkr�|j�}||kr�d|jksv|jddksv|j||dksvt|j�||dkr�y|j|�Wn.tk
r�}zt	t
j|��WYdd}~XnX|jj
�r�y|j|j|j|j�Wn0tk
�r}zt	t
j|��WYdd}~Xn&Xd|_d|jk�r,|jddk�r,qy|j|j�Wn0tk
�rl}zt	t
j|��WYdd}~XnXx�|jD]J}y|j|j|�Wn0tk
�r�}zt	t
j|��WYdd}~XnX�qvWqy|j|j|j|j|jd�Wn0tk
�r}zt	t
j|��WYdd}~XqXd|_qWdS)N�ipset�timeout�0r�T)rr#rZset_get_active_terse�optionsr$�rm_def_cr_optsr&r'r
r	r(r�_individual_callsZ
set_creater�	set_flush�entries�set_add�set_restore)r
rr r*Zactiver+�entryrrr�apply_ipset]sL


&
zFirewallIPSet.apply_ipsetcCs>x8|j�D],}|j|}d|_tjd|�|j|�q
WdS)NFzApplying ipset '%s')rrrrr)r9)r
rr rrr�apply_ipsets�s

zFirewallIPSet.apply_ipsetscCs�xz|j�D]n}|jdkrq
x\|j�D]P}y|j|�|j|�Wq$tk
rr}z|jtjkrb|�WYdd}~Xq$Xq$Wq
WdS)NZnftables)	r#rr�
check_appliedr&r
�coder	�NOT_APPLIED)r
r*r-r+rrr�flush�s

zFirewallIPSet.flushTcCs|j||d�jS)N)r)r!r$)r
rrrrr�get_type�szFirewallIPSet.get_typecCst|j|dd�jjd��S)NT)r�,)rr!r$�split)r
rrrr�
get_dimension�szFirewallIPSet.get_dimensioncCs|j|�}|j|�dS)N)r!r)r
rr rrrr;�s
zFirewallIPSet.check_appliedcCs|jsttj|j��dS)N)rr
r	r=r)r
r rrrr�szFirewallIPSet.check_applied_objcCs.|j||d�}d|jkr*|jddkr*dSdS)N)rZfamilyZinet6Zipv6Zipv4)r!r1)r
rrr rrr�
get_family�s

zFirewallIPSet.get_familycCs�|j|dd�}t|�}tj||j|j�||jkrFttj	d||f��t
||j�y$x|j�D]}|j|j
|�q^WWn.tk
r�}zttj|��WYdd}~Xn&Xd|jks�|jddkr�|jj|�dS)NT)rz'%s' already is in '%s'r.r/)r!rr�check_entryr1r$r5r
r	ZALREADY_ENABLEDrr#r6rr'r(r")r
rr8r r*r+rrr�	add_entry�s
zFirewallIPSet.add_entrycCs�|j|dd�}t|�}||jkr4ttjd||f��y$x|j�D]}|j|j|�q@WWn.t	k
r�}zttj
|��WYdd}~Xn&Xd|jks�|jddkr�|jj|�dS)NT)rz'%s' not in '%s'r.r/)
r!rr5r
r	ZNOT_ENABLEDr#Z
set_deleterr'r(r1�remove)r
rr8r r*r+rrr�remove_entry�s
zFirewallIPSet.remove_entrycCsD|j|dd�}t|�}d|jkr:|jddkr:ttj|��||jkS)NT)rr.r/)r!rr1r
r	ZIPSET_WITH_TIMEOUTr5)r
rr8r rrr�query_entry�s
zFirewallIPSet.query_entrycCs|j|dd�}|jS)NT)r)r!r5)r
rr rrr�get_entries�szFirewallIPSet.get_entriescCs@|j|dd�}t|�x|D]}tj||j|j�qWd|jksN|jddkrT||_y"x|j�D]}|j|j	�q`WWn.t
k
r�}zttj
|��WYdd}~XnXd|_yXxR|j�D]F}|jjr�x8|jD]}|j|j	|�q�Wq�|j|j	|j|j|jd�q�WWn0t
k
�r4}zttj
|��WYdd}~XnXd|_dS)NT)rr.r/)r!rrrDr1r$r5r#r4rr'r
r	r(rrr3r6r7)r
rr5r r8r*r+rrr�set_entries�s.
zFirewallIPSet.set_entriesN)F)F)T)T)�__name__�
__module__�__qualname__rrrrrrrr!r#r%r,r9r:r>r?rBr;rrCrErGrHrIrJrrrrr"s0

1

		N)�__doc__�__all__Zfirewall.core.loggerrZfirewall.core.ipsetrr2rrrZfirewall.core.io.ipsetrZfirewallr	Zfirewall.errorsr
�objectrrrrr�<module>score/__pycache__/logger.cpython-36.pyc000064400000055135150351351730013625 0ustar003

��g>y�@s�ddddgZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z
ddl
Z
Gdd�de�ZGdd�de�Z
Gd	d
�d
e
�ZGdd�de�ZGd
d�de�ZGdd�de�Ze�ZdS)�	LogTarget�FileLog�Logger�log�Nc@s2eZdZdZdd�Zddd�Zdd�Zd	d
�ZdS)
rz% Abstract class for logging targets. cCs
d|_dS)N)�fd)�self�r�/usr/lib/python3.6/logger.py�__init__(szLogTarget.__init__rcCstd��dS)Nz%LogTarget.write is an abstract method)�NotImplementedError)r�data�level�logger�is_debugrrr	�write+szLogTarget.writecCstd��dS)Nz%LogTarget.flush is an abstract method)r)rrrr	�flush.szLogTarget.flushcCstd��dS)Nz%LogTarget.close is an abstract method)r)rrrr	�close1szLogTarget.closeN)r)�__name__�
__module__�__qualname__�__doc__r
rrrrrrr	r&s

c@s.eZdZdd�Zddd�Zdd�Zdd	�Zd
S)�
_StdoutLogcCstj|�tj|_dS)N)rr
�sys�stdoutr)rrrr	r
8s
z_StdoutLog.__init__rcCs|jj|�|j�dS)N)rrr)rrr
rrrrr	r<sz_StdoutLog.writecCs|j�dS)N)r)rrrr	rAsz_StdoutLog.closecCs|jj�dS)N)rr)rrrr	rDsz_StdoutLog.flushN)r)rrrr
rrrrrrr	r7s
rc@seZdZdd�ZdS)�
_StderrLogcCstj|�tj|_dS)N)rr
r�stderrr)rrrr	r
Ks
z_StderrLog.__init__N)rrrr
rrrr	rJsrc@s.eZdZdd�Zddd�Zdd�Zdd	�Zd
S)�
_SyslogLogcCs.tj|�tjtjjtjd�tj	tj
�dS)Nr)rr
�syslogZopenlog�os�path�basenamer�argvZLOG_PIDZ
LOG_DAEMON)rrrr	r
Ss
	z_SyslogLog.__init__rcCs�d}|rtj}nF||jkr"tj}n4||jkr4tj}n"||jkrFtj}n||jkrVtj	}|j
d�rt|dt|�d�}t|�dkr�|dkr�tj|�ntj||�dS)N�
�r)rZ	LOG_DEBUG�INFO1ZLOG_INFO�WARNINGZLOG_WARNING�ERRORZLOG_ERR�FATALZLOG_CRIT�endswith�len)rrr
rrZpriorityrrr	ras"




z_SyslogLog.writecCstj�dS)N)rZcloselog)rrrr	rwsz_SyslogLog.closecCsdS)Nr)rrrr	rzsz_SyslogLog.flushN)r)rrrr
rrrrrrr	rRs
rc@s<eZdZdZddd�Zdd�Zddd	�Zd
d�Zdd
�ZdS)rz< FileLog class.
    File will be opened on the first write. �wcCstj|�||_||_dS)N)rr
�filename�mode)rr+r,rrr	r
�s
zFileLog.__init__cCsv|jr
dStjtjB}|jjd�r,|tjO}tj|j|d�|_tj	|jd�tj
|j|j�|_tj|jtjtj
�dS)N�ai�)rr�O_CREAT�O_WRONLYr,�
startswith�O_APPEND�openr+�fchmod�fdopen�fcntlZF_SETFDZ
FD_CLOEXEC)r�flagsrrr	r2�s
zFileLog.openrcCs(|js|j�|jj|�|jj�dS)N)rr2rr)rrr
rrrrr	r�sz
FileLog.writecCs|js
dS|jj�d|_dS)N)rr)rrrr	r�s
z
FileLog.closecCs|js
dS|jj�dS)N)rr)rrrr	r�sz
FileLog.flushN)r*)r)	rrrrr
r2rrrrrrr	rs

c@s�eZdZdZd[Zd\Zd]Zd^Zd_ZdZ	e
�Ze�Z
e�Zd`d	d
�Zdd�Zdadd�Zdbdd�Zdcdd�Zdddd�Zdd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zed"fd#d$�Zed"fd%d&�Zed"fd'd(�Zed"fd)d*�Zed"fd+d,�Z ed"fd-d.�Z!d/d0�Z"d1d2�Z#d3d4�Z$d5d6�Z%d7d8�Z&d9d:�Z'd;d<�Z(d=d>�Z)d?d@�Z*dAdB�Z+dCdD�Z,dedEdF�Z-dGdH�Z.dfdIdJ�Z/ed"dfdKdL�Z0ed"dfdMdN�Z1ed"dfdOdP�Z2dgdQdR�Z3dSdT�Z4dUdV�Z5dWdX�Z6dhdYdZ�Z7d"S)iraL	
    Format string:

    %(class)s      Calling class the function belongs to, else empty
    %(date)s       Date using Logger.date_format, see time module
    %(domain)s     Full Domain: %(module)s.%(class)s.%(function)s
    %(file)s       Filename of the module
    %(function)s   Function name, empty in __main__
    %(label)s      Label according to log function call from Logger.label
    %(level)d      Internal logging level
    %(line)d       Line number in module
    %(module)s     Module name
    %(message)s    Log message

    Standard levels:

    FATAL                 Fatal error messages
    ERROR                 Error messages
    WARNING               Warning messages
    INFOx, x in [1..5]    Information
    DEBUGy, y in [1..10]  Debug messages
    NO_INFO               No info output
    NO_DEBUG              No debug output
    INFO_MAX              Maximum info level
    DEBUG_MAX             Maximum debug level

    x and y depend on info_max and debug_max from Logger class
    initialization. See __init__ function.

    Default logging targets:

    stdout        Logs to stdout
    stderr        Logs to stderr
    syslog        Logs to syslog

    Additional arguments for logging functions (fatal, error, warning, info
    and debug):

    nl       Disable newline at the end with nl=0, default is nl=1.
    fmt      Format string for this logging entry, overloads global format
             string. Example: fmt="%(file)s:%(line)d %(message)s"
    nofmt    Only output message with nofmt=1. The nofmt argument wins over
             the fmt argument.

    Example:

    from logger import log
    log.setInfoLogLevel(log.INFO1)
    log.setDebugLogLevel(log.DEBUG1)
    for i in range(1, log.INFO_MAX+1):
        log.setInfoLogLabel(i, "INFO%d: " % i)
    log.setFormat("%(date)s %(module)s:%(line)d [%(domain)s] %(label)s: "
                  "%(level)d %(message)s")
    log.setDateFormat("%Y-%m-%d %H:%M:%S")

    fl = FileLog("/tmp/log", "a")
    log.addInfoLogging("*", fl)
    log.addDebugLogging("*", fl)
    log.addInfoLogging("*", log.syslog, fmt="%(label)s%(message)s")

    log.debug3("debug3")
    log.debug2("debug2")
    log.debug1("debug1")
    log.info2("info2")
    log.info1("info1")
    log.warning("warning\n", nl=0)
    log.error("error\n", nl=0)
    log.fatal("fatal")
    log.info(log.INFO1, "nofmt info", nofmt=1)

    ����r#r�
cCs�i|_i|_d|_d|_i|_i|_i|_i|_i|_i|_	|dkrPt
d|��|dkrdt
d|��|j|_||_
d|_||_|j|jd�|j|jd�|j|jd�|j|jd�xNtd|j
d�D]:}t|d	||�|j|d�t|d
|dd�||��q�WxTtd|jd�D]@}t|d
||�|j|d|�t|d|dd�||���qW|j|j�|j|j�|jd�|jd�|jd|j|j|j|jg�|jd|jdd�t|j|j
d�D��|jd|jdd�td|jd�D��dS)z Logger class initialization �r#zLogger: info_max %d is too lowrzLogger: debug_max %d is too lowz
FATAL ERROR: zERROR: z	WARNING: zINFO%dzinfo%dcs��fdd�S)Ncs�j�|f|�|�S)N)�info)�message�args�kwargs)r�xrr	�<lambda> sz3Logger.__init__.<locals>.<lambda>.<locals>.<lambda>r)rrAr)rrAr	rBsz!Logger.__init__.<locals>.<lambda>zDEBUG%dz	DEBUG%d: zdebug%dcs��fdd�S)Ncs�j�|f|�|�S)N)�debug)r>r?r@)rrArr	rB)sz3Logger.__init__.<locals>.<lambda>.<locals>.<lambda>r)rrAr)rrAr	rB(sz%(label)s%(message)sz%d %b %Y %H:%M:%S�*cSsg|]}|�qSrr)�.0�irrr	�
<listcomp>4sz#Logger.__init__.<locals>.<listcomp>cSsg|]}|�qSrr)rErFrrr	rG6sN) �_level�_debug_level�_format�_date_format�_label�_debug_label�_logging�_debug_logging�_domains�_debug_domains�
ValueErrorr%�NO_INFO�INFO_MAX�NO_DEBUG�	DEBUG_MAX�setInfoLogLabelr'�	TRACEBACKr&�range�setattr�setDebugLogLabel�setInfoLogLevelr$�setDebugLogLevel�	setFormat�
setDateFormat�setInfoLoggingrr�setDebugLogging)rZinfo_maxZ	debug_maxrHrrr	r
�sX






zLogger.__init__cCsNxHt|j|jd�D]2}||jkr$qx |j|D]\}}}|j�q0WqWdS)z Close all logging targets r#N)rYr'rVrNr)rr
�dummy�targetrrr	r8s

zLogger.closerDcCs$|j|�||jkr|j|S|jS)z Get info log level. )�_checkDomainrH�NOTHING)r�domainrrr	�getInfoLogLevel@s


zLogger.getInfoLogLevelcCs8|j|�||jkr|j}||jkr*|j}||j|<dS)z% Set log level [NOTHING .. INFO_MAX] N)rdrerTrH)rr
rfrrr	r\Gs


zLogger.setInfoLogLevelcCs*|j|�||jkr$|j||jS|jS)z Get debug log level. )rdrIrU)rrfrrr	�getDebugLogLevelPs

zLogger.getDebugLogLevelcCs:|j|�|dkrd}||jkr&|j}||j|j|<dS)z- Set debug log level [NO_DEBUG .. DEBUG_MAX] rN)rdrVrUrI)rr
rfrrr	r]Ws

zLogger.setDebugLogLevelcCs|jS)N)rJ)rrrr	�	getFormat`szLogger.getFormatcCs
||_dS)N)rJ)rrJrrr	r^cszLogger.setFormatcCs|jS)N)rK)rrrr	�
getDateFormatfszLogger.getDateFormatcCs
||_dS)N)rK)rrJrrr	r_iszLogger.setDateFormatcCs:|j|�}x*|D]"}|j||j|jd�||j|<qWdS)zU Set log label for level. Level can be a single level or an array
        of levels. )�	min_level�	max_levelN)�
_getLevels�_checkLogLevelr'rTrL)rr
�label�levelsrrr	rWls




zLogger.setInfoLogLabelcCs>|j|dd�}x*|D]"}|j||j|jd�||j|<qWdS)zU Set log label for level. Level can be a single level or an array
        of levels. r#)r)rkrlN)rmrnr$rVrM)rr
rorprrr	r[us



zLogger.setDebugLogLabelNcCs|j||||dd�dS)z� Set info log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r)rN)�_setLogging)rrfrcr
�fmtrrr	r`~szLogger.setInfoLoggingcCs|j||||dd�dS)z� Set debug log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r#)rN)rq)rrfrcr
rrrrr	ra�szLogger.setDebugLoggingcCs|j||||dd�dS)z� Add info log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r)rN)�_addLogging)rrfrcr
rrrrr	�addInfoLogging�szLogger.addInfoLoggingcCs|j||||dd�dS)z� Add debg log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r#)rN)rs)rrfrcr
rrrrr	�addDebugLogging�szLogger.addDebugLoggingcCs|j||||dd�dS)z� Delete info log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r)rN)�_delLogging)rrfrcr
rrrrr	�delInfoLogging�szLogger.delInfoLoggingcCs|j||||dd�dS)z� Delete debug log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r#)rN)rv)rrfrcr
rrrrr	�delDebugLogging�szLogger.delDebugLoggingcCs|j|dd�S)zN Is there currently any info logging for this log level (and
        domain)? r)r)�_isLoggingHere)rr
rrr	�isInfoLoggingHere�szLogger.isInfoLoggingHerecCs|j|dd�S)zO Is there currently any debug logging for this log level (and
        domain)? r#)r)ry)rr
rrr	�isDebugLoggingHere�szLogger.isDebugLoggingHerecOs,|j|�d|d<|j|j|f|�|�dS)z Fatal error log. rrN)�_checkKWargs�_logr')rrJr?r@rrr	�fatal�s
zLogger.fatalcOs,|j|�d|d<|j|j|f|�|�dS)z Error log. rrN)r|r}r&)rrJr?r@rrr	�error�s
zLogger.errorcOs,|j|�d|d<|j|j|f|�|�dS)z Warning log. rrN)r|r}r%)rrJr?r@rrr	�warning�s
zLogger.warningcOsB|j|d|jd�|j|�d|d<|j||j|f|�|�dS)z� Information log using info level [1..info_max].
        There are additional infox functions according to info_max from
        __init__r#)rkrlrrN)rnrTr|r}rS)rr
rJr?r@rrr	r=�s
zLogger.infocOs<|j|d|jd�|j|�d|d<|j||f|�|�dS)z� Debug log using debug level [1..debug_max].
        There are additional debugx functions according to debug_max
        from __init__r#)rkrlrN)rnrVr|r})rr
rJr?r@rrr	rC�s
zLogger.debugcCs|j|jtj�gid�dS)N)r?r@)r}rX�	traceback�
format_exc)rrrr	�	exception�szLogger.exceptioncCs&||ks||kr"td|||f��dS)Nz*Level %d out of range, should be [%d..%d].)rR)rr
rkrlrrr	rn�szLogger._checkLogLevelcCs2|sdSx$|j�D]}|dkrtd|��qWdS)N�nlrr�nofmtz0Key '%s' is not allowed as argument for logging.)r�rrr�)�keysrR)rr@�keyrrr	r|�s
zLogger._checkKWargscCs|s|dkrtd|��dS)Nr<zDomain '%s' is not valid.)rR)rrfrrr	rd�szLogger._checkDomaincCs�||jkrft|t�st|t�r$|}n|g}xp|D]0}|rL|j|d|jd�q0|j||j|jd�q0Wn6|r�dd�t|j	|j�D�}ndd�t|j|j�D�}|S)z Generate log level array. r#)rkrlcSsg|]}|�qSrr)rErFrrr	rG�sz%Logger._getLevels.<locals>.<listcomp>cSsg|]}|�qSrr)rErFrrr	rG�s)
�ALL�
isinstance�list�tuplernrVr'rTrYZDEBUG1)rr
rrprrr	rm�s


zLogger._getLevelscCsNt|t�st|t�r|}n|g}x(|D] }t|jt�s&td|jj��q&W|S)z Generate target array. z '%s' is no valid logging target.)r�r�r��
issubclass�	__class__rrRr)rrc�targetsZ_targetrrr	�_getTargets�s
zLogger._getTargetscCs�|r |j}|j}d|jdf}n|j}|j}|j|jdf}t|�dkrP|j�xVt	|d|d�D]@}||krrqdx0||D]$\}}}||kr||j
|g�j|�q|WqdWdS)z% Generate dict with domain by level. r#rN)rQrOrVrPrNr'rTr)�clearrY�
setdefault�append)rrrPrNZ_ranger
rfrbrrr	�_genDomainsszLogger._genDomainsc	Csl|j|�|j||�}|j|�}|r,|j}n|j}x*|D]"}x|D]}|||fg||<qBWq8W|j|�dS)N)rdrmr�rOrNr�)	rrfrcr
rrrrpr�rNrrr	rqs



zLogger._setLoggingc	Cst|j|�|j||�}|j|�}|r,|j}n|j}x2|D]*}x$|D]}|j|g�j|||f�qBWq8W|j|�dS)N)rdrmr�rOrNr�r�r�)	rrfrcr
rrrrpr�rNrrr	rs-s



 zLogger._addLoggingc
Cs�|j|�|j||�}|j|�}|r,|j}n|j}x�|D]|}	xv|D]n}|	|krPqB|||f||	kr�||	j|||f�t||	�dkr�||	=qB||jkrBtd|	||j	j
|f��qBWq8W|j|�dS)NrzDNo mathing logging for level %d, domain %s, target %s and format %s.)rdrmr�rOrN�remover)r�rRr�rr�)
rrfrcr
rrrrpr�rNrHrrr	rv<s&




zLogger._delLoggingcCst|j||�}|sdS|dd}|r,|j}n|j}x<||D]0\}}}|dksh|j|�shtj|d|�r<dSq<WdS)NFrf�.rDT)�_genDictrOrNr0�fnmatch�fnmatchcase)rr
r�_dict�point_domainrNrfrbrrr	ryUs
zLogger._isLoggingHerec	Cs�|jjdkrD|jjd}||jkrD|j|}|j|j|j�}|rD|Stj|j�}|j}|j|j	kr�t
|j	|jd�r�|j	|jj|kr�dSxT|j	j�D]F\}}t
|tj�r�t
||j�r�t||j�}t
|tj�r�|j|kr�|Sq�WdS)z7 Function to get calling class. Returns class or None. rZ	func_codeN)�f_code�co_argcount�co_varnames�f_locals�
_getClass2r��inspectZ	getmodule�co_name�__dict__�hasattr�__code__�itemsr��typesZ	ClassType�getattr�FunctionType)	r�frameZselfname�_self�obj�module�coderb�valuerrr	�	_getClassis*


zLogger._getClasscCsVx,|jj�D]}t|tj�r|j|kr|SqWx"|jD]}|j||�}|r6|Sq6WdS)z@ Internal function to get calling class. Returns class or None. N)r��valuesr�r�r�r��	__bases__r�)rr�r�r��baseZ_objrrr	r��s
zLogger._getClass2cOsld}d|kr|d}d}d|kr(|d}d}d|kr<|d}|j||�}|sPdSt|�dkrj|||d<n&t|�dkr�||d|d<n||d<|dd}	|r�|j}
n|j}
g}x�|
|D]�\}}
}|
|kr�q�|d	ks�|	j|d�s�tj|d|�r�|�s|j}d
|k�r|d
}|�r0|
j|d|||�n|
j|||||�|�rZ|
jd|||�|j	|
�q�WdS)Nrrr#r�r�r>rfr�rDrrr")
r�r)rOrNr0r�r�rJrr�)rr
rJr?r@rr�r�r�r�rNZused_targetsrfrcrrr	r}�sL
zLogger._logcCsg}d}|r |j}|j}|j}n|j}|j}|j}xN|D]F}|dkrh|||kr~d}t|�dkrdg}Pq8|||kr8|j|�q8W|r�t|�dkr�dS||kr�dStj	�}	x$|	r�|	j
r�|	jd|jkr�|	j
}	q�W|	s�t
d��|	jd}
|
d	}x|D]}|j|�r�g}Pq�W|	j}t|
�}
xx||D]l}|jd�}|dk�rD�q&n|dk�r\|d|�}n|}|
t|�k�r�|
j|��s�dSn|j|
��s&dS�q&Wd
}||k�r�||}|j|	j|
d
|jd
||tj|jtj��d�	}|dd
k�r�d
|d<d}x&||D]}|dk�r�q�d}P�q�W|jjd�dk�sR|jjd�dk�sR|�sRt|�dk�rl|j|	�}|�rl|j|d<d
|d|d<|dd
k�r�|dd	|d7<|dd
k�r�|dd	|d7<t|�dk�r�|S|dd	}x0|D](}|j|��stj|d|��r�|S�q�WdS)z Internal function. FrDTrr#Nrz Frame information not available.r�r<)	�file�liner��class�functionrfror
Zdater��?z	%(domain)z%(class)r�r�rf)rIrQrMrHrPrLr)r�r�Zcurrentframe�f_back�	f_globalsrrRr0r��find�co_filename�f_linenor��timeZstrftimerKZ	localtimerJr�rr�r�)rr
rZ
check_domainsZsimple_matchr�rPrLrf�fZmodule_nameZpoint_module�co�_lenrF�dZ	level_strZ
domain_neededr�r�rrr	r��s�














zLogger._genDict���������������)r7r;)rD)rD)rD)rD)r)r)r)r)8rrrrr�rer'rXr&r%rrrrrrr
rrgr\rhr]rir^rjr_rWr[r`rartrurwrxrzr{r~rr�r=rCr�rnr|rdrmr�r�rqrsrvryr�r�r}r�rrrr	r�sdG
;

	

					


 4)�__all__rr�r�r�r�rr�r5Zos.pathr�objectrrrrrrrrrrr	�<module>s.-(*4core/__pycache__/fw_transaction.cpython-36.pyc000064400000011650150351351730015361 0ustar003

��g��@sJdZdgZddlZddlmZddlmZddlmZGdd�de	�Z
dS)z!Transaction classes for firewalld�FirewallTransaction�N)�log)�errors)�
FirewallErrorc@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#S)$rcCs(||_i|_g|_g|_g|_g|_dS)N)�fw�rules�	pre_funcs�
post_funcs�
fail_funcs�modules)�selfr�r
�$/usr/lib/python3.6/fw_transaction.py�__init__!szFirewallTransaction.__init__cCs2|jj�|jdd�=|jdd�=|jdd�=dS)N)r�clearrr	r
)rr
r
rr)s
zFirewallTransaction.clearcCs|jj|jg�j|�dS)N)r�
setdefault�name�append)r�backend�ruler
r
r�add_rule/szFirewallTransaction.add_rulecCsx|D]}|j||�qWdS)N)r)rrrrr
r
r�	add_rules2s
zFirewallTransaction.add_rulescCs|j|jko||j|jkS)N)rr)rrrr
r
r�
query_rule6szFirewallTransaction.query_rulecCs2|j|jkr.||j|jkr.|j|jj|�dS)N)rr�remove)rrrr
r
r�remove_rule9szFirewallTransaction.remove_rulecGs|jj||f�dS)N)rr)r�func�argsr
r
r�add_pre=szFirewallTransaction.add_precGs|jj||f�dS)N)r	r)rrrr
r
r�add_post@szFirewallTransaction.add_postcGs|jj||f�dS)N)r
r)rrrr
r
r�add_failCszFirewallTransaction.add_failcCs||jkr|jj|�dS)N)rr)r�moduler
r
r�
add_moduleFs
zFirewallTransaction.add_modulecCs||jkr|jj|�dS)N)rr)rr r
r
r�
remove_moduleJs
z!FirewallTransaction.remove_modulecCsx|D]}|j|�qWdS)N)r!)rrr r
r
r�add_modulesNs
zFirewallTransaction.add_modulescCsx|D]}|j|�qWdS)N)r")rrr r
r
r�remove_modulesRs
z"FirewallTransaction.remove_modulescCs�tjdt|�|df�i}|sjxp|jD]<}x6t|j|�D]$}|j|g�j|jj|�j	|��q<Wq(Wn(x&|jD]}|j|g�j
|j|�qrW||jfS)Nz%s.prepare(%s, %s)z...)r�debug4�typer�reversedrrr�get_backend_by_name�reverse_rule�extendr)r�enabler�backend_namerr
r
r�prepareVszFirewallTransaction.preparecCstjdt|�|f�|j|�\}}|j�d}d}g}xp|D]h}y|jj|||�WnBtk
r�}z&d}|}tjt	j
��tj|�WYdd}~Xq>X|j|�q>W|s�|jj
||�}	|	r�|	\}
}|
r�tj|�|�ri}xH|D]@}g||<x2t||�D]"}||j|jj|�j|���qWq�Wxb|D]Z}y|jj|||�Wn<tk
�r�}ztjt	j
��tj|�WYdd}~XnX�q0Wxh|jD]^\}
}y|
|�WnFtk
�r�}z(tjt	j
��tjd|
||f�WYdd}~XnX�q�Wttj|��|j�dS)Nz%s.execute(%s)F�Tz#Calling fail func %s(%s) failed: %s)rr%r&r-�prerr�	Exception�debug1�	traceback�
format_exc�errorrZhandle_modulesr'r(r)r
rrZCOMMAND_FAILED�post)rr+rrr4ZerrorMsg�doner,�msgZ
module_returnZstatusZ
undo_rulesrrrr
r
r�executefsV



"&zFirewallTransaction.executecCs|tjdt|��xd|jD]Z\}}y||�Wqtk
rr}z(tjtj��tjd|||f�WYdd}~XqXqWdS)Nz%s.pre()z"Calling pre func %s(%s) failed: %s)	rr%r&rr0r1r2r3r4)rrrr7r
r
rr/�szFirewallTransaction.precCs|tjdt|��xd|jD]Z\}}y||�Wqtk
rr}z(tjtj��tjd|||f�WYdd}~XqXqWdS)Nz	%s.post()z#Calling post func %s(%s) failed: %s)	rr%r&r	r0r1r2r3r4)rrrr7r
r
rr5�szFirewallTransaction.postN)�__name__�
__module__�__qualname__rrrrrrrrrr!r"r#r$r-r8r/r5r
r
r
rr s"@)�__doc__�__all__r2Zfirewall.core.loggerrZfirewallrZfirewall.errorsr�objectrr
r
r
r�<module>score/__pycache__/icmp.cpython-36.pyc000064400000004265150351351730013274 0ustar003

��g�#@s�ddddgZddddddd	d
ddd
dddddddddddddddddddd d!d"d#d$�"Zd%d&d'd(d)dddd*d+d,d,d-d-d.d/d0d0d1d1d2d3�Zd4d5�Zd6d�Zd7d8�Zd9d�Zd:S);�
ICMP_TYPES�ICMPV6_TYPES�check_icmp_type�check_icmpv6_typez0/0z3/0z3/1z3/2z3/3z3/4z3/5z3/6z3/7z3/9z3/10z3/11z3/12z3/13z3/14z3/15z4/0z5/0z5/1z5/2z5/3z8/0z9/0z10/0z11/0z11/1z12/0z12/1z13/0z14/0z17/0z18/0)"z
echo-reply�pongznetwork-unreachablezhost-unreachablezprotocol-unreachablezport-unreachablezfragmentation-neededzsource-route-failedznetwork-unknownzhost-unknownznetwork-prohibitedzhost-prohibitedzTOS-network-unreachablezTOS-host-unreachablezcommunication-prohibitedzhost-precedence-violationzprecedence-cutoffz
source-quenchznetwork-redirectz
host-redirectzTOS-network-redirectzTOS-host-redirectzecho-request�pingzrouter-advertisementzrouter-solicitationzttl-zero-during-transitzttl-zero-during-reassemblyz
ip-header-badzrequired-option-missingztimestamp-requestztimestamp-replyzaddress-mask-requestzaddress-mask-replyz1/0z1/1z1/3z1/4z2/0z4/1z4/2z128/0z129/0z133/0z134/0z135/0z136/0z137/0)zno-routezcommunication-prohibitedzaddress-unreachablezport-unreachablezpacket-too-bigzttl-zero-during-transitzttl-zero-during-reassemblyz
bad-headerzunknown-header-typezunknown-optionzecho-requestrz
echo-replyrzrouter-solicitationzrouter-advertisementzneighbour-solicitationzneigbour-solicitationzneighbour-advertisementzneigbour-advertisementZredirectcCs|tkrdSdS)NTF)r)�_name�r�/usr/lib/python3.6/icmp.py�check_icmp_nameVsr
cCs|tj�krdSdS)NTF)r�values)�_typerrr	r[scCs|tkrdSdS)NTF)r)rrrr	�check_icmpv6_name`sr
cCs|tj�krdSdS)NTF)rr)rrrr	resN)�__all__rrr
rr
rrrrr	�<module>sxcore/__pycache__/rich.cpython-36.opt-1.pyc000064400000050640150351351730014226 0ustar003

��g8��@s�dddddddddd	d
ddd
ddddgZddlmZddlmZddlmZddlmZddlm	Z	Gdd�de
�ZGdd�de
�ZGdd�de
�Z
Gdd�de
�ZGdd�de�ZGdd�de
�ZGdd�de
�ZGdd�de
�ZGd d�de
�ZGd!d	�d	e
�ZGd"d
�d
e
�ZGd#d�de
�ZGd$d�de
�ZGd%d
�d
e
�ZGd&d�de�ZGd'd�de
�Zd(d)d/d1d+�ZGd,d�de
�ZGd-d�de
�Zd.S)2�Rich_Source�Rich_Destination�Rich_Service�	Rich_Port�
Rich_Protocol�Rich_Masquerade�Rich_IcmpBlock�
Rich_IcmpType�Rich_SourcePort�Rich_ForwardPort�Rich_Log�
Rich_Audit�Rich_Accept�Rich_Reject�	Rich_Drop�	Rich_Mark�
Rich_Limit�	Rich_Rule�)�	functions)�check_ipset_name)�REJECT_TYPES)�errors)�
FirewallErrorc@seZdZddd�Zdd�ZdS)rFcCs�||_|jdkrd|_||_|jdks0|jdkr8d|_n|jdk	rN|jj�|_||_|jdkrdd|_||_|jdkr�|jdkr�|jdkr�ttjd��dS)N�zno address, mac and ipset)�addr�mac�upper�ipset�invertrr�INVALID_RULE)�selfrrrr�r!�/usr/lib/python3.6/rich.py�__init__$s


zRich_Source.__init__cCsjd|jrdnd}|jdk	r*|d|jS|jdk	rB|d|jS|jdk	rZ|d|jSttjd��dS)Nz	source%s z NOTrzaddress="%s"zmac="%s"z
ipset="%s"zno address, mac and ipset)rrrrrrr)r �retr!r!r"�__str__5s


zRich_Source.__str__N)F)�__name__�
__module__�__qualname__r#r%r!r!r!r"r#s
c@seZdZddd�Zdd�ZdS)rFcCsV||_|jdkrd|_||_|jdkr,d|_||_|jdkrR|jdkrRttjd��dS)Nrzno address and ipset)rrrrrr)r rrrr!r!r"r#Bs

zRich_Destination.__init__cCsRd|jrdnd}|jdk	r*|d|jS|jdk	rB|d|jSttjd��dS)Nzdestination%s z NOTrzaddress="%s"z
ipset="%s"zno address and ipset)rrrrrr)r r$r!r!r"r%Ns

zRich_Destination.__str__N)F)r&r'r(r#r%r!r!r!r"rAs
c@seZdZdd�Zdd�ZdS)rcCs
||_dS)N)�name)r r)r!r!r"r#YszRich_Service.__init__cCs
d|jS)Nzservice name="%s")r))r r!r!r"r%\szRich_Service.__str__N)r&r'r(r#r%r!r!r!r"rXsc@seZdZdd�Zdd�ZdS)rcCs||_||_dS)N)�port�protocol)r r*r+r!r!r"r#`szRich_Port.__init__cCsd|j|jfS)Nzport port="%s" protocol="%s")r*r+)r r!r!r"r%dszRich_Port.__str__N)r&r'r(r#r%r!r!r!r"r_sc@seZdZdd�ZdS)r	cCsd|j|jfS)Nz#source-port port="%s" protocol="%s")r*r+)r r!r!r"r%hszRich_SourcePort.__str__N)r&r'r(r%r!r!r!r"r	gsc@seZdZdd�Zdd�ZdS)rcCs
||_dS)N)�value)r r,r!r!r"r#mszRich_Protocol.__init__cCs
d|jS)Nzprotocol value="%s")r,)r r!r!r"r%pszRich_Protocol.__str__N)r&r'r(r#r%r!r!r!r"rlsc@seZdZdd�Zdd�ZdS)rcCsdS)Nr!)r r!r!r"r#tszRich_Masquerade.__init__cCsdS)N�
masquerader!)r r!r!r"r%wszRich_Masquerade.__str__N)r&r'r(r#r%r!r!r!r"rssc@seZdZdd�Zdd�ZdS)rcCs
||_dS)N)r))r r)r!r!r"r#{szRich_IcmpBlock.__init__cCs
d|jS)Nzicmp-block name="%s")r))r r!r!r"r%~szRich_IcmpBlock.__str__N)r&r'r(r#r%r!r!r!r"rzsc@seZdZdd�Zdd�ZdS)rcCs
||_dS)N)r))r r)r!r!r"r#�szRich_IcmpType.__init__cCs
d|jS)Nzicmp-type name="%s")r))r r!r!r"r%�szRich_IcmpType.__str__N)r&r'r(r#r%r!r!r!r"r�sc@seZdZdd�Zdd�ZdS)r
cCs<||_||_||_||_|jdkr(d|_|jdkr8d|_dS)Nr)r*r+�to_port�
to_address)r r*r+r.r/r!r!r"r#�s

zRich_ForwardPort.__init__cCs<d|j|j|jdkrd|jnd|jdkr4d|jndfS)Nz(forward-port port="%s" protocol="%s"%s%srz
 to-port="%s"z
 to-addr="%s")r*r+r.r/)r r!r!r"r%�szRich_ForwardPort.__str__N)r&r'r(r#r%r!r!r!r"r
�sc@seZdZddd�Zdd�ZdS)rNcCs||_||_||_dS)N)�prefix�level�limit)r r0r1r2r!r!r"r#�szRich_Log.__init__cCs>d|jrd|jnd|jr$d|jnd|jr6d|jndfS)Nz	log%s%s%sz prefix="%s"rz level="%s"z %s)r0r1r2)r r!r!r"r%�szRich_Log.__str__)NNN)r&r'r(r#r%r!r!r!r"r�s
c@seZdZddd�Zdd�ZdS)rNcCs
||_dS)N)r2)r r2r!r!r"r#�szRich_Audit.__init__cCsd|jrd|jndS)Nzaudit%sz %sr)r2)r r!r!r"r%�szRich_Audit.__str__)N)r&r'r(r#r%r!r!r!r"r�s
c@seZdZddd�Zdd�ZdS)r
NcCs
||_dS)N)r2)r r2r!r!r"r#�szRich_Accept.__init__cCsd|jrd|jndS)Nzaccept%sz %sr)r2)r r!r!r"r%�szRich_Accept.__str__)N)r&r'r(r#r%r!r!r!r"r
�s
c@s&eZdZddd�Zdd�Zdd�ZdS)	rNcCs||_||_dS)N)�typer2)r Z_typer2r!r!r"r#�szRich_Reject.__init__cCs,d|jrd|jnd|jr$d|jndfS)Nz
reject%s%sz
 type="%s"rz %s)r3r2)r r!r!r"r%�szRich_Reject.__str__cCsT|jrP|sttjd��|dkrP|jt|krPdjt|�}ttjd|j|f��dS)Nz9When using reject type you must specify also rule family.�ipv4�ipv6z, z%Wrong reject type %s.
Use one of: %s.)r4r5)r3rrrr�join)r �familyZvalid_typesr!r!r"�check�szRich_Reject.check)NN)r&r'r(r#r%r8r!r!r!r"r�s
c@seZdZdd�ZdS)rcCsd|jrd|jndS)Nzdrop%sz %sr)r2)r r!r!r"r%�szRich_Drop.__str__N)r&r'r(r%r!r!r!r"r�sc@s&eZdZddd�Zdd�Zdd�ZdS)	rNcCs||_||_dS)N)�setr2)r Z_setr2r!r!r"r#�szRich_Mark.__init__cCsd|j|jrd|jndfS)Nz
mark set=%s%sz %sr)r9r2)r r!r!r"r%�szRich_Mark.__str__cCs�|jdk	r|j}nttjd��d|krv|jd�}t|�dkrHttj|��tj|d�shtj|d�r�ttj|��ntj|�s�ttj|��dS)Nzno value set�/�r�)r9rrZINVALID_MARK�split�lenrZcheckUINT32)r �x�splitsr!r!r"r8�s


zRich_Mark.check)N)r&r'r(r#r%r8r!r!r!r"r�s
r<�<�)�s�m�h�dc@s�eZdZddd�Zdd�Zedd��Zejdd��Zed	d
��Zejdd
��Ze	dd
��Z
dd�Ze	dd��Zdd�Z
dd�ZdS)rNcCs||_||_dS)N)r,�burst)r r,rGr!r!r"r#�szRich_Limit.__init__cCs|j�|j�dS)N)�value_parse�burst_parse)r r!r!r"r8�szRich_Limit.checkcCs|jS)N)�_value)r r!r!r"r,�szRich_Limit.valuecCsf|dkrd|_dSy|j|�\}}Wntk
r<|}YnX|�d|��}t|dd�|krb||_dS)Nr:rJ)rJ�_value_parser�getattr)r r,�rate�duration�vr!r!r"r,�s
cCs|jS)N)�_burst)r r!r!r"rGszRich_Limit.burstcCs\|dkrd|_dSy|j|�}Wntk
r8|}Yn
Xt|�}t|dd�|krX||_dS)NrP)rP�_burst_parser�strrL)r rG�br!r!r"rGs
cCs�d}d|kr|jd�}|s(t|�dkr4ttj|��|\}}yt|�}Wnttj|��YnX|dkrv|dd�}|dks�|dkr�ttj|��dt||d
kr�ttjd|f��|dkr�|dkr�ttjd|f��||fS)Nr:r;�second�minute�hour�dayr<rCrDrErFi'rz%s too fastz%s too slow)rTrUrVrW)rCrDrErF)r=r>rr�
INVALID_LIMIT�int�DURATION_TO_MULT)r,r@rMrNr!r!r"rKs&
zRich_Limit._value_parsecCs|j|j�S)N)rKrJ)r r!r!r"rH:szRich_Limit.value_parsec	CsR|dkrdSyt|�}Wnttj|��YnX|dksB|dkrNttj|��|S)Nr<i���)rYrrrX)rGrSr!r!r"rQ=szRich_Limit._burst_parsecCs|j|j�S)N)rQrP)r r!r!r"rIKszRich_Limit.burst_parsecCs,d|j�d�}|jdk	r(|d|j��7}|S)Nz
limit value="�"z burst=)rJrP)r rCr!r!r"r%Ns
zRich_Limit.__str__)N)r&r'r(r#r8�propertyr,�setterrG�staticmethodrKrHrQrIr%r!r!r!r"r�s
c@s>eZdZdZdZddd�Zdd�Zd	d
�Zdd�Zd
d�Z	dS)ri�i�NrcCsV|dk	rt|�|_nd|_||_d|_d|_d|_d|_d|_d|_|rR|j	|�dS)N)
rRr7�priority�source�destination�element�log�audit�action�_import_from_string)r r7�rule_strr_r!r!r"r#XszRich_Rule.__init__cCs�g}x|tj|�D]n}d|krp|jd�}t|�dksF|dsF|drVttjd|��|j|d|dd��q|jd|i�qW|jddi�|S)	z Lexical analysis �=r;rr<zinternal error in _lexer(): %s)�	attr_name�
attr_valuerb�EOL)rZ	splitArgsr=r>rrr�append)r rg�tokens�r�attrr!r!r"�_lexeris
 
zRich_Rule._lexercCs�|sttjd��tj|�}d|_d|_d|_d|_d|_	d|_
d|_d|_|j
|�}|rv|djd�dkrvttjd��i}g}d}�x`||jd�dko�|dgk�s�||jd�}||jd�}||jd�}|�r�|dHk�r�ttjd|���n�|dIk�r�|dk�r|j�rttjd+��n�|dk�r<|j�r<ttjd,��n�|dJk�rf|j	�rfttjd-||j	f��nh|d"k�r�|j
�r�ttjd.��nH|d#k�r�|j�r�ttjd/��n(|dKk�r�|j�r�ttjd0||jf��nttjd1|��t|�dk�r�|t|�d2nd3}	|	d3k�r�|�r`|�r`|d	k�r2ttjd4��n,|dk�rJttjd5��nttjd6||f��n*d|k�r�ttjd7||f��n
|jd��nL|	dk�rD|d	k�r�|dLk�r�ttjd:|��||_n||dk�ryt|�|_Wn&tk
�rttjd;|��YnXn:|�r6|dk�rd<}
nd=||f}
ttj|
��n
|j|��n�|	dk�r�|dMk�rb|||<nV|dNk�rvd>|d
<nBt|jd
�|jd�|jd�|jd
d?��|_|j�|j�|d2}�n|	dk�r,|dOk�r�|||<nN|dPk�r�d>|d
<n:t|jd
�|jd�|jd
d?��|_|j�|j�|d2}�n�|	dk�rd|dk�rTt|�|_	|j�nttjd@���nv|	dk�r�|dk�r�t|�|_	|j�nttjdA���n>|	dk�r�|dQk�r�|||<n0t|jd�|jd��|_	|j�|j�|d2}�n�|	dk�r&|dk�rt|�|_	|j�nttjdB���n�|	dk�r^|dk�rNt|�|_	|j�nttjdC���n||	dk�r�t�|_	|j�|j�|d2}�nN|	d k�r�|dRk�r�|||<n@t|jd�|jd�|jd�|jd��|_	|j�|j�|d2}�n�|	d!k�r@|dSk�r|||<n0t|jd�|jd��|_	|j�|j�|d2}�n�|	d"k�r�|dTk�r^|||<nN|d(k�rt|jd(�n8t |jd�|jd�|jd(��|_
|j�|j�|d2}�n*|	d#k�r�|d(k�r�|jd(�n(t!|jd(��|_|j�|j�|d2}�n�|	d$k�rH|d(k�r|jd(�n(t"|jd(��|_|j�|j�|d2}�n�|	d%k�r�|d(k�rh|jd(�n(t#|jd(��|_|j�|j�|d2}�nF|	d&k�r�|dk�r�|||<nF|d(k�r�|jd(�n0t$|jd�|jd(��|_|j�|j�|d2}n�|	d'k�r`|dk�r|||<nF|d(k�r.|jd(�n0t%|jd�|jd(��|_|j�|j�|d2}nz|	d(k�r�|dUk�r�||dD|��<nVdE|k�r�ttjdF��t&|dE|jdG��|d(<|jdEd�|jdGd�|j�|d2}|d2}q�W|j'�dS)VNz
empty rulerrbrk�rulerirjr_r7�addressrrrr,r*r+�to-port�to-addrr)r0r1r3r9rGzbad attribute '%s'r`ra�service�
icmp-block�	icmp-typer-�forward-port�source-portrcrd�accept�drop�reject�markr2�not�NOTzmore than one 'source' elementz#more than one 'destination' elementzFmore than one element. There cannot be both '%s' and '%s' in one rule.zmore than one 'log' elementzmore than one 'audit' elementzOmore than one 'action' element. There cannot be both '%s' and '%s' in one rule.zunknown element %sr<rz0'family' outside of rule. Use 'rule family=...'.z4'priority' outside of rule. Use 'rule priority=...'.z:'%s' outside of any element. Use 'rule <element> %s= ...'.z,'%s' outside of rule. Use 'rule ... %s ...'.r4r5zH'family' attribute cannot have '%s' value. Use 'ipv4' or 'ipv6' instead.z(invalid 'priority' attribute value '%s'.zdwrong 'protocol' usage. Use either 'rule protocol value=...' or  'rule [forward-]port protocol=...'.zDattribute '%s' outside of any element. Use 'rule <element> %s= ...'.TFzinvalid 'protocol' elementzinvalid 'service' elementzinvalid 'icmp-block' elementzinvalid 'icmp-type' elementzlimit.zlimit.valuezinvalid 'limit' elementzlimit.burst)r_r7rrrrrr,r*r+rsrtr)r0r1r3r9rG)rqr`rar+rur*rvrwr-rxryrcrdrzr{r|r}r2r~rrk)r+rur*rvrwr-rxry)rzr{r|r})r4r5)rrrrr)r~r)rrrr)r~r)r*r+)r*r+rsrt)r*r+)r0r1)r,rG)(rrrrZstripNonPrintableCharactersr_r7r`rarbrcrdrerp�getr>rlrY�
ValueError�INVALID_PRIORITYr�pop�clearrrrrrrrr
r	rrr
rrrrr8)r rgrmZattrsZin_elements�indexrbrirjZ
in_elementZerr_msgr!r!r"rfzs�

""













*




"






















(






 




















zRich_Rule._import_from_stringc	Cs`|jdk	r"|jd kr"ttj|j��|jdkrn|jdk	rB|jjdk	sL|jdk	rVttj��t|j	�t
krnttj��|j|jks�|j|j
kr�ttjd|j|j
f��|j	dko�|jdks�|jdk	o�|jdk�r
|jdkr�ttjd��|jdko�|jdko�|jdk�r
ttjd��t|j	�tt
tgk�rP|jdk�rP|jdk�rP|jdk�rPttjd��|jdk	�rj|jjdk	�r�|jdk�r�ttj��|jjdk	�r�ttjd��|jjdk	�r�ttjd	��tj|j|jj��sjttjt|jj���n�|jjdk	�r,|jjdk	�rttjd
��tj|jj��sjttjt|jj���n>|jjdk	�r^t|jj��sjttjt|jj���nttjd��|jdk	�r|jjdk	�r�|jdk�r�ttj��|jjdk	�r�ttjd	��tj|j|jj��sttjt|jj���n>|jjdk	�rt|jj��sttjt|jj���nttjd��t|j	�t k�rd|j	j!dk�sLt"|j	j!�d
k�r`ttj#t|j	j!����n�t|j	�t$k�r�tj%|j	j&��s�ttj'|j	j&��|j	j(d!k�r`ttj)|j	j(���n�t|j	�t*k�r�tj+|j	j,��s`ttj)|j	j,���nvt|j	�tk�r<|jdk	�rttjd��|jdk	�r`|jjdk	�r`ttjd���n$t|j	�tk�r�|j	j!dk�slt"|j	j!�d
k�r�ttj-t|j	j!���|j�r`ttjd���n�t|j	�t.k�r�|j	j!dk�s�t"|j	j!�d
k�r`ttj-t|j	j!����n�t|j	�t
k�r�tj%|j	j&��sttj'|j	j&��|j	j(d"k�r.ttj)|j	j(��|j	j/dk�rZ|j	j0dk�rZttj'|j	j/��|j	j/dk�r�tj%|j	j/��r�ttj'|j	j/��|j	j0dk�r�tj1|j|j	j0��r�ttj|j	j0��|jdk�r�ttj��|jdk	�r`ttjd��nrt|j	�t2k�r>tj%|j	j&��sttj'|j	j&��|j	j(d#k�r`ttj)|j	j(��n"|j	dk	�r`ttjdt|j	���|jdk	�r�|jj3�r�|jj3d$k�r�ttj4|jj3��|jj5dk	�r�|jj5j6�|jdk	�r�t|j�t7t8t9gk�r�ttj:t|j���|jj5dk	�r�|jj5j6�|jdk	�r\t|j�t8k�r(|jj6|j�nt|j�t;k�rB|jj6�|jj5dk	�r\|jj5j6�dS)%Nr4r5z/'priority' attribute must be between %d and %d.rzno element, no actionz%no element, no source, no destinationzno action, no log, no auditzaddress and maczaddress and ipsetz
mac and ipsetzinvalid sourcezinvalid destinationr<�tcp�udp�sctp�dccpzmasquerade and actionzmasquerade and mac sourcezicmp-block and actionrzforward-port and actionzUnknown element %s�emerg�alert�crit�error�warning�notice�info�debug)r4r5)r�r�r�r�)r�r�r�r�)r�r�r�r�)r�r�r�r�r�r�r�r�)<r7rrZINVALID_FAMILYr`rraZMISSING_FAMILYr3rbr
r_�priority_min�priority_maxr�rcrerrrrdrrrZ
check_addressZINVALID_ADDRrRZ	check_macZINVALID_MACrZ
INVALID_IPSETZINVALID_DESTINATIONrr)r>ZINVALID_SERVICErZ
check_portr*ZINVALID_PORTr+ZINVALID_PROTOCOLrZ
checkProtocolr,ZINVALID_ICMPTYPErr.r/Zcheck_single_addressr	r1ZINVALID_LOG_LEVELr2r8r
rrZINVALID_AUDIT_TYPEr)r r!r!r"r8hs�




 
 



   


zRich_Rule.checkcCs�d}|jr|d|j7}|jr,|d|j7}|jr@|d|j7}|jrT|d|j7}|jrh|d|j7}|jr||d|j7}|jr�|d|j7}|jr�|d|j7}tj	r�tj
|�S|S)Nrqz priority="%d"z family="%s"z %s)r_r7r`rarbrcrdrerZPY2Zu2b)r r$r!r!r"r%s$zRich_Rule.__str__i���)NNr)
r&r'r(r�r�r#rprfr8r%r!r!r!r"rTs
o-Nii�i�Q)�__all__ZfirewallrZfirewall.core.ipsetrZfirewall.core.baserrZfirewall.errorsr�objectrrrrr	rrrrr
rrr
rrrrZrrr!r!r!r"�<module>s@
dcore/__pycache__/modules.cpython-36.opt-1.pyc000064400000005500150351351730014744 0ustar003

��g��@sBdZdgZddlmZddlmZddlmZGdd�de�Z	dS)zmodules backend�modules�)�runProg)�log)�COMMANDSc@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dS)rcCstd|_td|_dS)NZmodprobeZrmmod)r�
_load_command�_unload_command)�self�r	�/usr/lib/python3.6/modules.py�__init__s
zmodules.__init__cCs
d|jS)Nz%s)�	__class__)rr	r	r
�__repr__$szmodules.__repr__cCs�g}i}y�tdd��p}xh|D]`}|s&P|j�}|j�}|j|d�|ddkrp|djd�dd	�||d<qg||d<qWWdQRXWntk
r�YnX||fS)
z6 get all loaded kernel modules and their dependencies z
/proc/modules�rr��-�,N����)�open�strip�split�append�FileNotFoundError)r�mods�deps�f�lineZsplitsr	r	r
�loaded_modules's 
 zmodules.loaded_modulescCs"tjd|j|j|�t|j|g�S)Nz	%s: %s %s)r�debug2rrr)r�moduler	r	r
�load_module<szmodules.load_modulecCs"tjd|j|j|�t|j|g�S)Nz	%s: %s %s)rrrrr)rrr	r	r
�
unload_module@szmodules.unload_modulecCsT||krdSx0||D]$}|j|||�||kr|j|�qW||krP|j|�dS)z  get all dependants of a module N)�get_depsr)rrr�ret�modr	r	r
r"Dszmodules.get_depscCs�g}|j�\}}|jd||�x*dD]"}||kr$|j|�|jd|�q$Wx^|D]V}|dks�|jd�s�|jd	�s�|jd
�s�|jd�s�|jd�s�|jd
�rP|j|||�qPW|S)z) get all loaded firewall-related modules Znf_conntrack�nf_conntrack_ipv4�nf_conntrack_ipv6r�	ip_tables�
ip6_tables�ebtablesZiptable_Z	ip6table_Znf_Zxt_Zipt_Zip6t_)r%r&r)r'r(r))rr"�remove�insert�
startswith)rrZmods2rZbad_bad_moduler$r	r	r
�get_firewall_modulesOs


zmodules.get_firewall_modulescCs>x8|j�D],}|j|�\}}|dkr
tjd||f�q
WdS)z% unload all firewall-related modules rz Failed to unload module '%s': %sN)r-r!rZdebug1)rrZstatusr#r	r	r
�unload_firewall_modulesdszmodules.unload_firewall_modulesN)�__name__�
__module__�__qualname__rr
rr r!r"r-r.r	r	r	r
rsN)
�__doc__�__all__Zfirewall.core.progrZfirewall.core.loggerrZfirewall.configr�objectrr	r	r	r
�<module>s
core/__pycache__/helper.cpython-36.opt-1.pyc000064400000000256150351351730014556 0ustar003

��g$�@sdZdZdS)zThe helper maxnamelen� N)�__doc__ZHELPER_MAXNAMELEN�rr�/usr/lib/python3.6/helper.py�<module>score/__pycache__/fw_icmptype.cpython-36.opt-1.pyc000064400000004205150351351730015623 0ustar003

��g�	�@s>dgZddlmZddlmZddlmZGdd�de�ZdS)�FirewallIcmpType�)�log)�errors)�
FirewallErrorc@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dS)rcCs||_i|_dS)N)�_fw�
_icmptypes)�self�fw�r
�!/usr/lib/python3.6/fw_icmptype.py�__init__szFirewallIcmpType.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r)rr
r
r�__repr__!szFirewallIcmpType.__repr__cCs|jj�dS)N)r�clear)rr
r
r�cleanup$szFirewallIcmpType.cleanupcCst|jj��S)N)�sortedr�keys)rr
r
r�
get_icmptypes)szFirewallIcmpType.get_icmptypescCs||jkrttj|��dS)N)rrrZINVALID_ICMPTYPE)r�icmptyper
r
r�check_icmptype,s
zFirewallIcmpType.check_icmptypecCs|j|�|j|S)N)rr)rrr
r
r�get_icmptype0s
zFirewallIcmpType.get_icmptypecCs�|j}t|�dkrddg}x�|D]z}|dkrL|jjrB|jjrBq |jj}n,|dkrt|jjrj|jjrjq |jj}ng}|jj	�|kr t
jd|j|f�q W||j|j<dS)NrZipv4Zipv6z5ICMP type '%s' is not supported by the kernel for %s.)
Zdestination�lenrZip4tables_enabledZnftables_enabledZipv4_supported_icmp_typesZip6tables_enabledZipv6_supported_icmp_types�name�lowerrZinfo1r)r�objZ	orig_ipvsZipvZsupported_icmpsr
r
r�add_icmptype4s 


zFirewallIcmpType.add_icmptypecCs|j|�|j|=dS)N)rr)rrr
r
r�remove_icmptypeGs
z FirewallIcmpType.remove_icmptypeN)�__name__�
__module__�__qualname__rrrrrrrrr
r
r
rrsN)	�__all__Zfirewall.core.loggerrZfirewallrZfirewall.errorsr�objectrr
r
r
r�<module>score/__pycache__/prog.cpython-36.opt-1.pyc000064400000001266150351351730014250 0ustar003

��g��@sddlZdgZddd�ZdS)�N�runProgc
Cs�|dkrg}|g|}d}|r@t|d��}|j�j�}WdQRXddi}y tj|tjtjtjd|d�}Wntk
r|d
SX|j|�\}}	|j	dd	�}|j
|fS)N�rZLANG�CT)�stdin�stderr�stdoutZ	close_fds�env��zutf-8�replace)r	r
)�open�read�encode�
subprocess�Popen�PIPEZSTDOUT�OSErrorZcommunicate�decode�
returncode)
�prog�argvr�argsZinput_stringZhandlerZprocess�outputZ
err_output�r�/usr/lib/python3.6/prog.pyrs$

)NN)r�__all__rrrrr�<module>score/__pycache__/fw_nm.cpython-36.opt-1.pyc000064400000011713150351351730014405 0ustar003

��g�@s dZddddddddgZd	d
lZd	dlmZyejdd
�Wnek
rTdZYn8Xyd	dlmZdZWn e	eej
fk
r�dZYnXd
ad	dlm
Z
d	dlmZd	dlmZd	d
lZdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d�Zd"d�Zd#d�Zd
S)$z(Functions for NetworkManager interaction�check_nm_imported�nm_is_imported�nm_get_zone_of_connection�nm_set_zone_of_connection�nm_get_connections�nm_get_connection_of_interface�nm_get_bus_name�nm_get_dbus_interface�N)�GLib�NMz1.0F)rT)�errors)�
FirewallError)�logcCststtjd��dS)zNCheck function to raise a MISSING_IMPORT error if the import of NM failed
    zgi.repository.NM = 1.0N)�_nm_importedr
rZMISSING_IMPORT�rr�/usr/lib/python3.6/fw_nm.pyr0scCstS)znReturns true if NM has been properly imported
    @return True if import was successful, False otherwirse
    )rrrrrr6scCststjjd�atS)z�Returns the NM client object or None if the import of NM failed
    @return NM.Client instance if import was successful, None otherwise
    N)�
_nm_clientrZClient�newrrrr�
nm_get_client<srcCs�t�t�j|�}|dkrdS|j�}|dkr2dSy |j�tjjtjjB@rPdSWn t	k
rr|j
�rndSYnX|j�}|dkr�d}|S)z�Get zone of connection from NM
    @param connection name
    @return zone string setting of connection, empty string if not set, None if connection is unknown
    N�)rr�get_connection_by_uuid�get_setting_connection�	get_flagsr�SettingsConnectionFlags�NM_GENERATED�NM_VOLATILE�AttributeError�get_unsavedZget_zone)�
connection�con�setting_con�zonerrrrEs$
cCsVt�t�j|�}|dkrdS|j�}|dkr2dS|dkr>d}|jd|�|jdd�S)zSet the zone for a connection
    @param zone name
    @param connection name
    @return True if zone was set, else False
    NFrr!T)rrrrZset_propertyZcommit_changes)r!rrr rrrrcsc	Cs~|j�|j�t�t�j�}xX|D]P}|j�r4q&|j�}|j�}|j�}|||<x |D]}|j�}|rZ|||<qZWq&WdS)znGet active connections from NM
    @param connections return dict
    @param connections_name return dict
    N)	�clearrr�get_active_connections�get_vpnZget_id�get_uuid�get_devices�get_ip_iface)	ZconnectionsZconnections_nameZactive_connections�
active_con�nameZuuidZdevices�dev�ip_ifacerrrrxs


cCs�t�g}x�t�j�D]|}|j�r$qy&|j�}|j�tjjtjj	B@rHwWnt
k
rh|j�rdwYnXx&|j�D]}|j
�}|rt|j|�qtWqW|S)zGGet active interfaces from NM
    @returns list of interface names
    )rrr#r$�get_connectionrrrrrrrr&r'�append)Zactive_interfacesr(rr*r+rrr�nm_get_interfaces�s$r.cCs6g}x,t�D]"}t|�}|t|�kr|j|�qW|S)N)r.rrr-)r!Z
interfaces�	interfaceZconnrrr�nm_get_interfaces_in_zone�sr0cCs<t�x0t�j�D]"}|j�}|dkr(q||kr|SqWdS)zzGet device from NM which has the given IP interface
    @param interface name
    @returns NM.Device instance or None
    N)rrr&r')r/�devicer+rrr�nm_get_device_by_ip_iface�sr2cCsxt�t|�}|dkrdS|j�}|dkr.dSy |j�}|j�tjj@rLdSWn tk
rn|j	�rjdSYnX|j
�S)z�Get connection from NM that is using the interface
    @param interface name
    @returns connection that is using interface or None
    N)rr2Zget_active_connectionr,rrrrrrr%)r/r1r(rrrrr�s
cCsRtsdSy&tj�}|jtjtj�}|j}~~|Stk
rLt	j
d�YnXdS)Nz(Failed to get bus name of NetworkManager)r�dbusZ	SystemBusZ
get_objectr�DBUS_INTERFACEZ	DBUS_PATHZbus_name�	ExceptionrZdebug2)Zbus�objr)rrrr�scCstsdStjS)Nr)rrr4rrrrr�s)�__doc__�__all__ZgiZ
gi.repositoryr
Zrequire_version�
ValueErrorrr�ImportError�ErrorrZfirewallrZfirewall.errorsr
Zfirewall.core.loggerrr3rrrrrrr.r0r2rrrrrrr�<module>s@

	 	
core/__pycache__/fw_ifcfg.cpython-36.pyc000064400000002613150351351730014111 0ustar003

��g
�@sTdZddgZddlZddlZddlmZddlmZddlm	Z	dd�Z
d	d�ZdS)
z.Functions to search for and change ifcfg files�search_ifcfg_of_interface�ifcfg_set_zone_of_interface�N)�config)�log)�ifcfgcCs�tjjtj�sdSxtttjtj��D]`}|jd�s4q$xd
D]}|j|�r:q:q:Wd	|krXq$t	d
tj|f�}|j
�|jd�|kr$|Sq$Wdtj|f}tjj|�r�t	|�}|j
�|SdS)z6search ifcfg file for the interface in config.IFCFGDIRNzifcfg-�.bak�.orig�.rpmnew�.rpmorig�.rpmsave�-range�.z%s/%sZDEVICEz%s/ifcfg-%s)rrr	r
rr)�os�path�existsrZIFCFGDIR�sorted�listdir�
startswith�endswithr�read�get)�	interface�filenameZignored�
ifcfg_file�r�/usr/lib/python3.6/fw_ifcfg.pyr!s*

cCsn|dkrd}t|�}|dk	rj|jd�|krj|jd�dko>|dkrjtjd||jf�|jd|�|j�dS)zYSet zone (ZONE=<zone>) in the ifcfg file that uses the interface
    (DEVICE=<interface>)N�ZZONEzSetting ZONE=%s in '%s')rrrZdebug1r�set�write)Zzonerrrrrr?s)�__doc__�__all__rZos.pathZfirewallrZfirewall.core.loggerrZfirewall.core.io.ifcfgrrrrrrr�<module>score/__pycache__/watcher.cpython-36.pyc000064400000005256150351351730014002 0ustar003

��g��@s*dgZddlmZmZGdd�de�ZdS)�Watcher�)�Gio�GLibc@sdeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dS)rcCs"||_||_i|_i|_g|_dS)N)�	_callback�_timeout�	_monitors�	_timeouts�_blocked)�self�callbackZtimeout�r�/usr/lib/python3.6/watcher.py�__init__s
zWatcher.__init__cCs:tjj|�}|jtjjd�|j|<|j|jd|j�dS)N�changed)	r�File�new_for_pathZmonitor_directory�FileMonitorFlags�NONEr�connect�_file_changed_cb)r
Z	directory�gfilerrr
�
add_watch_dir"szWatcher.add_watch_dircCs:tjj|�}|jtjjd�|j|<|j|jd|j�dS)Nr)	rrrZmonitor_filerrrrr)r
�filenamerrrr
�add_watch_file(szWatcher.add_watch_filecCs
|jj�S)N)r�keys)r
rrr
�get_watches.szWatcher.get_watchescCs
||jkS)N)r)r
rrrr
�	has_watch1szWatcher.has_watchcCs|j|=dS)N)r)r
rrrr
�remove_watch4szWatcher.remove_watchcCs||jkr|jj|�dS)N)r	�append)r
rrrr
�block_source7s
zWatcher.block_sourcecCs||jkr|jj|�dS)N)r	�remove)r
rrrr
�unblock_source;s
zWatcher.unblock_sourcecCs4x.t|jj��D]}tj|j|�|j|=qWdS)N)�listrrr�
source_remove)r
rrrr
�clear_timeouts?szWatcher.clear_timeoutscCs ||jkr|j|�|j|=dS)N)r	rr)r
rrrr
�_call_callbackDs

zWatcher._call_callbackcCs�|j�}||jkr8||jkr4tj|j|�|j|=dS|tjjksh|tjjksh|tjj	ksh|tjj
kr�||jkr�tj|j|�|j|=tj|j|j
|�|j|<dS)N)Zget_parse_namer	rrr#rZFileMonitorEventZCHANGEDZCREATEDZDELETEDZATTRIBUTE_CHANGEDZtimeout_add_secondsrr%)r
ZmonitorZgio_fileZgio_other_fileZeventrrrr
rIs


zWatcher._file_changed_cbN)�__name__�
__module__�__qualname__rrrrrrrr!r$r%rrrrr
rsN)�__all__Z
gi.repositoryrr�objectrrrrr
�<module>score/__pycache__/fw_ipset.cpython-36.opt-1.pyc000064400000016503150351351730015121 0ustar003

��g�%�@sfdZdgZddlmZddlmZmZmZm	Z	ddl
mZddlm
Z
ddlmZGdd�de�Zd	S)
z
ipset backend�
FirewallIPSet�)�log)�remove_default_create_options�normalize_ipset_entry�check_entry_overlaps_existing�check_for_overlapping_entries)�IPSet)�errors)�
FirewallErrorc@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	d4dd�Z
dd�Zdd�Zd5dd�Z
dd�Zdd�Zdd�Zd6dd �Zd!d"�Zd#d$�Zd%d&�Zd7d'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Zd3S)8rcCs||_i|_dS)N)�_fw�_ipsets)�self�fw�r�/usr/lib/python3.6/fw_ipset.py�__init__#szFirewallIPSet.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r)r
rrr�__repr__'szFirewallIPSet.__repr__cCs|jj�dS)N)r�clear)r
rrr�cleanup,szFirewallIPSet.cleanupcCs||j�krttj|��dS)N)�
get_ipsetsr
r	Z
INVALID_IPSET)r
�namerrr�check_ipset/szFirewallIPSet.check_ipsetcCs||j�kS)N)r)r
rrrr�query_ipset3szFirewallIPSet.query_ipsetcCst|jj��S)N)�sortedr�keys)r
rrrr6szFirewallIPSet.get_ipsetscCst|j�dkS)Nr)�lenr)r
rrr�
has_ipsets9szFirewallIPSet.has_ipsetsFcCs&|j|�|j|}|r"|j|�|S)N)rr�check_applied_obj)r
r�applied�objrrr�	get_ipset<s



zFirewallIPSet.get_ipsetcCs4g}|jjr|j|jj�|jjr0|j|jj�|S)N)rZnftables_enabled�appendZnftables_backendZ
ipset_enabledZ
ipset_backend)r
�backendsrrrr#CszFirewallIPSet.backendscCs0|j|jjkr ttjd|j��||j|j<dS)Nz'%s' is not supported by ipset.)�typerZipset_supported_typesr
r	ZINVALID_TYPErr)r
r rrr�	add_ipsetKszFirewallIPSet.add_ipsetcCs�|j|}|jrh|rhy x|j�D]}|j|�q"WWqttk
rd}zttj|��WYdd}~XqtXntj	d|�|j|=dS)Nz,Keeping ipset '%s' because of timeout option)
rrr#�set_destroy�	Exceptionr
r	�COMMAND_FAILEDr�debug1)r
rZkeepr �backend�msgrrr�remove_ipsetQs
 zFirewallIPSet.remove_ipsetc<Cs$|j|}�x|j�D�]}|jdkr�|j�}||kr�d|jksv|jddksv|j||dksvt|j�||dkr�y|j|�Wn.tk
r�}zt	t
j|��WYdd}~XnX|jj
�r�y|j|j|j|j�Wn0tk
�r}zt	t
j|��WYdd}~Xn&Xd|_d|jk�r,|jddk�r,qy|j|j�Wn0tk
�rl}zt	t
j|��WYdd}~XnXx�|jD]J}y|j|j|�Wn0tk
�r�}zt	t
j|��WYdd}~XnX�qvWqy|j|j|j|j|jd�Wn0tk
�r}zt	t
j|��WYdd}~XqXd|_qWdS)N�ipset�timeout�0r�T)rr#rZset_get_active_terse�optionsr$�rm_def_cr_optsr&r'r
r	r(r�_individual_callsZ
set_creater�	set_flush�entries�set_add�set_restore)r
rr r*Zactiver+�entryrrr�apply_ipset]sL


&
zFirewallIPSet.apply_ipsetcCs>x8|j�D],}|j|}d|_tjd|�|j|�q
WdS)NFzApplying ipset '%s')rrrrr)r9)r
rr rrr�apply_ipsets�s

zFirewallIPSet.apply_ipsetscCs�xz|j�D]n}|jdkrq
x\|j�D]P}y|j|�|j|�Wq$tk
rr}z|jtjkrb|�WYdd}~Xq$Xq$Wq
WdS)NZnftables)	r#rr�
check_appliedr&r
�coder	�NOT_APPLIED)r
r*r-r+rrr�flush�s

zFirewallIPSet.flushTcCs|j||d�jS)N)r)r!r$)r
rrrrr�get_type�szFirewallIPSet.get_typecCst|j|dd�jjd��S)NT)r�,)rr!r$�split)r
rrrr�
get_dimension�szFirewallIPSet.get_dimensioncCs|j|�}|j|�dS)N)r!r)r
rr rrrr;�s
zFirewallIPSet.check_appliedcCs|jsttj|j��dS)N)rr
r	r=r)r
r rrrr�szFirewallIPSet.check_applied_objcCs.|j||d�}d|jkr*|jddkr*dSdS)N)rZfamilyZinet6Zipv6Zipv4)r!r1)r
rrr rrr�
get_family�s

zFirewallIPSet.get_familycCs�|j|dd�}t|�}tj||j|j�||jkrFttj	d||f��t
||j�y$x|j�D]}|j|j
|�q^WWn.tk
r�}zttj|��WYdd}~Xn&Xd|jks�|jddkr�|jj|�dS)NT)rz'%s' already is in '%s'r.r/)r!rr�check_entryr1r$r5r
r	ZALREADY_ENABLEDrr#r6rr'r(r")r
rr8r r*r+rrr�	add_entry�s
zFirewallIPSet.add_entrycCs�|j|dd�}t|�}||jkr4ttjd||f��y$x|j�D]}|j|j|�q@WWn.t	k
r�}zttj
|��WYdd}~Xn&Xd|jks�|jddkr�|jj|�dS)NT)rz'%s' not in '%s'r.r/)
r!rr5r
r	ZNOT_ENABLEDr#Z
set_deleterr'r(r1�remove)r
rr8r r*r+rrr�remove_entry�s
zFirewallIPSet.remove_entrycCsD|j|dd�}t|�}d|jkr:|jddkr:ttj|��||jkS)NT)rr.r/)r!rr1r
r	ZIPSET_WITH_TIMEOUTr5)r
rr8r rrr�query_entry�s
zFirewallIPSet.query_entrycCs|j|dd�}|jS)NT)r)r!r5)r
rr rrr�get_entries�szFirewallIPSet.get_entriescCs@|j|dd�}t|�x|D]}tj||j|j�qWd|jksN|jddkrT||_y"x|j�D]}|j|j	�q`WWn.t
k
r�}zttj
|��WYdd}~XnXd|_yXxR|j�D]F}|jjr�x8|jD]}|j|j	|�q�Wq�|j|j	|j|j|jd�q�WWn0t
k
�r4}zttj
|��WYdd}~XnXd|_dS)NT)rr.r/)r!rrrDr1r$r5r#r4rr'r
r	r(rrr3r6r7)r
rr5r r8r*r+rrr�set_entries�s.
zFirewallIPSet.set_entriesN)F)F)T)T)�__name__�
__module__�__qualname__rrrrrrrr!r#r%r,r9r:r>r?rBr;rrCrErGrHrIrJrrrrr"s0

1

		N)�__doc__�__all__Zfirewall.core.loggerrZfirewall.core.ipsetrr2rrrZfirewall.core.io.ipsetrZfirewallr	Zfirewall.errorsr
�objectrrrrr�<module>score/__pycache__/ipXtables.cpython-36.pyc000064400000104137150351351730014276 0ustar003

��g���@s(ddlZddlZddlmZddlmZddlmZm	Z	m
Z
mZmZm
Z
mZmZddlmZddlmZmZmZmZmZddlmZmZmZmZmZmZmZddl Z dZ!d	d
dgdd
gdd
d	d
dgdd
d
gd	d
dgd�Z"ddd�Z#ddd�Z$dd�Z%dd�Z&dd�Z'Gdd�de(�Z)Gdd�de)�Z*dS)�N)�runProg)�log)�tempFile�readfile�	splitArgs�	check_mac�portStr�check_single_address�
check_address�normalizeIP6)�config)�
FirewallError�INVALID_PASSTHROUGH�INVALID_RULE�
UNKNOWN_ERROR�INVALID_ADDR)�Rich_Accept�Rich_Reject�	Rich_Drop�	Rich_Mark�Rich_Masquerade�Rich_ForwardPort�Rich_IcmpBlock��INPUT�OUTPUT�FORWARD�
PREROUTING�POSTROUTING)�security�raw�mangle�nat�filterzicmp-host-prohibitedzicmp6-adm-prohibited)�ipv4�ipv6�icmpz	ipv6-icmpcCs�ddddddd�}|dd�}x~|D]v}y|j|�}Wntk
rLw$YnX|d
kr�yt||d	�Wntk
r~YnX|j|d	�||||<q$W|S)z Inverse valid rule z-Dz--deletez-Xz--delete-chain)z-Az--appendz-Iz--insertz-Nz--new-chainN�-I�--insert�)r'r()�index�	Exception�int�pop)�args�replace_args�ret_args�arg�idx�r3�/usr/lib/python3.6/ipXtables.py�common_reverse_rule9s(
r5cCs�ddddddd�}|dd�}x�|D]x}y|j|�}Wntk
rLw$YnX|dkr�yt||d	�Wntk
r~YnX|j|d	�||||<|SWttd
��dS)z Reverse valid passthough rule z-Dz--deletez-Xz--delete-chain)z-Az--appendz-Iz--insertz-Nz--new-chainN�-I�--insertr)zno '-A', '-I' or '-N' arg)r6r7)r*�
ValueErrorr,r-r
r)r.r/r0�xr2r3r3r4�common_reverse_passthrough^s,
r:cCs�t|�}tddddddddd	d
ddd
dddddddg�}t||@�dkrbttdt||@�d��tddddddg�}t||@�dkr�ttd��dS)zZ Check if passthough rule is valid (only add, insert and new chain
    rules are allowed) z-Cz--checkz-Dz--deletez-Rz	--replacez-Lz--listz-Sz--list-rulesz-Fz--flushz-Zz--zeroz-Xz--delete-chainz-Pz--policyz-Ez--rename-chainrzarg '%s' is not allowedz-Az--appendz-Iz--insertz-Nz--new-chainzno '-A', '-I' or '-N' argN)�set�lenr
r�list)r.Znot_allowedZneededr3r3r4�common_check_passthrough�s*

r>c@s�eZdZdZdZdZdd�Zdd�Zdd�Zd	d
�Z	dd�Z
d
d�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �Zdhd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zdid,d-�Zd.d/�Zdjd1d2�Zd3d4�Zd5d6�Zdkd8d9�Zdld:d;�Z d<d=�Z!d>d?�Z"d@dA�Z#dBdC�Z$dDdE�Z%dFdG�Z&dHdI�Z'dJdK�Z(dLdM�Z)dNdO�Z*dPdQ�Z+dmdRdS�Z,dndTdU�Z-dodVdW�Z.dXdY�Z/dpdZd[�Z0dqd\d]�Z1drd^d_�Z2dsd`da�Z3dbdc�Z4ddde�Z5dfdg�Z6d!S)t�	ip4tablesr$TcCsd||_tj|j|_tjd|j|_|j�|_|j�|_	|j
�g|_i|_i|_
g|_i|_dS)Nz
%s-restore)�_fwrZCOMMANDS�ipv�_command�_restore_command�_detect_wait_option�wait_option�_detect_restore_wait_option�restore_wait_option�fill_exists�available_tables�rich_rule_priority_counts�policy_priority_counts�zone_source_index_cache�
our_chains)�self�fwr3r3r4�__init__�s

zip4tables.__init__cCs$tjj|j�|_tjj|j�|_dS)N)�os�path�existsrBZcommand_existsrCZrestore_command_exists)rNr3r3r4rH�szip4tables.fill_existscCs�|jr(|j|kr(|jgdd�|D�}ndd�|D�}tjd|j|jdj|��t|j|�\}}|dkr�td|jdj|�|f��|S)NcSsg|]}d|�qS)z%sr3)�.0�itemr3r3r4�
<listcomp>�sz#ip4tables.__run.<locals>.<listcomp>cSsg|]}d|�qS)z%sr3)rTrUr3r3r4rV�sz	%s: %s %s� rz'%s %s' failed: %s)rEr�debug2�	__class__rB�joinrr8)rNr.Z_args�status�retr3r3r4Z__run�szip4tables.__runc
Cs<y|j|�}Wntk
r"dSX||||d�<dSdS)NF�T)r*r8)rN�rule�patternZreplacement�ir3r3r4�
_rule_replace�szip4tables._rule_replacecCs|tko|t|kS)N)�BUILT_IN_CHAINS)rNrA�table�chainr3r3r4�is_chain_builtin�szip4tables.is_chain_builtincCs2d|g}|r|jd�n
|jd�|j|�|gS)Nz-tz-Nz-X)�append)rN�addrcrdr^r3r3r4�build_chain_rules�s

zip4tables.build_chain_rulescCs8d|g}|r |d|t|�g7}n|d|g7}||7}|S)Nz-tz-Iz-D)�str)rNrgrcrdr*r.r^r3r3r4�
build_rule�szip4tables.build_rulecCst|�S)N)r5)rNr.r3r3r4�reverse_rule�szip4tables.reverse_rulecCst|�dS)N)r>)rNr.r3r3r4�check_passthrough�szip4tables.check_passthroughcCst|�S)N)r:)rNr.r3r3r4�reverse_passthrough�szip4tables.reverse_passthroughcCs�d}y|jd�}Wntk
r&YnXt|�|dkrD||d}d}xLd
D]D}y|j|�}Wntk
rtYqNXt|�|dkrN||d}qNW||fS)Nr#z-tr]�-A�--append�-I�--insert�-N�--new-chain)rnrorprqrrrs)r*r8r<)rNr.rcr`rd�optr3r3r4�passthrough_parse_table_chain�s$z'ip4tables.passthrough_parse_table_chaincCs4yH|jd�}|j|�|j|�}d|dkr:||df}n||df}WnFtk
r�y|jd�}|j|�d}Wntk
r�dSXYnXd}|ddkr�d}|r�|r�||kr�|j|�nn|�r0|�r�||kr�|j|�|jdd
�d�|j|�}n|jj�rd}nt|�}d|d<|j	dd|d�dS)Nz%%ZONE_SOURCE%%z-m���z%%ZONE_INTERFACE%%Tr�-D�--deleteFcSs|dS)Nrr3)r9r3r3r4�<lambda>&sz4ip4tables._run_replace_zone_source.<locals>.<lambda>)�keyz-Ir)z%dr])ryrz)
r*r-r8�removerf�sortr@�_allow_zone_driftingr<�insert)rNr^rLr`�zoneZzone_source�rule_addr*r3r3r4�_run_replace_zone_source	s>







z"ip4tables._run_replace_zone_sourcecCsy|j|�}Wntk
r$Y�n�Xd}d}d}|j|�|j|�}t|�tkr\ttd��d}	xLdD]D}
y|j|
�}Wntk
r�YqfXt|�|dkrf||d}	qfWxhdD]`}
y|j|
�}Wntk
r�Yq�Xt|�|dk�r�||d}|
dk�rd}|
dkr�d}q�W|	|f}|�sp||k�sP|||k�sP|||dk�rZttd��|||d8<n�||k�r�i||<|||k�r�d|||<d}
xHt	||j
��D]4}||k�r�|�r�P|
|||7}
||k�r�P�q�W|||d7<d
||<|j|dd|
�dS)a
        Change something like
          -t filter -I public_IN %%RICH_RULE_PRIORITY%% 123
        or
          -t filter -A public_IN %%RICH_RULE_PRIORITY%% 321
        into
          -t filter -I public_IN 4
        or
          -t filter -I public_IN
        TFr]z%priority must be followed by a numberr#�-t�--table�-A�--append�-I�--insert�-D�--deleterz*nonexistent or underflow of priority countr)z%dN���)r�r�)r�r�r�r�r�r�)r�r�)r�r�)r*r8r-�typer,r
rr<r�sorted�keysr�)rNr^Zpriority_counts�tokenr`r�r�Zinsert_add_index�priorityrcrt�jrdr*�pr3r3r4�_set_rule_replace_priority2sj








z$ip4tables._set_rule_replace_prioritycCsPt�}i}tj|j�}tj|j�}tj|j�}�x�|D�]�}|dd�}	|j|	dddt|jg�|j|	dt	|jg�y|	j
d�}
Wntk
r�Yn8X|dkr�q6|d$kr�d
dd|g|	|
|
d
�<n
|	j|
�|j
|	|d�|j
|	|d�|j|	|�d}xZd%D]R}y|	j
|�}
Wntk
�r,Yn(Xt|	�|
d
k�r|	j|
�|	j|
�}�qWxhtt|	��D]X}
xPtjD]F}
|
|	|
k�rt|	|
jd��o�|	|
jd��rtd|	|
|	|
<�qtW�qhW|j|g�j|	�q6WxR|D]J}||}|jd|�x"|D]}	|jdj|	�d��qW|jd��q�W|j�tj|j�}tjd|j|j d|j|j!f�g}|j"�rz|j|j"�|jd�t#|j ||jd�\}}tj$�dk�r
t%|j�}|dk	�r
d
}
xH|D]@}tj&d|
|fd
dd �|jd��s�tj&d!d
d"�|
d
7}
�q�Wtj'|j�|dk�r:td#|j dj|�|f��||_||_||_dS)&Nz
%%REJECT%%�REJECTz
--reject-withz%%ICMP%%z%%LOGTYPE%%�off�unicast�	broadcast�	multicastz-m�pkttypez
--pkt-typer]z%%RICH_RULE_PRIORITY%%z%%POLICY_PRIORITY%%r#�-t�--table�"z"%s"z*%s
rW�
zCOMMIT
z	%s: %s %sz%s: %dz-n)�stdinr)z%8d: %sr)�nofmt�nlr)r�z'%s %s' failed: %s)r�r�r�)r�r�)(r�copy�deepcopyrJrKrLra�DEFAULT_REJECT_TYPErA�ICMPr*r8r-r�r�r<�range�stringZ
whitespace�
startswith�endswith�
setdefaultrf�writerZ�closerQ�stat�namerrXrYrC�st_sizerGrZgetDebugLogLevelrZdebug3�unlink)rN�rules�
log_denied�	temp_fileZtable_rulesrJrKrLZ_ruler^r`rcrt�cr�r.r[r\�lines�liner3r3r4�	set_rules�s�









zip4tables.set_rulesc
Cs�|j|dddt|jg�|j|dt|jg�y|jd�}Wntk
rRYn:X|dkr`dS|dkr�ddd
|g|||d�<n
|j|�tj|j	�}tj|j
�}tj|j�}|j||d�|j||d�|j
||�|j|�}||_	||_
||_|S)Nz
%%REJECT%%r�z
--reject-withz%%ICMP%%z%%LOGTYPE%%r�rr�r�r�z-mr�z
--pkt-typer]z%%RICH_RULE_PRIORITY%%z%%POLICY_PRIORITY%%)r�r�r�)rar�rAr�r*r8r-r�r�rJrKrLr�r��_ip4tables__run)rNr^r�r`rJrKrL�outputr3r3r4�set_rule�s.

zip4tables.set_ruleNcCs�g}|r|gntj�}xx|D]p}||jkr6|j|�qy,|jd|ddg�|jj|�|j|�Wqtk
r�tjd|j|f�YqXqW|S)Nz-tz-Lz-nzA%s table '%s' does not exist (or not enough permission to check).)	rbr�rIrfr�r8r�debug1rA)rNrcr\Ztablesr3r3r4�get_available_tabless

zip4tables.get_available_tablescCs`d}t|jdddg�}|ddkr\d}t|jdddg�}|ddkrHd}tjd|j|j|�|S)Nrz-wz-Lz-nrz-w10z%s: %s will be using %s option.)rrBrrXrY)rNrEr\r3r3r4rDszip4tables._detect_wait_optioncCs�t�}|jd�|j�d}xJdD]B}t|j|g|jd�}|ddkr"d|dkr"d	|dkr"|}Pq"Wtjd
|j|j|�t	j
|j�|S)Nz#foor�-w�--wait=2)r�rzinvalid optionr]zunrecognized optionz%s: %s will be using %s option.)r�r�)rr�r�rrCr�rrXrYrQr�)rNr�rEZtest_optionr\r3r3r4rF"s

z%ip4tables._detect_restore_wait_optioncCsVi|_i|_g|_g}x:tj�D].}|j|�s0q xdD]}|jd||g�q6Wq W|S)N�-F�-X�-Zz-t)r�r�r�)rJrKrLrbr�r�rf)rNr�rc�flagr3r3r4�build_flush_rules5s

zip4tables.build_flush_rulescCsfg}|dkrdn|}xLtj�D]@}|j|�s.q|dkr8qx$t|D]}|jd|d||g�qBWqW|S)NZPANIC�DROPr"z-tz-P)rbr�r�rf)rN�policyr��_policyrcrdr3r3r4�build_set_policy_rulesDs
z ip4tables.build_set_policy_rulescCs g}d}y"|jd|jdkrdnddg�}WnJtk
rt}z.|jdkrVtjd|�ntjd|�WYd	d	}~XnX|j�}d
}x�|D]�}|r�|j�j�}|j�}xD|D]<}	|	j	d�r�|	j
d�r�|	d
d�}
n|	}
|
|kr�|j|
�q�W|jdko�|j	d��s|jdkr�|j	d�r�d}q�W|S)zQReturn ICMP types that are supported by the iptables/ip6tables command and kernelrz-pr$r&z	ipv6-icmpz--helpziptables error: %szip6tables error: %sNF�(�)r]zValid ICMP Types:r%zValid ICMPv6 Types:Tr�)r�rAr8rr��
splitlines�strip�lower�splitr�r�rf)rNrAr\r�Zexr�Zin_typesr�Zsplitsr�r9r3r3r4�supported_icmp_typesPs4
 

zip4tables.supported_icmp_typescCsgS)Nr3)rNr3r3r4�build_default_tablesqszip4tables.build_default_tablesr�c	Csi}|jd�rpg|d<t�|jd<xLtdD]@}|djd|�|djd||f�|jdjd|�q,W|jd��r\g|d<t�|jd<x�tdD]�}|djd|�|djd||f�|jdjd|�|dkr�xt|jjr�ddd	d
gndd	d
gD]R}|djd||f�|djd|||f�|jdjtd
||fg���qWq�W|jd��rNg|d<t�|jd<x�tdD]�}|djd|�|djd||f�|jdjd|�|dk�r�xv|jj�r�ddd	d
gndd	d
gD]R}|djd||f�|djd|||f�|jdjtd
||fg���q�W�q�W|jd��r@g|d<t�|jd<x�tdD]�}|djd|�|djd||f�|jdjd|�|d9k�rxxv|jj�r�ddd	d
gndd	d
gD]R}|djd||f�|djd|||f�|jdjtd
||fg���q�W�qxWg|d<t�|jd<|djd�|djd�|djd�|djd�|jdjtd��xf|jj�r�ddd	d
gndd	d
gD]B}|djd|�|djd|�|jdjtd|���q�W|dk�r |djd�|djd�|dk�rF|djd�|djd�|djd�|djd �|djd!�|djd"�|jdjtd#��xJd:D]B}|djd$|�|djd%|�|jdjtd&|���q�Wxzd;D]r}xj|jj�r
dd	gnd	gD]N}|djd)||f�|djd*||f�|jdjtd+||f���qW�q�WxJd<D]B}|djd$|�|djd%|�|jdjtd&|���qnW|dk�r�|djd,�|djd-�|dk�r�|djd.�|djd/�|dd0d1d2d3g7<|jdjtd4��xJd=D]B}|djd5|�|djd6|�|jdjtd7|���q2WxJd>D]B}|djd5|�|djd6|�|jdjtd7|���q~Wg}xJ|D]B}||j�k�r�q�x(||D]}|jd8|gt	|���q�W�q�W|S)?Nrz-N %s_directz-A %s -j %s_directz	%s_directr r�POLICIES_preZZONES_SOURCEZZONES�
POLICIES_postz-N %s_%sz-A %s -j %s_%sz%s_%sr!r"rr#zB-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPTz-A INPUT -i lo -j ACCEPTz-N INPUT_directz-A INPUT -j INPUT_directZINPUT_directz-N INPUT_%sz-A INPUT -j INPUT_%szINPUT_%sr�z^-A INPUT -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: 'z/-A INPUT -m conntrack --ctstate INVALID -j DROPz9-A INPUT %%LOGTYPE%% -j LOG --log-prefix 'FINAL_REJECT: 'z-A INPUT -j %%REJECT%%zD-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPTz-A FORWARD -i lo -j ACCEPTz-N FORWARD_directz-A FORWARD -j FORWARD_directZFORWARD_directz
-N FORWARD_%sz-A FORWARD -j FORWARD_%sz
FORWARD_%s�IN�OUTz-N FORWARD_%s_%sz-A FORWARD -j FORWARD_%s_%sz
FORWARD_%s_%sz`-A FORWARD -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: 'z1-A FORWARD -m conntrack --ctstate INVALID -j DROPz;-A FORWARD %%LOGTYPE%% -j LOG --log-prefix 'FINAL_REJECT: 'z-A FORWARD -j %%REJECT%%z-N OUTPUT_directz>-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPTz-A OUTPUT -o lo -j ACCEPTz-A OUTPUT -j OUTPUT_directZ
OUTPUT_directz-N OUTPUT_%sz-A OUTPUT -j OUTPUT_%sz	OUTPUT_%sz-t)rr)r�)r�r�)r�)r�)r�)
r�r;rMrbrfrgr@r�updater)	rNr�Z
default_rulesrdZdispatch_suffix�	directionZfinal_default_rulesrcr^r3r3r4�build_default_rulesus�
$(
&*
&*&



(






"zip4tables.build_default_rulescCsf|dkrdddhS|dkr,d|j�kr,dhS|dkrHd|j�krHddhS|d	krbd	|j�krbdhSiS)
Nr#r�
FORWARD_IN�FORWARD_OUTr!rr"rr )r�)rNrcr3r3r4�get_zone_table_chains�s
zip4tables.get_zone_table_chainsc	s�|jjj|���jdkrdnd��dkr4�dkr4dnd}	|jjj|�t|	��g}
g}x|D]}|
jd|g�qZWx|D]}|jd	|g�qvWxB|D]:}
|jjj|
�}|dkr�|j	|�r�q�|
j|j
d|
��q�Wx\|D]T}
|jjj|
�}|dk�r|j	|��rq�t|
��r�dk�rq�|j|j
d|
��q�W������fdd�}g}|
�r�x�|
D]F}|�r�x8|D]}|j|||���qdWn|�r�n|j||d���qTWnH|�r�n@|�r�x8|D]}|j|d|���q�Wn|�r�n|j|dd��|S)Nr�pre�postr"rTFz-iz-or$r%z-sr�rz-dcsVddd��}d�|d��fd�jg}|r6|j|�|rD|j|�|jd�g�|S)Nz-Az-D)TFz-tz%s_POLICIES_%sz%%POLICY_PRIORITY%%z-j)r��extend)�ingress_fragment�egress_fragment�add_delr^)r�rd�chain_suffix�enable�p_objrcr3r4�_generate_policy_dispatch_rules


zSip4tables.build_policy_ingress_egress_rules.<locals>._generate_policy_dispatch_rule)r$r%)r$r%)rr�r)r@r�Z
get_policyr��policy_base_chain_name�POLICY_CHAIN_PREFIXrfr�Zcheck_source�is_ipv_supported�_rule_addr_fragmentr)rNr�r�rcrdZingress_interfacesZegress_interfacesZingress_sourcesZegress_sources�isSNATZingress_fragmentsZegress_fragments�	interface�addrrAr�r�r�r�r3)r�rdr�r�r�rcr4�!build_policy_ingress_egress_rules�sR






z+ip4tables.build_policy_ingress_egress_rulesFc
Cs�|dkr|dkrdnd}|jjj||t|d�}	ddddddd�|}
d	}|rb|rbd
d|dg}n,|rtd
d|g}ndd|g}|s�|dg7}|d||
|||	g7}|gS)Nr"rTF)r�z-iz-o)rrrr�r�rz-gz-Iz%s_ZONESz%%ZONE_INTERFACE%%z-Az-Dz-t)r@r�r�r�)
rNr�r�r�r�rcrdrfr�r�rt�actionr^r3r3r4�!build_zone_source_interface_rulesKs&

z+ip4tables.build_zone_source_interface_rulescCs�|jd�rP|dd�}|dkr$d}nd}dj|g|jjj|��}ddd	||gSt|�rz|dkrjttd
��ddd|j�gSt	d
|�r�t
|�}n,td
|�r�|jd�}t
|d�d|d}||gSdS)Nzipset:�z-d�dst�src�,z-mr;z--match-setzCan't match a destination MAC.�macz--mac-sourcer%�/rr])
r�rZr@�ipsetZ
get_dimensionrr
r�upperr	rr
r�)rNrt�address�invertr��flags�
addr_splitr3r3r4r�es"





zip4tables._rule_addr_fragmentc
Cs�ddd�|}|dkr"|dkr"dnd}|jjj||t|d�}	d	d
d	d	d
d
d�|}
|jjrdd|}nd
|}t|�r�|dkr�gS||d|d|g}|j|j|
|��|jd|	g�|gS)Nz-Iz-D)TFr"rTF)r�z-sz-d)rrrr�r�rz%s_ZONES_SOURCEz%s_ZONESr�rz%%ZONE_SOURCE%%z-tz-g)rr�r)r@r�r�r�rrr�r�)
rNr�r�r�r�rcrdr�r�r�rtZzone_dispatch_chainr^r3r3r4�build_zone_source_address_rules{s&
z)ip4tables.build_zone_source_address_rulescCs>ddd�|}ddd�|}|dkr0|dkr0dnd	}|jjj||t|d
�}|j|jt|d|d|d
|d|d|g��g}	|	j||d|g�|	j|d
|d|g�|	j|d|d|g�|	j|d|d|g�|	j|d|d|g�|	j|d|d|g�|	j||d|dd
|g�|	j||d|dd|g�|	j||d|dd|g�|	j||d|dd|g�|	j||d|dd|g�|jjj|j	}
|jj
�dk�r|dk�r|
dk�r�|	j||d|ddddd|g	�|
dk�r|	j||d|ddddd|g	�|dk�r,|
dk�r,|	j||d|d|
g�|�s:|	j�|	S)Nz-Nz-X)TFz-Az-Dr"rTF)r�z%s_logz%s_denyz%s_prez%s_postz%s_allowz-tz-jr�r#r��
%%REJECT%%z%%LOGTYPE%%�LOGz--log-prefixz
"%s_REJECT: "r�z"%s_DROP: "�ACCEPT)r�r�)r�r�r�r�)r@r�r�r�rMr�r;rfZ	_policies�target�get_log_denied�reverse)rNr�r�rcrdZ
add_del_chainZadd_del_ruler�r�r�r�r3r3r4�build_policy_chain_rules�sN




z"ip4tables.build_policy_chain_rulescCs2|sgSddd|jg}|jdk	r.|d|jg7}|S)Nz-m�limitz--limitz
--limit-burst)�valueZburst)rNr�sr3r3r4�_rule_limit�s
zip4tables._rule_limitcCs�t|j�tttgkrn<|jrHt|j�tttt	gkrRt
tdt|j���n
t
td��|jdkr�t|j�ttgks�t|j�tt	gkr�dSt|j�tgks�t|j�ttgkr�dSn|jdkr�dSdSdS)NzUnknown action %szNo rule action specified.r�allowZdenyr�r�)
r��elementrrrr�rrrrr
rr�)rN�	rich_ruler3r3r4�_rich_rule_chain_suffix�s 


z!ip4tables._rich_rule_chain_suffixcCs>|jr|jrttd��|jdkr(dS|jdkr6dSdSdS)NzNot log or auditrrr�r�)r�auditr
rr�)rNrr3r3r4� _rich_rule_chain_suffix_from_log�s


z*ip4tables._rich_rule_chain_suffix_from_logcCs|jdkrgSd|jgS)Nrz%%RICH_RULE_PRIORITY%%)r�)rNrr3r3r4�_rich_rule_priority_fragment�s
z&ip4tables._rich_rule_priority_fragmentc
Cs�|js
gS|jjj||t�}ddd�|}|j|�}d||d||fg}	|	|j|�7}	|	|ddg7}	|jjr�|	dd	|jjg7}	|jjr�|	d
d|jjg7}	|	|j	|jj
�7}	|	S)Nz-Az-D)TFz-tz%s_%sz-jr�z--log-prefixz'%s'z--log-levelz%s)rr@r�r�r�rr�prefix�levelrr)
rNr�rr�rc�
rule_fragmentr�r�r�r^r3r3r4�_rich_rule_log�s
zip4tables._rich_rule_logcCs�|js
gSddd�|}|jjj||t�}|j|�}d||d||fg}	|	|j|�7}	|	|7}	t|j�t	krrd}
n,t|j�t
kr�d}
nt|j�tkr�d}
nd	}
|	d
dd|
g7}	|	|j|jj
�7}	|	S)
Nz-Az-D)TFz-tz%s_%sZacceptZrejectZdrop�unknownz-jZAUDITz--type)r
r@r�r�r�rrr�r�rrrrr)rNr�rr�rcrr�r�r�r^Z_typer3r3r4�_rich_rule_audits$
zip4tables._rich_rule_auditcCs2|js
gSddd�|}|jjj||t�}|j|�}d||f}	t|j�tkrXddg}
n�t|j�tkr�ddg}
|jjr�|
d|jjg7}
nnt|j�t	kr�dd	g}
nVt|j�t
kr�d
}|jjj||t�}d||f}	ddd|jjg}
ntt
d
t|j���d|||	g}||j|�7}|||
7}||j|jj�7}|S)Nz-Az-D)TFz%s_%sz-jr�r�z
--reject-withr�r!�MARKz--set-xmarkzUnknown action %sz-t)r�r@r�r�r�r	r�rrrrr;r
rrrr)rNr�rr�rcrr�r�r�rdZrule_actionr^r3r3r4�_rich_rule_action$s4


zip4tables._rich_rule_actioncCs�|sgSg}|jr�|jr"|jd�td|j�rB|dt|j�g7}q�td|j�r||jjd�}|dt|d�d|dg7}q�|d|jg7}nD|jr�|ddg7}|jr�|jd�|jj	j
|jd	�}|d
|j|g7}|S)N�!r%z-dr�rr]z-mr;r�z--match-set)r�r�rfr	rr
r�r�r@r��_ipset_match_flags)rNZ	rich_destrr�r�r3r3r4�_rich_rule_destination_fragmentFs&
"
z)ip4tables._rich_rule_destination_fragmentcCs|sgSg}|jr�|jr"|jd�td|j�rB|dt|j�g7}nHtd|j�r||jjd�}|dt|d�d|dg7}n|d|jg7}n�t|d�r�|jr�|ddg7}|jr�|jd�|d	|jg7}nPt|d
�o�|j	�r|ddg7}|jr�|jd�|j
jj|j	d�}|d
|j	|g7}|S)Nrr%z-sr�rr]r�z-mz--mac-sourcer�r;r�z--match-set)
r�r�rfr	rr
r��hasattrr�r�r@r�r)rNZrich_sourcerr�r�r3r3r4�_rich_rule_source_fragment^s0
"

z$ip4tables._rich_rule_source_fragmentcCsddd�|}d}|jjj||t�}	d|g}
|rD|
ddt|�g7}
|rT|
d|g7}
|rx|
|j|j�7}
|
|j|j�7}
|s�t	|j
�tkr�|
d	d
ddg7}
g}|r�|j|j
|||||
��|j|j|||||
��|j|j|||||
��n"|j|d
|	d|g|
ddg�|S)Nz-Az-D)TFr#z-pz--dportz%sz-dz-m�	conntrackz	--ctstatez
NEW,UNTRACKEDz%s_allowz-tz-jr�)r@r�r�r�rr�destinationr�sourcer�r�rrfrrr)rNr�r��proto�portrrr�rcr�rr�r3r3r4�build_policy_ports_rules{s*z"ip4tables.build_policy_ports_rulescCs�ddd�|}d}|jjj||t�}d|g}	|r<|	d|g7}	|r`|	|j|j�7}	|	|j|j�7}	|stt|j	�t
kr�|	ddd	d
g7}	g}
|r�|
j|j|||||	��|
j|j
|||||	��|
j|j|||||	��n"|
j|d|d|g|	d
dg�|
S)Nz-Az-D)TFr#z-pz-dz-mrz	--ctstatez
NEW,UNTRACKEDz%s_allowz-tz-jr�)r@r�r�r�rrrrr�r�rrfrrr)rNr�r��protocolrrr�rcr�rr�r3r3r4�build_policy_protocol_rules�s&z%ip4tables.build_policy_protocol_rulescCsddd�|}d}|jjj||t�}	d|g}
|rD|
ddt|�g7}
|rT|
d|g7}
|rx|
|j|j�7}
|
|j|j�7}
|s�t	|j
�tkr�|
d	d
ddg7}
g}|r�|j|j
|||||
��|j|j|||||
��|j|j|||||
��n"|j|d
|	d|g|
ddg�|S)Nz-Az-D)TFr#z-pz--sportz%sz-dz-mrz	--ctstatez
NEW,UNTRACKEDz%s_allowz-tz-jr�)r@r�r�r�rrrrrr�r�rrfrrr)rNr�r�rrrrr�rcr�rr�r3r3r4�build_policy_source_ports_rules�s*z)ip4tables.build_policy_source_ports_rulescCsvd}|jjj||t�}	ddd�|}
|
d|	ddd|g}|rP|dd	t|�g7}|r`|d
|g7}|ddd
|g7}|gS)Nr z-Az-D)TFz%s_allowz-tz-pz--dportz%sz-dz-jZCTz--helper)r@r�r�r�r)rNr�r�rrrZhelper_nameZmodule_short_namercr�r�r^r3r3r4�build_policy_helper_ports_rules�sz)ip4tables.build_policy_helper_ports_rulesc
	Cs�ddd�|}|jjj||t�}g}	|rH|	jdd|d|d|dd	g�n6t|�rTgS|	jdd|d|g|jd
|�dd	g�|	S)Nz-Az-D)TFz-tr#z%s_allowz-oz-jr�z-d)r@r�r�r�rfrr�)
rNr�r�r�rcr�rr�r�r�r3r3r4�build_zone_forward_rules�sz"ip4tables.build_zone_forward_rulesc
Cs,d}|jjj||tdd�}ddd�|}g}|rj|j|�}||j|�7}||j|j�7}||j|j	�7}nd}g}	|	j
dd|d	||fg|d
ddd
dg�g}|r�|j|�}||j|�7}||j|j�7}||j|j	�7}nd}d}|jjj||t�}|	j
dd|d	||fg|ddddd
dg�|	S)Nr"T)r�z-Az-D)TFrz-tz%s_%srz-o�loz-jZ
MASQUERADEr#z-mrz	--ctstatez
NEW,UNTRACKEDr�)r@r�r�r�r	rrrrrrf)
rNr�r�rrcr�r�rr�r�r3r3r4�build_policy_masquerade_rules�s6

z'ip4tables.build_policy_masquerade_rulesc
Cs
d}|jjj||t�}	ddd�|}
d}|rPtd|�rH|dt|�7}n||7}|rn|dkrn|dt|d	�7}g}|r�|j|�}
|j|�}||j	|j
�7}||j|j�7}nd
}
g}|r�|j
|j|||d|��|j
dd|
d|	|
fg|d
|dt|�ddd|g�|S)Nr"z-Az-D)TFrr%z[%s]z:%s�-rz-tz%s_%sz-pz--dportz-jZDNATz--to-destination)r@r�r�r�r	rrr	rrrrrrfr)rNr�r�rr ZtoportZtoaddrrrcr�r�Ztorr�r�r3r3r4�build_policy_forward_port_ruless2


z)ip4tables.build_policy_forward_port_rulescCs�d}|jjj||t�}ddd�|}|jdkrFddg}ddd	|jg}	ndd
g}ddd|jg}	g}
|jjj|�r|d
|}d}nd|}d}g}
|r�|
|j|j�7}
|
|j	|j
�7}
|
||	7}
|�rP|
j|j|||||
��|
j|j
|||||
��|j�r|
j|j|||||
��n:|j|�}|
jd||d||fg|j|�|
ddg�n`|jj�dk�r�|dk�r�|
j||d|g|
ddddd|g�|
j||d|g|
d|g�|
S)Nr#z-Az-D)TFr$z-pr&z-mz--icmp-typez	ipv6-icmpZicmp6z
--icmpv6-typez%s_allowr�z%s_denyz
%%REJECT%%z-tz%s_%sz-jr�z%%LOGTYPE%%r�z--log-prefixz"%s_ICMP_BLOCK: ")r@r�r�r�rAr��query_icmp_block_inversionrrrrrfrrr�rr	rr�)rNr�r�Zictrrcr�r�r�matchr�Zfinal_chainZfinal_targetrr�r3r3r4�build_policy_icmp_block_rules3sJ

 z'ip4tables.build_policy_icmp_block_rulesc	Cs�d}|jjj||t�}g}d}|jjj|�r�d}|jj�dkr�|rRd|t|�g}nd|g}|d|dd	d
ddd
d|g	}|j|�|d7}nd}|r�d|t|�g}nd|g}|d|dd	d|g}|j|�|S)Nr#r�z
%%REJECT%%r�z-Iz-Dz-tz-pz%%ICMP%%z%%LOGTYPE%%z-jr�z--log-prefixz"%s_ICMP_BLOCK: "r]r�)r@r�r�r�r)r�rirf)	rNr�r�rcr�r�Zrule_idxZ
ibi_targetr^r3r3r4�'build_policy_icmp_block_inversion_rulesds.



z1ip4tables.build_policy_icmp_block_inversion_rulescCsxd}g}||j|j�7}||j|j�7}g}|j|j|||||��|j|j|||||��|j|j|||||��|S)Nr#)rrrrrfrrr)rNr�r�rrcrr�r3r3r4�*build_policy_rich_source_destination_rules�sz4ip4tables.build_policy_rich_source_destination_rulescCs
||jkS)N)rA)rNrAr3r3r4r��szip4tables.is_ipv_supported)N)N)r�)F)F)NN)NN)NN)NN)N)N)N)7�__name__�
__module__�__qualname__rAr�Zpolicies_supportedrPrHr�rarerhrjrkrlrmrur�r�r�r�r�rDrFr�r�r�r�r�r�r�r�r�r�rrr	rrrrrrrrr!r"r#r$r&r(r+r,r-r�r3r3r3r4r?�sh

			)Pa#

!
zN

0"




&
!
1"r?c@s&eZdZdZdZddd�Zdd�ZdS)	�	ip6tablesr%Fc
Cs�g}|jddddddddd	d
g
�|dkrL|jddddddddd	dd
dg�|jdddddddd	dg	�|jdddddddd	dg	�|S)Nz-Irz-tr!z-mZrpfilterz--invertz--validmarkz-jr�r�r�z--log-prefixzrpfilter_DROP: z-pz	ipv6-icmpz$--icmpv6-type=neighbour-solicitationr�z"--icmpv6-type=router-advertisement)rf)rNr�r�r3r3r4�build_rpfilter_rules�s$



zip6tables.build_rpfilter_rulescCs�ddddddddd	g	}d
}|jdj|�g}|jddd
|g�xT|D]L}|jddd|d|ddddg
�|jjdkrF|jddd|d|ddddg
�qFW|jdddddd|g�|jdddddd|g�|S)Nz::0.0.0.0/96z::ffff:0.0.0.0/96z2002:0000::/24z2002:0a00::/24z2002:7f00::/24z2002:ac10::/28z2002:c0a8::/32z2002:a9fe::/32z2002:e000::/19ZRFC3964_IPv4r#z-tz-Nz-Iz-dz-jr�z
--reject-withzaddr-unreachr��allr�z--log-prefixz"RFC3964_IPv4_REJECT: "r�4r)r�r3)rMrgrfr@Z_log_denied)rNZ
daddr_listZ
chain_namer�Zdaddrr3r3r4�build_rfc3964_ipv4_rules�s4



z"ip6tables.build_rfc3964_ipv4_rulesN)F)r.r/r0rAr�r2r5r3r3r3r4r1�s
r1)+Zos.pathrQr�Zfirewall.core.progrZfirewall.core.loggerrZfirewall.functionsrrrrrr	r
rZfirewallrZfirewall.errorsr
rrrrZfirewall.core.richrrrrrrrr�r�rbr�r�r5r:r>�objectr?r1r3r3r3r4�<module>s@($%* xcore/__pycache__/fw_policy.cpython-36.pyc000064400000154111150351351730014333 0ustar003

��g=V�@s�ddlZddlZddlmZddlmZmZmZmZm	Z	m
Z
mZmZm
Z
mZddlmZmZmZmZmZmZmZmZmZmZmZddlmZddlmZddlm Z ddl!m"Z"dd	l#m$Z$Gd
d�de%�Z&dS)�N)�log)
�portStr�checkIPnMask�
checkIP6nMask�
checkProtocol�enable_ip_forwarding�check_single_address�portInPortRange�get_nf_conntrack_short_name�coalescePortRange�breakPortRange)�	Rich_Rule�Rich_Accept�Rich_Service�	Rich_Port�
Rich_Protocol�Rich_Masquerade�Rich_ForwardPort�Rich_SourcePort�Rich_IcmpBlock�
Rich_IcmpType�	Rich_Mark)�FirewallTransaction)�errors)�
FirewallError)�LastUpdatedOrderedDict)�SOURCE_IPSET_TYPESc@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
�ddd�Zdd�Zdd�Zdd�Z�dd d!�Z�d
d"d#�Z�dd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Z�dd0d1�Zd2d3�Z�dd4d5�Zd6d7�Zd8d9�Zd:d;�Zd<d=�Zd>d?�Z �dd@dA�Z!dBdC�Z"�ddDdE�Z#dFdG�Z$dHdI�Z%dJdK�Z&dLdM�Z'dNdO�Z(dPdQ�Z)dRdS�Z*�ddTdU�Z+dVdW�Z,�ddXdY�Z-dZd[�Z.d\d]�Z/d^d_�Z0d`da�Z1dbdc�Z2�dddde�Z3dfdg�Z4�ddhdi�Z5djdk�Z6dldm�Z7dndo�Z8dpdq�Z9drds�Z:dtdu�Z;dvdw�Z<�ddxdy�Z=dzd{�Z>�dd|d}�Z?d~d�Z@d�d��ZAd�d��ZBd�d��ZCd�d��ZD�dd�d��ZEd�d��ZF�dd�d��ZGd�d��ZHd�d��ZId�d��ZJd�d��ZK�dd�d��ZLd�d��ZM�dd�d��ZNd�d��ZOd�d��ZPd�d��ZQd�d��ZR�dd�d��ZSd�d��ZT�dd�d��ZUd�d��ZVd�d��ZW�dd�d��ZX�d d�d��ZY�d!d�d��ZZd�d��Z[�d"d�d��Z\d�d��Z]�d#d�d��Z^d�d��Z_d�d��Z`d�d��Za�d$d�dÄZbd�dńZc�d%d�dDŽZdd�dɄZed�d˄Zfd�d̈́Zgd�dτZh�d&d�dфZid�dӄZjd�dՄZk�d'd�dׄZld�dلZmd�dۄZnd�d݄Zod�d߄Zpd�d�Zqd�d�Zrd�d�Zsd�d�Ztd�d�Zu�d(d�d�Zv�d)d�d�Zwd�d�Zxd�d�Zyd�d�Zzd�d��Z{�d*d�d��Z|d�d��Z}d�d��Z~d�d��Zd�d��Z��d�d�Z��d�d�Z��d�d�Z��d�d�Z��d+�d	�d
�Z�dS(,�FirewallPolicycCs||_i|_i|_dS)N)�_fw�_chains�	_policies)�self�fw�r#�/usr/lib/python3.6/fw_policy.py�__init__szFirewallPolicy.__init__cCsd|j|j|jfS)Nz
%s(%r, %r))�	__class__rr )r!r#r#r$�__repr__szFirewallPolicy.__repr__cCs|jj�|jj�dS)N)r�clearr )r!r#r#r$�cleanups
zFirewallPolicy.cleanupcCs
t|j�S)N)rr)r!r#r#r$�new_transaction$szFirewallPolicy.new_transactioncCst|jj��S)N)�sortedr �keys)r!r#r#r$�get_policies)szFirewallPolicy.get_policiescCs8g}x*|j�D]}|j|�}|js|j|�qWt|�S)N)r-�
get_policy�derived_from_zone�appendr+)r!Zpolicies�p�p_objr#r#r$�"get_policies_not_derived_from_zone,s
z1FirewallPolicy.get_policies_not_derived_from_zonecCs~g}xt|j�D]h}|j|�}t|d�t|jjj��tddg�B@rt|d�t|jjj��tddg�B@r|j|�qW|S)N�
ingress_zones�HOST�ANY�egress_zones)r3�get_settings�setr�zoneZget_active_zonesr0)r!Zactive_policies�policy�settingsr#r#r$�)get_active_policies_not_derived_from_zone4s
((z8FirewallPolicy.get_active_policies_not_derived_from_zonecCs|jj|�}|j|S)N)r�check_policyr )r!r;r1r#r#r$r.>szFirewallPolicy.get_policycCs,dd�dD�|_||j|j<|j|j�dS)NcSsi|]}t�|�qSr#)r)�.0�xr#r#r$�
<dictcomp>Csz-FirewallPolicy.add_policy.<locals>.<dictcomp>�services�ports�
masquerade�
forward_ports�source_ports�icmp_blocks�rules�	protocols�icmp_block_inversionr4r7)rBrCrDrErFrGrHrIrJr4r7)r<r �name�copy_permanent_to_runtime)r!�objr#r#r$�
add_policyBs
zFirewallPolicy.add_policycCs0|j|}|jr|j|�|jj�|j|=dS)N)r �applied�unapply_policy_settingsr<r()r!r;rMr#r#r$�
remove_policyNs



zFirewallPolicy.remove_policycCs�|j|}|jrdSx|jD]}|j||dd�qWx|jD]}|j||dd�q<Wx|jD]}|j||�q\Wx|jD]}|j	|f|��qxWx|j
D]}|j||�q�Wxf|jD]\}y|j
|f|��Wq�tk
�r}z$|jtjgkr�tj|�n|�WYdd}~Xq�Xq�Wx|jD]}|j||��qWxj|jD]`}y|j|f|��WnDtk
�r�}z&|jtjgk�r�tj|�n|�WYdd}~XnX�q:Wx|jD]}|j||��q�W|j�r�|j|�dS)NF)�allow_apply)r rOr4�add_ingress_zoner7�add_egress_zonerG�add_icmp_blockrE�add_forward_portrB�add_servicerC�add_portr�coder�ALREADY_ENABLEDr�warningrI�add_protocolrF�add_source_portrH�add_rulerD�add_masquerade)r!r;rM�args�errorr#r#r$rLUsB
z(FirewallPolicy.copy_permanent_to_runtimeNcCsNxH|j�D]<}|j|}|jr q
||j�kr
tjd|�|j||d�q
WdS)NzApplying policy '%s')�use_transaction)r-r r/r=rZdebug1�apply_policy_settings)r!rbr;r2r#r#r$�apply_policies|s
zFirewallPolicy.apply_policiescCs|j|}||_dS)N)r rO)r!r;rOrMr#r#r$�set_policy_applied�s
z!FirewallPolicy.set_policy_appliedcCstj�||d�}|S)N)Zdate�sender�timeout)�time)r!rgrf�retr#r#r$Z__gen_settings�szFirewallPolicy.__gen_settingscCs|j|�jS)N)r.r<)r!r;r#r#r$r8�szFirewallPolicy.get_settingscCsj|jj|�}|j|}|r |js.|r2|jr2dS|r<d|_|dkrN|j�}n|}|r�x8|jsh|j|�n|j|�D]\}}|j|d|||�qrW|j	|�}	|js�|j
|||��xV|	D�]L}
�xD|	|
D�]6}|
dkr�|j||||�q�|
dkr�q�q�|
dk�r|j|||f|��q�|
dk�r0|j
||||�q�|
dk�rV|j|||d|d|�q�|
d	k�rr|j||||�q�|
d
k�r�|j|||d|d|�q�|
dk�r�|j|||�q�|
dk�r�|j||t|d
�|�q�|
dk�r�q�q�|
dk�r�q�q�tjd||
|�q�Wq�W|�sRx<|j�s"|j|�n|j|�D]\}}|j|d|||��q,Wd|_|dk�rf|j|�dS)NTrGrJrErBrCr�rIrFrDrH)�rule_strr4r7z5Policy '%s': Unknown setting '%s:%s', unable to applyF)rr>r rOr*r/�%_get_table_chains_for_policy_dispatch�#_get_table_chains_for_zone_dispatch�gen_chain_rulesr8�_ingress_egress_zones�_icmp_block�
_forward_port�_service�_port�	_protocol�_source_port�_masquerade�_FirewallPolicy__ruler
rr[�execute)r!�enabler;rb�_policyrM�transaction�table�chainr<�keyr`r#r#r$�_policy_settings�sj













zFirewallPolicy._policy_settingscCs|jd||d�dS)NT)rb)r)r!r;rbr#r#r$rc�sz$FirewallPolicy.apply_policy_settingscCs|jd||d�dS)NF)rb)r)r!r;rbr#r#r$rP�sz&FirewallPolicy.unapply_policy_settingscCsr|j|�j�}|j|�|j|�|j|�|j|�|j|�|j|�|j|�|j	|�|j
|�|j|�d�
}|jj
||�S)zH
        :return: exported config updated with runtime settings
        )
rBrCrGrDrE�
rich_rulesrIrFr4r7)r.Zexport_config_dict�
list_services�
list_ports�list_icmp_blocks�query_masquerade�list_forward_ports�
list_rules�list_protocols�list_source_ports�list_ingress_zones�list_egress_zonesrZ'combine_runtime_with_permanent_settings)r!r;Z	permanentZruntimer#r#r$�get_config_with_settings_dict�sz,FirewallPolicy.get_config_with_settings_dictcs�ddlm�d
��fdd�	}��fdd�}�j�jf�j�jf�j�jf�j�j	f�j
�jf||f�j�j
f�j�jf�j�jf�j�jfd�
}�j|�}�jj||�\}}	xt|	D]l}
t|	|
t��rxV|	|
D]8}t|t�r�||
d|f|��q�||
d||�q�Wq�||
d|�q�Wx�|D]�}
t||
t��r�xn||
D]J}t|t��rv||
d|f|�d|d	��n||
d||d|d	��qFWn||
d|d|d	��q(WdS)Nr)r
cs�j|�|d�d|d�dS)N)rkr)rgrf)r^)r;rkrgrf)r
r!r#r$�add_rule_wrapper�szFFirewallPolicy.set_config_with_settings_dict.<locals>.add_rule_wrappercs�j|�|d��dS)N)rk)�remove_rule)r;rk)r
r!r#r$�remove_rule_wrapper�szIFirewallPolicy.set_config_with_settings_dict.<locals>.remove_rule_wrapper)
rBrCrGrDrEr�rIrFr4r7rj)rgrf)rN)�firewall.core.richr
rW�remove_servicerX�remove_portrU�remove_icmp_blockr_�remove_masqueraderV�remove_forward_portr\�remove_protocolr]�remove_source_portrS�remove_ingress_zonerT�remove_egress_zoner�rZget_added_and_removed_settings�
isinstance�list�tuple)r!r;r<rfr�r�Z
setting_to_fnZold_settingsZadd_settingsZremove_settingsr~r`r#)r
r!r$�set_config_with_settings_dict�s:











  z,FirewallPolicy.set_config_with_settings_dictcCs&|sttj��|dkr"|jj|�dS)Nr5r6)r5r6)rr�INVALID_ZONEr�
check_zone)r!r:r#r#r$�check_ingress_zones
z!FirewallPolicy.check_ingress_zonecCs|j|�|S)N)r�)r!r:r#r#r$Z__ingress_zone_id"s
z FirewallPolicy.__ingress_zone_idrTcCs�|jj|�}|jj|�|jj�|j|}|j|�}	|	|jdkrXttj	d||f��d|jdks�d|jdks�|dkr�|jdr�ttj
d��|dkr�d|jdkr�ttj
d��|dkr�|j�}
n|}
|�rJ|jr�|j
d||
�|j||	||�|
j|j||	�|j�s:||j�k�rH|j||
d	�|
j|j|d�n|j
d
||
�n |j||	||�|
j|j||	�|dk�r~|
jd
�dS)Nr4z'%s' already in '%s'r6r5zI'ingress-zones' may only contain one of: many regular zones, ANY, or HOSTr7zF'HOST' can only appear in either ingress or egress zones, but not bothF)rbT)r6r5)rr>�
check_timeout�check_panicr � _FirewallPolicy__ingress_zone_idr<rrrZr�r*rOro�&_FirewallPolicy__register_ingress_zone�add_fail�(_FirewallPolicy__unregister_ingress_zoner=rcrerx)r!r;r:rgrfrbrRrz�_obj�zone_idr{r#r#r$rS&s<




zFirewallPolicy.add_ingress_zonecCs|j||�|jd|<dS)Nr4)�_FirewallPolicy__gen_settingsr<)r!r�r�rgrfr#r#r$Z__register_ingress_zoneSsz&FirewallPolicy.__register_ingress_zonecCs�|jj|�}|jj�|j|}|j|�}||jdkrLttjd||f��|dkr^|j	�}n|}|j
r�t|jd�dkr�|j||�n|j
d||�|j||�|j|j||dd�||j�kr�|j
d||�n|j|j||�|dkr�|jd�|S)Nr4z'%s' not in '%s'rjFT)rr>r�r r�r<rr�NOT_ENABLEDr*rO�lenrPror�r�r�r=�add_postrx)r!r;r:rbrzr�r�r{r#r#r$r�Vs,




z"FirewallPolicy.remove_ingress_zonecCs||jdkr|jd|=dS)Nr4)r<)r!r�r�r#r#r$Z__unregister_ingress_zoneysz(FirewallPolicy.__unregister_ingress_zonecCs|j|�|j|�dkS)Nr4)r�r8)r!r;r:r#r#r$�query_ingress_zone}sz!FirewallPolicy.query_ingress_zonecCst|j|�dj��S)Nr4)r�r8r,)r!r;r#r#r$r��sz!FirewallPolicy.list_ingress_zonescCs&|sttj��|dkr"|jj|�dS)Nr5r6)r5r6)rrr�rr�)r!r:r#r#r$�check_egress_zone�s
z FirewallPolicy.check_egress_zonecCs|j|�|S)N)r�)r!r:r#r#r$Z__egress_zone_id�s
zFirewallPolicy.__egress_zone_idcCs�|jj|�}|jj|�|jj�|j|}|j|�}	|	|jdkrXttj	d||f��d|jdks�d|jdks�|dkr�|jdr�ttj
d��|dkr�d|jdkr�ttj
d��|dkr�|j�}
n|}
|�rJ|jr�|j
d||
�|j||	||�|
j|j||	�|j�s:||j�k�rH|j||
d	�|
j|j|d�n|j
d
||
�n |j||	||�|
j|j||	�|dk�r~|
jd
�dS)Nr7z'%s' already in '%s'r6r5zH'egress-zones' may only contain one of: many regular zones, ANY, or HOSTr4zF'HOST' can only appear in either ingress or egress zones, but not bothF)rbT)r6r5)rr>r�r�r �_FirewallPolicy__egress_zone_idr<rrrZr�r*rOro�%_FirewallPolicy__register_egress_zoner��'_FirewallPolicy__unregister_egress_zoner=rcrerx)r!r;r:rgrfrbrRrzr�r�r{r#r#r$rT�s<




zFirewallPolicy.add_egress_zonecCs|j||�|jd|<dS)Nr7)r�r<)r!r�r�rgrfr#r#r$Z__register_egress_zone�sz%FirewallPolicy.__register_egress_zonecCs�|jj|�}|jj�|j|}|j|�}||jdkrLttjd||f��|dkr^|j	�}n|}|j
r�t|jd�dkr�|j||�n|j
d||�|j||�|j|j||dd�||j�kr�|j
d||�n|j|j||�|dkr�|jd�|S)Nr7z'%s' not in '%s'rjFT)rr>r�r r�r<rrr�r*rOr�rPror�r�r�r=r�rx)r!r;r:rbrzr�r�r{r#r#r$r��s,




z!FirewallPolicy.remove_egress_zonecCs||jdkr|jd|=dS)Nr7)r<)r!r�r�r#r#r$Z__unregister_egress_zone�sz'FirewallPolicy.__unregister_egress_zonecCs|j|�|j|�dkS)Nr7)r�r8)r!r;r:r#r#r$�query_egress_zone�sz FirewallPolicy.query_egress_zonecCst|j|�dj��S)Nr7)r�r8r,)r!r;r#r#r$r��sz FirewallPolicy.list_egress_zonescCs|j�dS)N)Zcheck)r!�ruler#r#r$�
check_rule�szFirewallPolicy.check_rulecCs|j|�t|�S)N)r��str)r!r�r#r#r$Z	__rule_id�s
zFirewallPolicy.__rule_idcCsx|sdS|jr,t|j�rdSt|j�rtdSnHt|d�r@|jr@dSt|d�rt|jrt|j|j�|j|j�|j|j�SdS)N�ipv4�ipv6�mac��ipset)	Zaddrrr�hasattrr�r��_check_ipset_type_for_source�_check_ipset_applied�
_ipset_family)r!�sourcer#r#r$�_rule_source_ipv�s

zFirewallPolicy._rule_source_ipvcCs|j||||�dS)N)�
_rule_prepare)r!ryr;r�r{r#r#r$Z__ruleszFirewallPolicy.__rulecCsL|jj|�}|jj|�|jj�|j|}|j|�}||jdkrh|jrP|jn|}	tt	j
d||	f��|j�s�|jr�t|jt
�r�d|jdkr�tt	jd��d|jdkr�tt	jd��x6|jdD](}
|
dkr�q�|jjj|
�r�tt	jd	��q�W|j�r�t|jt��r�d|jdk�r,|jj�r�tt	jd
��nb|jd�r�|jj�sNtt	jd��x>|jdD]0}
|
dk�rl�qZ|jjj|
��rZtt	jd���qZW|j�r�t|jt��r�x>|jdD]0}
|
dk�rq�|jjj|
��r�tt	jd
���q�W|dk�r�|j�}n|}|j�r|jd|||�|j||||�|j|j||�|dk�rH|jd�|S)NrHz'%s' already in '%s'r5r7z.'masquerade' is invalid for egress zone 'HOST'r4z/'masquerade' is invalid for ingress zone 'HOST'r6zR'masquerade' cannot be used in a policy if an ingress zone has assigned interfaceszAA 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'zC'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zonezS'forward-port' cannot be used in a policy if an egress zone has assigned interfaceszR'mark' action cannot be used in a policy if an egress zone has assigned interfacesT)r6r5)rr>r�r�r �_FirewallPolicy__rule_idr<r/rrrZ�elementr�rr�r:�list_interfacesr�
to_address�INVALID_FORWARD�actionrr*rOrw�_FirewallPolicy__register_ruler�� _FirewallPolicy__unregister_rulerx)r!r;r�rgrfrbrzr��rule_id�_namer:r{r#r#r$r^
s`










zFirewallPolicy.add_rulecCs|j||�|jd|<dS)NrH)r�r<)r!r�r�rgrfr#r#r$Z__register_ruleEszFirewallPolicy.__register_rulec	Cs�|jj|�}|jj�|j|}|j|�}||jdkr\|jrD|jn|}ttj	d||f��|dkrn|j
�}n|}|jr�|jd|||�|j
|j||�|dkr�|jd�|S)NrHz'%s' not in '%s'FT)rr>r�r r�r<r/rrr�r*rOrwr�r�rx)	r!r;r�rbrzr�r�r�r{r#r#r$r�Is"




zFirewallPolicy.remove_rulecCs||jdkr|jd|=dS)NrH)r<)r!r�r�r#r#r$Z__unregister_ruledsz FirewallPolicy.__unregister_rulecCs|j|�|j|�dkS)NrH)r�r8)r!r;r�r#r#r$�
query_rulehszFirewallPolicy.query_rulecCst|j|�dj��S)NrH)r�r8r,)r!r;r#r#r$r�kszFirewallPolicy.list_rulescCs|jj|�dS)N)r�
check_service)r!�servicer#r#r$r�pszFirewallPolicy.check_servicecCs|j|�|S)N)r�)r!r�r#r#r$Z__service_idss
zFirewallPolicy.__service_idcCs�|jj|�}|jj|�|jj�|j|}|j|�}||jdkrh|jrP|jn|}	tt	j
d||	f��|dkrz|j�}
n|}
|jr�|j
d|||
�|j||||�|
j|j||�|dkr�|
jd�|S)NrBz'%s' already in '%s'T)rr>r�r�r �_FirewallPolicy__service_idr<r/rrrZr*rOrr�!_FirewallPolicy__register_servicer��#_FirewallPolicy__unregister_servicerx)r!r;r�rgrfrbrzr��
service_idr�r{r#r#r$rWws&




zFirewallPolicy.add_servicecCs|j||�|jd|<dS)NrB)r�r<)r!r�r�rgrfr#r#r$Z__register_service�sz!FirewallPolicy.__register_servicec	Cs�|jj|�}|jj�|j|}|j|�}||jdkr\|jrD|jn|}ttj	d||f��|dkrn|j
�}n|}|jr�|jd|||�|j
|j||�|dkr�|jd�|S)NrBz'%s' not in '%s'FT)rr>r�r r�r<r/rrr�r*rOrrr�r�rx)	r!r;r�rbrzr�r�r�r{r#r#r$r��s"




zFirewallPolicy.remove_servicecCs||jdkr|jd|=dS)NrB)r<)r!r�r�r#r#r$Z__unregister_service�sz#FirewallPolicy.__unregister_servicecCs|j|�|j|�dkS)NrB)r�r8)r!r;r�r#r#r$�
query_service�szFirewallPolicy.query_servicecCs|j|�dj�S)NrB)r8r,)r!r;r#r#r$r��szFirewallPolicy.list_servicescCsTg}xJ|D]B}y|jjj|�}Wn tk
r@ttj|��YnX|j|�q
W|S)N)r�helper�
get_helperrr�INVALID_HELPERr0)r!�helpers�_helpersr��_helperr#r#r$�get_helpers_for_service_helpers�s
z.FirewallPolicy.get_helpers_for_service_helperscCs�g}x�|D]�}y|jjj|�}Wn tk
r@ttj|��YnXt|j�dkr�t|j	�}y|jjj|�}|j
|�Wq�tk
r�|r�tjd|�w
Yq�Xq
|j
|�q
W|S)NrjzHelper '%s' is not available)
rr�r�rrr�r�rCr
�moduler0rr[)r!�modulesryr�r�r��_module_short_namer�r#r#r$�get_helpers_for_service_modules�s"


z.FirewallPolicy.get_helpers_for_service_modulescCs|jj|�|jj|�dS)N)r�
check_port�check_tcpudp)r!�port�protocolr#r#r$r��szFirewallPolicy.check_portcCs|j||�t|d�|fS)N�-)r�r)r!r�r�r#r#r$Z	__port_id�szFirewallPolicy.__port_idcs�|jj|�}|jj|�|jj�|j|}tt�fdd�|jd��}	x@|	D]8}
t||
d�rN|j	rl|j	n|}t
tjd|�|f��qNWt
|dd�|	D��\}}
|dkr�|j�}n|}|j�rx$|D]}|jd|t|d	��|�q�Wx$|
D]}|jd
|t|d	��|�q�Wx:|D]2}|j|��}
|j||
||�|j|j||
��qWx*|
D]"}|j|��}
|j|j||
��qNW|dk�r�|jd�|S)Ncs|d�kS)Nrjr#)r@)r�r#r$�<lambda>�sz)FirewallPolicy.add_port.<locals>.<lambda>rCrz'%s:%s' already in '%s'cSsg|]\}}|�qSr#r#)r?rsrtr#r#r$�
<listcomp>�sz+FirewallPolicy.add_port.<locals>.<listcomp>Tr�F)rr>r�r�r r��filterr<r	r/rrrZrr*rOrsr�_FirewallPolicy__port_id�_FirewallPolicy__register_portr�� _FirewallPolicy__unregister_portr�rx)r!r;r�r�rgrfrbrzr��existing_port_ids�port_idr��added_ranges�removed_rangesr{�ranger#)r�r$rX�s:









zFirewallPolicy.add_portcCs|j||�|jd|<dS)NrC)r�r<)r!r�r�rgrfr#r#r$Z__register_portszFirewallPolicy.__register_portcs�|jj|�}|jj�|j|}tt�fdd�|jd��}xB|D]}t||d�rBPqBW|jrf|jn|}	t	t
jd|�|	f��t|dd�|D��\}
}|dkr�|j
�}n|}|j�rx$|
D]}
|jd|t|
d	��|�q�Wx$|D]}
|jd
|t|
d	��|�q�Wx:|
D]2}
|j|
��}|j||dd�|j|j||��qWx*|D]"}
|j|
��}|j|j||��qDW|dk�r~|jd�|S)Ncs|d�kS)Nrjr#)r@)r�r#r$r�sz,FirewallPolicy.remove_port.<locals>.<lambda>rCrz'%s:%s' not in '%s'cSsg|]\}}|�qSr#r#)r?rsrtr#r#r$r�#sz.FirewallPolicy.remove_port.<locals>.<listcomp>Tr�F)rr>r�r r�r�r<r	r/rrr�rr*rOrsrr�r�r�r�r�rx)r!r;r�r�rbrzr�r�r�r�r�r�r{r�r#)r�r$r�s:









zFirewallPolicy.remove_portcCs||jdkr|jd|=dS)NrC)r<)r!r�r�r#r#r$Z__unregister_port=sz FirewallPolicy.__unregister_portcCs6x0|j|�dD]\}}t||�r||krdSqWdS)NrCTF)r8r	)r!r;r�r�rsrtr#r#r$�
query_portAszFirewallPolicy.query_portcCst|j|�dj��S)NrC)r�r8r,)r!r;r#r#r$r�HszFirewallPolicy.list_portscCst|�sttj|��dS)N)rrrZINVALID_PROTOCOL)r!r�r#r#r$�check_protocolMszFirewallPolicy.check_protocolcCs|j|�|S)N)r�)r!r�r#r#r$Z
__protocol_idQs
zFirewallPolicy.__protocol_idcCs�|jj|�}|jj|�|jj�|j|}|j|�}||jdkrh|jrP|jn|}	tt	j
d||	f��|dkrz|j�}
n|}
|jr�|j
d|||
�|j||||�|
j|j||�|dkr�|
jd�|S)NrIz'%s' already in '%s'T)rr>r�r�r �_FirewallPolicy__protocol_idr<r/rrrZr*rOrt�"_FirewallPolicy__register_protocolr��$_FirewallPolicy__unregister_protocolrx)r!r;r�rgrfrbrzr��protocol_idr�r{r#r#r$r\Us&




zFirewallPolicy.add_protocolcCs|j||�|jd|<dS)NrI)r�r<)r!r�r�rgrfr#r#r$Z__register_protocolrsz"FirewallPolicy.__register_protocolc	Cs�|jj|�}|jj�|j|}|j|�}||jdkr\|jrD|jn|}ttj	d||f��|dkrn|j
�}n|}|jr�|jd|||�|j
|j||�|dkr�|jd�|S)NrIz'%s' not in '%s'FT)rr>r�r r�r<r/rrr�r*rOrtr�r�rx)	r!r;r�rbrzr�r�r�r{r#r#r$r�vs$





zFirewallPolicy.remove_protocolcCs||jdkr|jd|=dS)NrI)r<)r!r�r�r#r#r$Z__unregister_protocol�sz$FirewallPolicy.__unregister_protocolcCs|j|�|j|�dkS)NrI)r�r8)r!r;r�r#r#r$�query_protocol�szFirewallPolicy.query_protocolcCst|j|�dj��S)NrI)r�r8r,)r!r;r#r#r$r��szFirewallPolicy.list_protocolscCs|j||�t|d�|fS)Nr�)r�r)r!r�r�r#r#r$Z__source_port_id�szFirewallPolicy.__source_port_idcs�|jj|�}|jj|�|jj�|j|}tt�fdd�|jd��}	x@|	D]8}
t||
d�rN|j	rl|j	n|}t
tjd|�|f��qNWt
|dd�|	D��\}}
|dkr�|j�}n|}|j�rx$|D]}|jd|t|d	��|�q�Wx$|
D]}|jd
|t|d	��|�q�Wx:|D]2}|j|��}
|j||
||�|j|j||
��qWx*|
D]"}|j|��}
|j|j||
��qNW|dk�r�|jd�|S)Ncs|d�kS)Nrjr#)r@)r�r#r$r��sz0FirewallPolicy.add_source_port.<locals>.<lambda>rFrz'%s:%s' already in '%s'cSsg|]\}}|�qSr#r#)r?rsrtr#r#r$r��sz2FirewallPolicy.add_source_port.<locals>.<listcomp>Tr�F)rr>r�r�r r�r�r<r	r/rrrZrr*rOrur�_FirewallPolicy__source_port_id�%_FirewallPolicy__register_source_portr��'_FirewallPolicy__unregister_source_portr�rx)r!r;r�r�rgrfrbrzr�r�r�r�r�r�r{r�r#)r�r$r]�s:









zFirewallPolicy.add_source_portcCs|j||�|jd|<dS)NrF)r�r<)r!r�r�rgrfr#r#r$Z__register_source_port�sz%FirewallPolicy.__register_source_portcs�|jj|�}|jj�|j|}tt�fdd�|jd��}xB|D]}t||d�rBPqBW|jrf|jn|}	t	t
jd|�|	f��t|dd�|D��\}
}|dkr�|j
�}n|}|j�rx$|
D]}
|jd|t|
d	��|�q�Wx$|D]}
|jd
|t|
d	��|�q�Wx:|
D]2}
|j|
��}|j||dd�|j|j||��qWx*|D]"}
|j|
��}|j|j||��qDW|dk�r~|jd�|S)Ncs|d�kS)Nrjr#)r@)r�r#r$r��sz3FirewallPolicy.remove_source_port.<locals>.<lambda>rFrz'%s:%s' not in '%s'cSsg|]\}}|�qSr#r#)r?rsrtr#r#r$r��sz5FirewallPolicy.remove_source_port.<locals>.<listcomp>Tr�F)rr>r�r r�r�r<r	r/rrr�rr*rOrurr�r�r�r�r�rx)r!r;r�r�rbrzr�r�r�r�r�r�r{r�r#)r�r$r��s:









z!FirewallPolicy.remove_source_portcCs||jdkr|jd|=dS)NrF)r<)r!r�r�r#r#r$Z__unregister_source_port�sz'FirewallPolicy.__unregister_source_portcCs6x0|j|�dD]\}}t||�r||krdSqWdS)NrFTF)r8r	)r!r;r�r�rsrtr#r#r$�query_source_port�sz FirewallPolicy.query_source_portcCst|j|�dj��S)NrF)r�r8r,)r!r;r#r#r$r�sz FirewallPolicy.list_source_portscCsdS)NTr#)r!r#r#r$Z__masquerade_idszFirewallPolicy.__masquerade_idcCs8|jj|�}|jj|�|jj�|j|}|j�}||jdkrb|jrN|jn|}tt	j
d|��|js�d|jdkr�tt	jd��d|jdkr�tt	jd��x6|jdD](}	|	dkr�q�|jjj
|	�r�tt	jd	��q�W|dkr�|j�}
n|}
|j�r|jd
||
�|j||||�|
j|j||�|dk�r4|
jd
�|S)NrDz"masquerade already enabled in '%s'r5r7z.'masquerade' is invalid for egress zone 'HOST'r4z/'masquerade' is invalid for ingress zone 'HOST'r6zR'masquerade' cannot be used in a policy if an ingress zone has assigned interfacesT)rr>r�r�r �_FirewallPolicy__masquerade_idr<r/rrrZr�r:r�r*rOrv�$_FirewallPolicy__register_masquerader��&_FirewallPolicy__unregister_masqueraderx)r!r;rgrfrbrzr��
masquerade_idr�r:r{r#r#r$r_
s:





zFirewallPolicy.add_masqueradecCs|j||�|jd|<dS)NrD)r�r<)r!r�r�rgrfr#r#r$Z__register_masquerade2sz$FirewallPolicy.__register_masqueradecCs�|jj|�}|jj�|j|}|j�}||jdkrV|jrB|jn|}ttj	d|��|dkrh|j
�}n|}|jr�|jd||�|j
|j||�|dkr�|jd�|S)NrDzmasquerade not enabled in '%s'FT)rr>r�r r�r<r/rrr�r*rOrvr�r�rx)r!r;rbrzr�r�r�r{r#r#r$r�6s"




z FirewallPolicy.remove_masqueradecCs||jdkr|jd|=dS)NrD)r<)r!r�r�r#r#r$Z__unregister_masqueradePsz&FirewallPolicy.__unregister_masqueradecCs|j�|j|�dkS)NrD)r�r8)r!r;r#r#r$r�TszFirewallPolicy.query_masqueradecCs^|jj|�|jj|�|r(|jj|�|rBt||�sBttj|��|rZ|rZttjd��dS)Nz.port-forwarding is missing to-port AND to-addr)rr�r�rrrZINVALID_ADDRr�)r!�ipvr�r��toport�toaddrr#r#r$�check_forward_portYs
z!FirewallPolicy.check_forward_portcCsLtd|�r|jd||||�n|jd||||�t|d�|t|d�t|�fS)Nr�r�r�)rrrr�)r!r�r�r�r�r#r#r$Z__forward_port_idfs


z FirewallPolicy.__forward_port_idc	CsZ|jj|�}	|jj|�|jj�|j|	}
|j||||�}||
jdkrt|
jrV|
jn|	}tt	j
d|||||f��|
js�d|
jdkr�|r�tt	jd��nR|
jdr�|s�tt	jd��x6|
jdD](}
|
dkr�q�|jjj
|
�r�tt	jd��q�W|dk�r|j�}n|}|
j�r"|jd	|	|||||�|j|
|||�|j|j|
|�|dk�rV|jd	�|	S)
NrEz'%s:%s:%s:%s' already in '%s'r5r7zAA 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'zC'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zoner6zS'forward-port' cannot be used in a policy if an egress zone has assigned interfacesT)rr>r�r�r � _FirewallPolicy__forward_port_idr<r/rrrZr�r:r�r�r*rOrq�&_FirewallPolicy__register_forward_portr��(_FirewallPolicy__unregister_forward_portrx)r!r;r�r�r�r�rgrfrbrzr��
forward_idr�r:r{r#r#r$rVnsB






zFirewallPolicy.add_forward_portcCs|j||�|jd|<dS)NrE)r�r<)r!r�rrgrfr#r#r$Z__register_forward_port�sz&FirewallPolicy.__register_forward_portcCs�|jj|�}|jj�|j|}|j||||�}	|	|jdkrh|jrJ|jn|}
ttj	d|||||
f��|dkrz|j
�}n|}|jr�|jd||||||�|j
|j||	�|dkr�|jd�|S)NrEz'%s:%s:%s:%s' not in '%s'FT)rr>r�r rr<r/rrr�r*rOrqr�rrx)r!r;r�r�r�r�rbrzr�rr�r{r#r#r$r��s&



z"FirewallPolicy.remove_forward_portcCs||jdkr|jd|=dS)NrE)r<)r!r�rr#r#r$Z__unregister_forward_port�sz(FirewallPolicy.__unregister_forward_portcCs"|j||||�}||j|�dkS)NrE)rr8)r!r;r�r�r�r�rr#r#r$�query_forward_port�sz!FirewallPolicy.query_forward_portcCst|j|�dj��S)NrE)r�r8r,)r!r;r#r#r$r��sz!FirewallPolicy.list_forward_portscCs|jj|�dS)N)rZcheck_icmptype)r!�icmpr#r#r$�check_icmp_block�szFirewallPolicy.check_icmp_blockcCs|j|�|S)N)r)r!rr#r#r$Z__icmp_block_id�s
zFirewallPolicy.__icmp_block_idcCs�|jj|�}|jj|�|jj�|j|}|j|�}||jdkrh|jrP|jn|}	tt	j
d||	f��|dkrz|j�}
n|}
|jr�|j
d|||
�|j||||�|
j|j||�|dkr�|
jd�|S)NrGz'%s' already in '%s'T)rr>r�r�r �_FirewallPolicy__icmp_block_idr<r/rrrZr*rOrp�$_FirewallPolicy__register_icmp_blockr��&_FirewallPolicy__unregister_icmp_blockrx)r!r;rrgrfrbrzr��icmp_idr�r{r#r#r$rU�s&




zFirewallPolicy.add_icmp_blockcCs|j||�|jd|<dS)NrG)r�r<)r!r�rrgrfr#r#r$Z__register_icmp_block�sz$FirewallPolicy.__register_icmp_blockc	Cs�|jj|�}|jj�|j|}|j|�}||jdkr\|jrD|jn|}ttj	d||f��|dkrn|j
�}n|}|jr�|jd|||�|j
|j||�|dkr�|jd�|S)NrGz'%s' not in '%s'FT)rr>r�r rr<r/rrr�r*rOrpr�r
rx)	r!r;rrbrzr�rr�r{r#r#r$r��s"




z FirewallPolicy.remove_icmp_blockcCs||jdkr|jd|=dS)NrG)r<)r!r�rr#r#r$Z__unregister_icmp_blocksz&FirewallPolicy.__unregister_icmp_blockcCs|j|�|j|�dkS)NrG)rr8)r!r;rr#r#r$�query_icmp_blockszFirewallPolicy.query_icmp_blockcCs|j|�dj�S)NrG)r8r,)r!r;r#r#r$r�szFirewallPolicy.list_icmp_blockscCsdS)NTr#)r!r#r#r$Z__icmp_block_inversion_idsz(FirewallPolicy.__icmp_block_inversion_idc
Cs|jj|�}|jj�|j|}|j�}||jdkrV|jrB|jn|}ttj	d|��|dkrh|j
�}n|}|jr�x&|j|�dD]}	|j
d||	|�q�W|jd||�|j|||�|j|j|||�|j�rx&|j|�dD]}	|j
d||	|�q�W|jd||�|dk�r|jd�|S)NrJz,icmp-block-inversion already enabled in '%s'rGFT)rr>r�r �(_FirewallPolicy__icmp_block_inversion_idr<r/rrrZr*rOr8rp�_icmp_block_inversion�._FirewallPolicy__register_icmp_block_inversionr��*_FirewallPolicy__undo_icmp_block_inversionrx)
r!r;rfrbrzr��icmp_block_inversion_idr�r{r`r#r#r$�add_icmp_block_inversions6





z'FirewallPolicy.add_icmp_block_inversioncCs|jd|�|jd|<dS)NrrJ)r�r<)r!r�rrfr#r#r$Z__register_icmp_block_inversionEsz.FirewallPolicy.__register_icmp_block_inversioncCs�|j�}|jr6x&|j|�dD]}|jd|||�qW||jdkrP|jd|=|jr~x&|j|�dD]}|jd|||�qfW|jd�dS)NrGFrJT)r*rOr8rpr<rx)r!rzr�rr{r`r#r#r$Z__undo_icmp_block_inversionJsz*FirewallPolicy.__undo_icmp_block_inversionc	Cs|jj|�}|jj�|j|}|j�}||jdkrV|jrB|jn|}ttj	d|��|dkrh|j
�}n|}|jr�x&|j|�dD]}|j
d|||�q�W|jd||�|j||�|j|j||d�|j�rx&|j|�dD]}|j
d|||�q�W|jd||�|dk�r|jd�|S)NrJz(icmp-block-inversion not enabled in '%s'rGFT)rr>r�r r
r<r/rrr�r*rOr8rpr�0_FirewallPolicy__unregister_icmp_block_inversionr�rrx)	r!r;rbrzr�rr�r{r`r#r#r$�remove_icmp_block_inversion\s6






z*FirewallPolicy.remove_icmp_block_inversioncCs||jdkr|jd|=dS)NrJ)r<)r!r�rr#r#r$Z!__unregister_icmp_block_inversion�sz0FirewallPolicy.__unregister_icmp_block_inversioncCs|j�|j|�dkS)NrJ)r
r8)r!r;r#r#r$�query_icmp_block_inversion�sz)FirewallPolicy.query_icmp_block_inversionc
Cs�|jjj|�}|jr*|jjj|jd}n|}|rT||jkrt||f|j|krtdSn ||jksp||f|j|krtdSx@|jj�D]2}|jr�||j	�kr�|j
||||�}	|j||	�q�W|j||||fg�|j
|j||||fg�dS)Nr)rr;r.r/r:Z_zone_policiesr�enabled_backends�policies_supportedZget_available_tablesZbuild_policy_chain_rules�	add_rules�_register_chainsr�)
r!r;�creater|r}r{rMZtracking_policy�backendrHr#r#r$rn�s$

zFirewallPolicy.gen_chain_rulescCsbx\|D]T\}}|r,|jj|g�j||f�q|j|j||f�t|j|�dkr|j|=qWdS)Nr)r�
setdefaultr0�remover�)r!r;rZtablesr|r}r#r#r$r�szFirewallPolicy._register_chainscCs$|jjj|�dkrdS|jjj|�S)Nzhash:mac)rr��get_typeZ
get_family)r!rKr#r#r$r��szFirewallPolicy._ipset_familycCs|jjj|�S)N)rr�r)r!rKr#r#r$Z__ipset_type�szFirewallPolicy.__ipset_typecCsdj|g|jjj|��S)N�,)�joinrr�Z
get_dimension)r!rK�flagr#r#r$�_ipset_match_flags�sz!FirewallPolicy._ipset_match_flagscCs|jjj|�S)N)rr�Z
check_applied)r!rKr#r#r$r��sz#FirewallPolicy._check_ipset_appliedcCs*|j|�}|tkr&ttjd||f��dS)Nz.ipset '%s' with type '%s' not usable as source)�_FirewallPolicy__ipset_typerrrZ
INVALID_IPSET)r!rKZ_typer#r#r$r��s
z+FirewallPolicy._check_ipset_type_for_sourcecs�t|j�tkr��jjj|jj�}|dkr2|jjg}xR|jD]H}||krHq:�j|�|j	|�t
j|�}||j_�j|||||d�q:Wg}	|j
r�|j
g}	nH|jr�t|jt�s�t|jt�r�jjj|jj���jr�fdd�dD�}	�j|j�}
|
�r&|j
�r |j
|
k�r&ttjd|
|j
f��n|
g}	|	�s4ddg}	�fdd�|	D�}	|	|_�x2t�fdd�|	D��D�]}t|j�tk�r��jjj|jj�}g}t|j�d	k�r�|j�r�ttjd
��xB|	D].}
|
|jk�r�|j|
��r�|j	|j|
��q�Wn
|j	d��x~|D�]�}t|j�tk�r�j|j |�}|�j!|j"�7}t#t|�dd�d
�}g}x�|D]�}|j$}t%|�}|j&dd�}|j	|�|j
dk�r�|j|j
��r��qTt|j'�dk�r�|j	|�n:x8|j'D].\}}|j(||||||j|�}|j)||��q�W�qTW|j*|�x4|j'D]*\}}|j+||||||�}|j)||��q
Wx.|j,D]$}|j-|||||�}|j)||��q@Wx4|j.D]*\}}|j/||||||�}|j)||��qpW�qW�qft|j�t0k�r�|jj1}|jj2}�j3||�|j+||||d|�}|j)||��qft|j�t4k�r<|jj5}�j6|�|j-|||d|�}|j)||��qft|j�t7k�r�|�rzx&|	D]}
|j|
��rX|j8t9|
��qXW|j:|||�}|j)||��qft|j�t;k�r4|jj1}|jj2}|jj<}|jj=}xD|	D]<}
|j|
��r�j>|
||||�|�r�|�r�|j8t9|
��q�W|j?|||||||�}|j)||��qft|j�t@k�r�|jj1}|jj2}�j3||�|j/||||d|�}|j)||�n�t|j�tk�s�t|j�tk�r>�jjj|jj��|j
�r�j�r�|j
�jk�r�ttjAd|j
|jjf��t|j�tk�r |j�r t|j�tk�r ttjd��|jB||�|�}|j)||�n>|jdk�rf|jC|||�}|j)||�nttjdt|j����qfWdS)N)�included_servicescsg|]}|�jkr|�qSr#)�destination)r?r�)�ictr#r$r��sz0FirewallPolicy._rule_prepare.<locals>.<listcomp>r�r�z;Source address family '%s' conflicts with rule family '%s'.csg|]}�jj|�r|�qSr#)r�is_ipv_enabled)r?r�)r!r#r$r��scsg|]}�jj|��qSr#)r�get_backend_by_ipv)r?r@)r!r#r$r��srz"Destination conflict with service.cSs|jS)N)rK)r@r#r#r$r�sz.FirewallPolicy._rule_prepare.<locals>.<lambda>)r~�	conntrack�natr�rjz3rich rule family '%s' conflicts with icmp type '%s'z'IcmpBlock not usable with accept actionzUnknown element %s)r�r�)D�typer�rrr��get_servicerK�includesr�r0�copy�deepcopyr��familyr�rr�config�get_icmptyper%r�r�rrZINVALID_RULE�ipvsr9r��is_ipv_supportedr�rr�r�r�r�r+r�r
�replacerC�build_policy_helper_ports_rulesrZadd_modules�build_policy_ports_rulesrI�build_policy_protocol_rulesrF�build_policy_source_ports_rulesrr�r�r�r�valuer�rr�r�build_policy_masquerade_rulesrZto_portr�r�build_policy_forward_port_rulesrZINVALID_ICMPTYPE�build_policy_icmp_block_rulesZ*build_policy_rich_source_destination_rules)r!ryr;r�r{r$�svc�includeZ_ruler3Z
source_ipvrZdestinationsr�r%r�r�r�r�r��
nat_moduler��protorHr�r�r�r#)r&r!r$r��s




 









zFirewallPolicy._rule_preparecCsb|jjj|�}|j|j|�}||j|j�7}tt|�dd�d�}|dkrN|g}x@|j	D]6}||krdqV|j
|�|j|�|j|||||d�qVWg}	xndD]f}
|jj
|
�s�q�|jj|
�}t|j�dkr�|
|jkr�|	j||j|
f�q�|df|	kr�|	j|df�q�W�xV|	D�]L\}}x�|D]�}
|
j}t|�}|
jjdd	�}|j|�|
jd
k�rf|j|
j��rf�qt|
j�dk�r�|j|�n:x8|
jD].\}}|j||||||
j|�}|j||��q�W�qWx2|jD](\}}|j|||||�}|j||��q�Wx,|jD]"}|j||||�}|j||��q�Wx2|jD](\}}|j|||||�}|j||��q,W�qWdS)
NcSs|jS)N)rK)r@r#r#r$r��sz)FirewallPolicy._service.<locals>.<lambda>)r~)r$r�r�rr)r*r�rj)r�r�) rr�r,r�r�r�r�r+r9r-r�r0rrr'r(r�r%r�r
r5Z
add_moduler0r4rCr6rKrr7rIr8rFr9)r!ryr;r�r{r$r>r�r?Zbackends_ipvr�rr%r�r�r�r@r�rArHr�r#r#r$rr�sb






zFirewallPolicy._servicecCs<x6|jj�D](}|jsq|j||||�}|j||�qWdS)N)rrrr7r)r!ryr;r�r�r{rrHr#r#r$rs�s
zFirewallPolicy._portcCs:x4|jj�D]&}|jsq|j|||�}|j||�qWdS)N)rrrr8r)r!ryr;r�r{rrHr#r#r$rt�s
zFirewallPolicy._protocolcCs<x6|jj�D](}|jsq|j||||�}|j||�qWdS)N)rrrr9r)r!ryr;r�r�r{rrHr#r#r$ru�s
zFirewallPolicy._source_portcCs8d}|jt|�|jj|�}|j||�}|j||�dS)Nr�)r�rrr(r;r)r!ryr;r{r�rrHr#r#r$rv�s
zFirewallPolicy._masqueradecCsXtd|�rd}nd}|r(|r(|jt|�|jj|�}	|	j||||||�}
|j|	|
�dS)Nr�r�)rr�rrr(r<r)r!ryr;r{r�r�r�r�r�rrHr#r#r$rq�s

zFirewallPolicy._forward_portc
Cs�|jjj|�}xl|jj�D]^}|js&qd}|jrXx&dD]}||jkr6|j|�s6d}Pq6W|r^q|j|||�}	|j||	�qWdS)NFr�r�T)r�r�)	rr1r2rrr%r4r=r)
r!ryr;rr{r&rZskip_backendr�rHr#r#r$rp�s


zFirewallPolicy._icmp_blockcCsh|j|j}|dkrdS|j|�r0|dkr0dSx2|jj�D]$}|jsHq<|j||�}|j||�q<WdS)N�DROP�
%%REJECT%%�REJECTZACCEPT)rBrCrD)r �targetrrrrZ'build_policy_icmp_block_inversion_rulesr)r!ryr;r{rErrHr#r#r$rsz$FirewallPolicy._icmp_block_inversionc	Cs�x|D]}|j|�qWx|D]}|j|�qWd|ks@d|krXt|�dkrXttjd��d|kshd|kr�t|�dkr�ttjd��|s�|r�|r�|r�d|kr�d|kr�ttjd|��|s�|r�|r�|r�d|kr�d|kr�ttjd|��dS)Nr6r5rjzI'ingress-zones' may only contain one of: many regular zones, ANY, or HOSTzH'egress-zones' may only contain one of: many regular zones, ANY, or HOSTzpolicy "%s" has no ingresszpolicy "%s" has no egress)r�r�r�rrr�)	r!r;r4r7�ingress_interfaces�egress_interfaces�ingress_sources�egress_sourcesr:r#r#r$�check_ingress_egress"s$

z#FirewallPolicy.check_ingress_egressc

Cs�|dkr&|dkr�|r�ttjd|��n�|dkrtd|krFttjd|��d|kr^ttjd|��|r�ttjd|��n||d	kr�d|kr�ttjd|��d|kr�ttjd|��nB|d
kr�d|kr�ttjd|��n |dkr�d|kr�ttjd
|��dS)N�
PREROUTING�rawzFpolicy "%s" egress-zones may not include a zone with added interfaces.�POSTROUTINGr5z/policy "%s" ingress-zones may not include HOST.z.policy "%s" egress-zones may not include HOST.zGpolicy "%s" ingress-zones may not include a zone with added interfaces.�FORWARD�INPUTz0policy "%s" egress-zones must include only HOST.�OUTPUTz1policy "%s" ingress-zones must include only HOST.)rrr�)
r!r;r|r}r4r7rFrGrHrIr#r#r$�check_ingress_egress_chain<s,z)FirewallPolicy.check_ingress_egress_chaincCs$|j�}|j|||�|jd�dS)NT)r*rorx)r!ryr;r{r#r#r$�!_ingress_egress_zones_transactionYsz0FirewallPolicy._ingress_egress_zones_transactioncCsL|j|}|jd}|jd}t�}t�}t�}	t�}
xB|D]:}|dkrJq<|t|jjj|��O}|	t|jjj|��O}	q<WxB|D]:}|dkr�q�|t|jjj|��O}|
t|jjj|��O}
q�W|j||||||	|
�xr|jj�D]d}|j	s�q�xV|j
|�D]H\}
}|j||
||||||	|
�	|j|||
||||	|
�}|j
||��q�Wq�WdS)Nr4r7r6r5)r6r5)r6r5)r r<r9rr:r�Zlist_sourcesrJrrrlrQZ!build_policy_ingress_egress_rulesr)r!ryr;r{rMr4r7rFrGrHrIr:rr|r}rHr#r#r$ro^s@






z$FirewallPolicy._ingress_egress_zonescCs6|j|}d|jdkrFd|jdkrFdddg}|jjsB|jd�|Sd|jdkrpdg}|jjsl|jd�|Sd|jdkr�dgSd|jdko�d|jdk�r�ddddg}|jj�s�|jd�|Sd|jdk�r.dddg}|jj�s�|jd�x4|jdD]}|jjj|�d�rP�qW|jd �|Sd|jdk�r�d!d"g}|jj�sZ|jd#�x>|jdD]}|jjj|�d�rfP�qfW|jd$�|jd%�|Sd&g}|jj�s�|jd'�x4|jdD]}|jjj|�d�r�P�q�W|jd(�x>|jdD]}|jjj|�d�r�P�q�W|jd)�|jd*�|SdS)+z:Create a list of (table, chain) needed for policy dispatchr6r4r5r7r�rOr*rK�manglerLrPrNrMZ
interfacesN)r�rO)r*rK)rSrK)rLrK)r�rO)rLrK)r�rP)r�rN)r*rK)r*rM)rSrK)rLrK)r�rN)r*rK)rSrK)rLrK)r*rM)r�rN)r*rM)rLrK)r*rK)rSrK)r�rN)rLrK)r*rM)r*rK)rSrK)r r<r�nftables_enabledr0r:r8)r!r;rM�tcr:r#r#r$rl�sj
















z4FirewallPolicy._get_table_chains_for_policy_dispatchcCsr|j|}d|jdkr4dg}|jjs0|jd�|Sd|jdkrLdddgSd|jdkrbddgStd|�SdS)z8Create a list of (table, chain) needed for zone dispatchr5r7r�rOrLrKr6�
FORWARD_INr*rSr4�FORWARD_OUTrMzInvalid policy: %sN)r�rO)rLrK)r�rV)r*rK)rSrK)r�rW)r*rM)r r<rrTr0r)r!r;rMrUr#r#r$rm�s

z2FirewallPolicy._get_table_chains_for_zone_dispatchFcCs�|jjj|�}|jr|j}n||}d|jdkrl|dkrBd|S|dkrRd|S|jsh|dkrhd|S�nJd|jd	kr�|js�|dkr�d
|S�n"d|jdk�r�|dkr�|jr�d|Sd
|Sn0|dkr�|r�d|Sd|Sn|dk�r�d|Sn�d|jd	k�rh|dk�r*|j�r d|Sd
|Sn<|dk�rL|�rBd|Sd|Sn|dk�r�|j�s�d|SnN|j�s�|dk�r�d
|S|dk�r�|�r�d|Sd|Sn|dk�r�d|Std|||f�S)Nr5r7r�ZIN_rLZPRE_rSr*r4ZOUT_r6ZFWDI_ZFWD_ZPOST_ZFWDO_z.Can't convert policy to chain name: %s, %s, %s)rSr*)rSrL)rSrL)rSrL)rr;r.r/r<r)r!r;r|Z
policy_prefixZisSNATrM�suffixr#r#r$�policy_base_chain_name�sb













z%FirewallPolicy.policy_base_chain_name)N)N)N)N)rNNT)N)rNNT)N)rNN)N)rNN)N)rNN)N)rNN)N)rNN)N)rNN)N)NN)NN)NNrNN)NNN)NN)rNN)N)NN)N)N)N)NN)F)��__name__�
__module__�__qualname__r%r'r)r*r-r3r=r.rNrQrLrdrer�r8rrcrPr�r�r�r�rSr�r�r�r�r�r�r�rTr�r�r�r�r�r�r�r�rwr^r�r�r�r�r�r�r�rWr�r�r�r�r�r�r�r�r�rXr�r�r�r�r�r�r�r\r�r�r�r�r�r�r]r�r�r�r�r�r�r_r�r�r�r�rrrVrr�rrr�rrrUr	r�r
rr�r
rrrrrrrnrr�r#r"r�r�r�rrrsrtrurvrqrprrJrQrRrorlrmrYr#r#r#r$rs$
'	?.,#,#:
'('('
+))@@		(Pr)'rhr.Zfirewall.core.loggerrZfirewall.functionsrrrrrrr	r
rrr�r
rrrrrrrrrrZfirewall.core.fw_transactionrZfirewallrZfirewall.errorsrZfirewall.fw_typesrZfirewall.core.baser�objectrr#r#r#r$�<module>s04core/__pycache__/icmp.cpython-36.opt-1.pyc000064400000004265150351351730014233 0ustar003

��g�#@s�ddddgZddddddd	d
ddd
dddddddddddddddddddd d!d"d#d$�"Zd%d&d'd(d)dddd*d+d,d,d-d-d.d/d0d0d1d1d2d3�Zd4d5�Zd6d�Zd7d8�Zd9d�Zd:S);�
ICMP_TYPES�ICMPV6_TYPES�check_icmp_type�check_icmpv6_typez0/0z3/0z3/1z3/2z3/3z3/4z3/5z3/6z3/7z3/9z3/10z3/11z3/12z3/13z3/14z3/15z4/0z5/0z5/1z5/2z5/3z8/0z9/0z10/0z11/0z11/1z12/0z12/1z13/0z14/0z17/0z18/0)"z
echo-reply�pongznetwork-unreachablezhost-unreachablezprotocol-unreachablezport-unreachablezfragmentation-neededzsource-route-failedznetwork-unknownzhost-unknownznetwork-prohibitedzhost-prohibitedzTOS-network-unreachablezTOS-host-unreachablezcommunication-prohibitedzhost-precedence-violationzprecedence-cutoffz
source-quenchznetwork-redirectz
host-redirectzTOS-network-redirectzTOS-host-redirectzecho-request�pingzrouter-advertisementzrouter-solicitationzttl-zero-during-transitzttl-zero-during-reassemblyz
ip-header-badzrequired-option-missingztimestamp-requestztimestamp-replyzaddress-mask-requestzaddress-mask-replyz1/0z1/1z1/3z1/4z2/0z4/1z4/2z128/0z129/0z133/0z134/0z135/0z136/0z137/0)zno-routezcommunication-prohibitedzaddress-unreachablezport-unreachablezpacket-too-bigzttl-zero-during-transitzttl-zero-during-reassemblyz
bad-headerzunknown-header-typezunknown-optionzecho-requestrz
echo-replyrzrouter-solicitationzrouter-advertisementzneighbour-solicitationzneigbour-solicitationzneighbour-advertisementzneigbour-advertisementZredirectcCs|tkrdSdS)NTF)r)�_name�r�/usr/lib/python3.6/icmp.py�check_icmp_nameVsr
cCs|tj�krdSdS)NTF)r�values)�_typerrr	r[scCs|tkrdSdS)NTF)r)rrrr	�check_icmpv6_name`sr
cCs|tj�krdSdS)NTF)rr)rrrr	resN)�__all__rrr
rr
rrrrr	�<module>sxcore/__pycache__/helper.cpython-36.pyc000064400000000256150351351730013617 0ustar003

��g$�@sdZdZdS)zThe helper maxnamelen� N)�__doc__ZHELPER_MAXNAMELEN�rr�/usr/lib/python3.6/helper.py�<module>score/__pycache__/fw_service.cpython-36.pyc000064400000003201150351351730014465 0ustar003

��gg�@s2dgZddlmZddlmZGdd�de�ZdS)�FirewallService�)�errors)�
FirewallErrorc@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dS)rcCs||_i|_dS)N)Z_fw�	_services)�self�fw�r� /usr/lib/python3.6/fw_service.py�__init__szFirewallService.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r)rrrr	�__repr__ szFirewallService.__repr__cCs|jj�dS)N)r�clear)rrrr	�cleanup#szFirewallService.cleanupcCst|jj��S)N)�sortedr�keys)rrrr	�get_services(szFirewallService.get_servicescCs||jkrttj|��dS)N)rrrZINVALID_SERVICE)r�servicerrr	�
check_service+s
zFirewallService.check_servicecCs|j|�|j|S)N)rr)rrrrr	�get_service/s
zFirewallService.get_servicecCs||j|j<dS)N)r�name)r�objrrr	�add_service3szFirewallService.add_servicecCs|j|�|j|=dS)N)rr)rrrrr	�remove_service6s
zFirewallService.remove_serviceN)�__name__�
__module__�__qualname__r
rrrrrrrrrrr	rsN)�__all__ZfirewallrZfirewall.errorsr�objectrrrrr	�<module>score/__pycache__/ipset.cpython-36.pyc000064400000021161150351351730013462 0ustar003

��gq2�@s�dZdddgZddlZddlZddlmZddlmZddl	m
Z
dd	lmZdd
l
mZmZddlmZdZd
ddddddddddgZddddd�Zdddd�ZGd d�de�Zd!d�Zd"d�Zd#d$�Zd%d&�Zd'd(�ZdS))zThe ipset command wrapper�ipset�check_ipset_name�remove_default_create_options�N)�errors)�
FirewallError)�runProg)�log)�tempFile�readfile)�COMMANDS� zhash:ipzhash:ip,portzhash:ip,port,ipzhash:ip,port,netzhash:ip,markzhash:netzhash:net,netz
hash:net,portzhash:net,port,netzhash:net,ifacezhash:macz
inet|inet6�valuez
value in secs)�family�hashsize�maxelem�timeoutZinetZ1024Z65536)rrrc@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zd'd
d�Z	dd�Z
dd�Zdd�Zd(dd�Z
d)dd�Zdd�Zd*dd�Zd+dd�Zdd �Zd!d"�Zd#d$�Zd%d&�ZdS),rzipset command wrapper classcCstd|_d|_dS)Nr)r�_command�name)�self�r�/usr/lib/python3.6/ipset.py�__init__Ks
zipset.__init__cCs^dd�|D�}tjd|j|jdj|��t|j|�\}}|dkrZtd|jdj|�|f��|S)zCall ipset with argscSsg|]}d|�qS)z%sr)�.0�itemrrr�
<listcomp>Rszipset.__run.<locals>.<listcomp>z	%s: %s %s� rz'%s %s' failed: %s)r�debug2�	__class__r�joinr�
ValueError)r�argsZ_args�status�retrrrZ__runOszipset.__runcCs t|�tkrttjd|��dS)zCheck ipset namezipset name '%s' is not validN)�len�IPSET_MAXNAMELENrrZINVALID_NAME)rrrrr�
check_nameZszipset.check_namecCs�g}d}y|jdg�}Wn0tk
rH}ztjd|�WYdd}~XnX|j�}d}xT|D]L}|r�|j�jdd�}|d|kr�|dtkr�|j|d�|j	d�r\d	}q\W|S)
z?Return types that are supported by the ipset command and kernel�z--helpzipset error: %sNF�rzSupported set types:T)
�_ipset__runrrZdebug1�
splitlines�strip�split�IPSET_TYPES�append�
startswith)rr"�outputZex�linesZin_types�line�splitsrrr�set_supported_types`s  

zipset.set_supported_typescCs(t|�tks|tkr$ttjd|��dS)zCheck ipset typez!ipset type name '%s' is not validN)r#r$r,rrZINVALID_TYPE)r�	type_namerrr�
check_typeuszipset.check_typeNcCsd|j|�|j|�d||g}t|t�rZx0|j�D]$\}}|j|�|dkr2|j|�q2W|j|�S)z+Create an ipset with name, type and options�creater&)r%r5�
isinstance�dict�itemsr-r()r�set_namer4�optionsr �key�valrrr�
set_create{s




zipset.set_createcCs|j|�|jd|g�S)NZdestroy)r%r()rr:rrr�set_destroy�s
zipset.set_destroycCsd||g}|j|�S)N�add)r()rr:�entryr rrr�set_add�s
z
ipset.set_addcCsd||g}|j|�S)N�del)r()rr:rAr rrr�
set_delete�s
zipset.set_deletecCs,d||g}|r"|jddj|��|j|�S)N�testz%sr)r-rr()rr:rAr;r rrrrE�s
z
ipset.testcCs2dg}|r|j|�|r"|j|�|j|�jd�S)N�list�
)r-�extendr(r+)rr:r;r rrr�set_list�s

zipset.set_listcCs<|jdgd�}i}d}}i}�x|D�]}t|�dkr:q&dd�|jdd�D�}t|�dkr`q&q&|d	d
krv|d}q&|d	dkr�|d}q&|d	dkr&|dj�}d	}	x^|	t|�k�r||	}
|
dk�r�t|�|	kr�|	d7}	||	||
<ntjd|�iS|	d7}	q�W|�r$|�r$|t|�f||<d}}|j�q&W|S)z" Get active ipsets (only headers) z-terse)r;N�cSsg|]}|j��qSr)r*)r�xrrrr�sz.ipset.set_get_active_terse.<locals>.<listcomp>�:r'r�NameZTypeZHeaderrrrr�netmaskz&Malformed ipset list -terse output: %s)rrrrrN)rIr#r+r�errorr�clear)rr0r"�_nameZ_type�_optionsr1Zpairr2�i�optrrr�set_get_active_terse�sD

zipset.set_get_active_tersecCsdg}|r|j|�|j|�S)N�save)r-r()rr:r rrrrV�s
z
ipset.savecCs�|j|�|j|�t�}d|kr*d|}d||dg}|rlx0|j�D]$\}}	|j|�|	dkrD|j|	�qDW|jddj|��|jd|�xN|D]F}
d|
kr�d|
}
|r�|jd||
dj|�f�q�|jd	||
f�q�W|j�tj	|j
�}tjd
|j
|jd|j
|jf�dg}t|j||j
d
�\}}
tj�dk�r�yt|j
�Wntk
�r`YnVXd}xNt|j
�D]@}tjd||fddd�|jd��s�tjddd�|d7}�qrWtj|j
�|dk�r�td|jdj|�|
f��|
S)Nrz'%s'r6z-existr&z%s
z	flush %s
z
add %s %s %s
z
add %s %s
z%s: %s restore %sz%s: %dZrestore)�stdinr'rJz%8d: %sr)�nofmt�nlrG)rXz'%s %s' failed: %s)r%r5r	r9r-�writer�close�os�statrrrrr�st_sizerZgetDebugLogLevelr
�	ExceptionZdebug3�endswith�unlinkr)rr:r4�entriesZcreate_optionsZ
entry_optionsZ	temp_filer r<r=rAr]r!r"rSr1rrr�set_restore�sV




zipset.set_restorecCsdg}|r|j|�|j|�S)N�flush)r-r()rr:r rrr�	set_flushs
zipset.set_flushcCs|jd||g�S)N�rename)r()rZold_set_nameZnew_set_namerrrrf
szipset.renamecCs|jd||g�S)N�swap)r()rZ
set_name_1Z
set_name_2rrrrgsz
ipset.swapcCs|jdg�S)N�version)r()rrrrrhsz
ipset.version)N)N)NN)N)NN)�__name__�
__module__�__qualname__�__doc__rr(r%r3r5r>r?rBrDrErIrUrVrcrerfrgrhrrrrrHs&



'

7cCst|�tkrdSdS)z"Return true if ipset name is validFT)r#r$)rrrrrscCs8|j�}x*tD]"}||krt|||kr||=qW|S)z( Return only non default create options )�copy�IPSET_DEFAULT_CREATE_OPTIONS)r;rRrTrrrrs

c
Cshg}xX|jd�D]J}y&|jd�|jttj|dd���Wqtk
rX|j|�YqXqWdj|�S)z! Normalize IP addresses in entry �,�/F)�strict)r+�indexr-�str�	ipaddress�
ip_networkrr)rAZ_entryZ_partrrr�normalize_ipset_entry&s
rvcCsxt|jd��dkrdSytj|dd�}Wntk
r<dSXx4|D],}|jtj|dd��rDttjdj	||���qDWdS)z: Check if entry overlaps any entry in the list of entries rorJNF)rqz,Entry '{}' overlaps with existing entry '{}')
r#r+rtrur�overlapsrr�
INVALID_ENTRY�format)rArbZ
entry_networkZitrrrr�check_entry_overlaps_existing2s
rzcCs~ydd�|D�}Wntk
r&dSXt|�dkr8dS|j�|jd�}x.|D]&}|j|�rrttjdj||���|}qPWdS)z> Check if any entry overlaps any entry in the list of entries cSsg|]}tj|dd��qS)F)rq)rtru)rrKrrrrEsz1check_for_overlapping_entries.<locals>.<listcomp>NrzEntry '{}' overlaps entry '{}')	rr#�sort�poprwrrrxry)rbZprev_networkZcurrent_networkrrr�check_for_overlapping_entriesBs2


r})rl�__all__Zos.pathr\rtZfirewallrZfirewall.errorsrZfirewall.core.progrZfirewall.core.loggerrZfirewall.functionsr	r
Zfirewall.configrr$r,ZIPSET_CREATE_OPTIONSrn�objectrrrrvrzr}rrrr�<module>sF
P	core/__pycache__/nftables.cpython-36.pyc000064400000130376150351351730014145 0ustar003

��g��%@slddlmZddlZddlZddlZddlmZddlmZm	Z	m
Z
mZmZddl
mZmZmZmZmZmZmZddlmZmZmZmZmZmZmZddlmZdZed	d
Z dZ!dZ"id
ddCe"fiddDe"fdde"fd�dde"fdde"fdde"fdde"fd�d�Z#dEdd�Z$e$ddd�e$dd�e$dd�e$dd�e$ddd�e$ddd �e$ddd�e$dd!d"�e$ddd#�e$ddd"�e$dd$d"�e$ddd%�e$dd!d�e$ddd&�e$ddd�e$dd$�e$ddd'�e$ddd(�e$ddd)�e$dd!�e$dd$d"�e$dd*�e$dd+�e$dd,�e$ddd-�e$dd.�e$dd/�e$dd0�e$dd!d'�e$ddd1�e$dd!d)�e$ddd2�e$dd.d"�e$dd.d�d3�"e$d4dd'�e$d4d$d�e$d4dd)�e$d4dd"�e$d4d�e$d4d�e$d4d�e$d4dd-�e$d4d5�e$d4d6�e$d4d7�e$d4d8�e$d4d9�e$d4d:�e$d4dd�e$d4d;�e$d4d$�e$d4dd�e$d4d<�e$d4dd&�e$d4d=�e$d4d>�e$d4d.�e$d4d.d"�e$d4d.d�e$d4d$d"�e$d4d$d)�d?�d@�Z%GdAdB�dBe&�Z'dS)F�)�absolute_importN)�log)�	check_mac�getPortRange�normalizeIP6�check_single_address�
check_address)�
FirewallError�
UNKNOWN_ERROR�INVALID_RULE�INVALID_ICMPTYPE�INVALID_TYPE�
INVALID_ENTRY�INVALID_PORT)�Rich_Accept�Rich_Reject�	Rich_Drop�	Rich_Mark�Rich_Masquerade�Rich_ForwardPort�Rich_IcmpBlock)�NftablesZ	firewalld�_Zpolicy_dropZpolicy_�
�
PREROUTING�
prerouting��dZpostrouting)r�POSTROUTING�input�forward�output)r�INPUT�FORWARD�OUTPUT)�raw�mangle�nat�filtercCsHdd|dd�id|d�ig}|dk	rD|jdd|dd�id|d�i�|S)N�match�payload�type)�protocol�fieldz==)�left�op�right�code)�append)r,r+r1�	fragments�r4�/usr/lib/python3.6/nftables.py�_icmp_types_fragmentsSsr6�icmpzdestination-unreachable�
z
echo-replyzecho-request���redirect��zparameter-problem�����zrouter-advertisementzrouter-solicitationz
source-quench�z
time-exceededztimestamp-replyztimestamp-request��)"zcommunication-prohibitedzdestination-unreachablez
echo-replyzecho-requestzfragmentation-neededzhost-precedence-violationzhost-prohibitedz
host-redirectzhost-unknownzhost-unreachablez
ip-header-badznetwork-prohibitedznetwork-redirectznetwork-unknownznetwork-unreachablezparameter-problemzport-unreachablezprecedence-cutoffzprotocol-unreachabler;zrequired-option-missingzrouter-advertisementzrouter-solicitationz
source-quenchzsource-route-failedz
time-exceededztimestamp-replyztimestamp-requestztos-host-redirectztos-host-unreachableztos-network-redirectztos-network-unreachablezttl-zero-during-reassemblyzttl-zero-during-transit�icmpv6zmld-listener-donezmld-listener-queryzmld-listener-reportzmld2-listener-reportznd-neighbor-advertznd-neighbor-solicitzpacket-too-bigznd-redirectznd-router-advertznd-router-solicit)zaddress-unreachablez
bad-headerzbeyond-scopezcommunication-prohibitedzdestination-unreachablez
echo-replyzecho-requestz
failed-policyzmld-listener-donezmld-listener-queryzmld-listener-reportzmld2-listener-reportzneighbour-advertisementzneighbour-solicitationzno-routezpacket-too-bigzparameter-problemzport-unreachabler;zreject-routezrouter-advertisementzrouter-solicitationz
time-exceededzttl-zero-during-reassemblyzttl-zero-during-transitzunknown-header-typezunknown-option)�ipv4�ipv6c@s`eZdZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Z	dd
�Z
dd�Zd�dd�Zdd�Z
dd�Zdd�Zdd�Zd�dd�Zdd�Zd�d d!�Zd"d#�Zd�d%d&�Zd�d(d)�Zd�d*d+�Zd�d,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�Zd<d=�Z d>d?�Z!d@dA�Z"dBdC�Z#dDdE�Z$dFdG�Z%dHdI�Z&d�dJdK�Z'dLdM�Z(dNdO�Z)dPdQ�Z*dRdS�Z+d�dTdU�Z,d�dVdW�Z-d�dXdY�Z.dZd[�Z/d�d\d]�Z0d�d^d_�Z1d�d`da�Z2d�dbdc�Z3d�ddde�Z4dfdg�Z5d�dhdi�Z6djdk�Z7d�dldm�Z8dndo�Z9dpdq�Z:drds�Z;dtdu�Z<d�dvdw�Z=d�dxdy�Z>dzd{�Z?d�d|d}�Z@d~d�ZAd�d��ZBd�d��ZCd�d��ZDd�d��ZEd�d��ZFd�d��ZGd�d�d��ZHdS)��nftablesTcCsb||_d|_g|_i|_i|_i|_i|_i|_gggd�|_t	�|_
|j
jd�|j
jd�dS)NT)�inet�ip�ip6)
�_fwZrestore_command_existsZavailable_tables�rule_to_handle�rule_ref_count�rich_rule_priority_counts�policy_priority_counts�zone_source_index_cache�created_tablesrrIZset_echo_outputZset_handle_output)�self�fwr4r4r5�__init__�sznftables.__init__cCs�xdD]}||krPqWd||dkr`||ddd||dddf}||dd=n(d||dkr�d}||dd=ndS||dd	}|r�|dkr�||kr�|||kr�||j|�n�|dk�r�||kr�g||<|�r(|||k�r||j|�||jd
d�d�||j|�}n|jj�r8d
}nt||�}||}||=|d
k�rf||d<n |d8}||d<||ddd<dS)N�add�insert�deletez%%ZONE_SOURCE%%�rule�zone�addressz%%ZONE_INTERFACE%%�familycSs|dS)Nrr4)�xr4r4r5�<lambda>�sz3nftables._run_replace_zone_source.<locals>.<lambda>)�keyrr<�index)rWrXrY)�remover2�sortrarM�_allow_zone_drifting�len)rTrZrR�verbZzone_sourcer]ra�
_verb_snippetr4r4r5�_run_replace_zone_source�sD




z!nftables._run_replace_zone_sourcecCsBd|krdtj|d�iSd|kr4dtj|d�iSttd��dS)NrXrYrWzFailed to reverse rule)�copy�deepcopyr	r
)rT�dictr4r4r5�reverse_rule�s
znftables.reverse_rulec
Cs�xdD]}||krPqW|||dk�r�||d|}||d|=t|�tkr^ttd��||dd||ddf}|dkr�||ks�|||ks�|||dkr�ttd	��|||d
8<n�||kr�i||<|||kr�d|||<d}xVt||j��D]B}||k�r"|dk�r"P||||7}||k�r|dk�rP�qW|||d
7<||}	||=|dk�r�|	|d<n |d
8}|	|d<||ddd<dS)
NrWrXrYrZz%priority must be followed by a numberr]�chainrz*nonexistent or underflow of priority countr<ra)rWrXrY)r+�intr	rr
�sorted�keys)
rTrZZpriority_counts�tokenrf�priorityrmra�prgr4r4r5�_set_rule_replace_priority�sD

 


z#nftables._set_rule_replace_prioritycCsfx`d
D]X}||krd||krtj||d�}xdD]}||kr6||=q6Wtj|dd	�}|SqWdS)NrWrXrYrZra�handle�positionT)Z	sort_keys)rWrXrY)rarurv)rirj�json�dumps)rTrZrf�rule_keyZnon_keyr4r4r5�
_get_rule_keys


znftables._get_rule_keycCsLdddddg}dddg}g}g}tj|j�}tj|j�}tj|j�}	|jj�}
�x�|D�]�}t|�tkrvtt	d|��x|D]}||kr|Pq|W||kr�tt
d|��|j|�}
|
|
k�rDtj
d|j|
|
|
�|dkr�|
|
d	7<qVnX|
|
d	k�r|
|
d	8<qVn6|
|
d	k�r,|
|
d	8<ntt	d
|
|
|
f��n|
�r\|dk�r\d	|
|
<|j|�tj|�}|
�rttd||dd��||dd<|j||d
�|j||d�|j||	�|dk�rdd|ddd|ddd|ddd|j|
d�ii}|j|�qVWdddd	iig|i}tj�dk�rVtjd|jtj|��|jj|�\}}}|dk�r�tdd|tj|�f��||_||_|	|_|
|_d}x�|D]�}|d	7}|j|�}
|
�s̐q�d|k�r�|j|
=|j|
=�q�x"|D]}||d|k�r�P�q�W||d|k�r$�q�|d||dd|j|
<�q�WdS)NrWrXrY�flush�replacez#rule must be a dictionary, rule: %szno valid verb found, rule: %sz%s: prev rule ref cnt %d, %sr<z)rule ref count bug: rule_key '%s', cnt %drZ�exprz%%RICH_RULE_PRIORITY%%z%%POLICY_PRIORITY%%r]�tablerm)r]r~rmrurIZmetainfoZjson_schema_versionr@z.%s: calling python-nftables with JSON blob: %srz'%s' failed: %s
JSON blob:
%szpython-nftablesru)rirjrPrQrRrOr+rkr	r
rrzrZdebug2�	__class__r2�listr(rtrhrNZgetDebugLogLevelZdebug3rwrxrIZjson_cmd�
ValueError)rT�rules�
log_deniedZ_valid_verbsZ_valid_add_verbsZ_deduplicated_rulesZ_executed_rulesrPrQrRrOrZrfryZ_ruleZ	json_blobZrcr!�errorrar4r4r5�	set_rules+s�







&






znftables.set_rulescCs|j|g|�dS)N�)r�)rTrZr�r4r4r5�set_rule�sznftables.set_ruleNcCs|r
|gStj�S)N)�IPTABLES_TO_NFT_HOOKrp)rTr~r4r4r5�get_available_tables�sznftables.get_available_tablescCsFg}x<dD]4}|jdd||d�ii�|jdd||d�ii�q
W|S)	NrJrKrLrWr~)r]�namerY)rJrKrL)r2)rTr~r�r]r4r4r5�_build_delete_table_rules�s


z"nftables._build_delete_table_rulescCs�i}i}xB|jd�D]4}|j|�}||jkr|j|||<|j|||<qW||_||_i|_i|_i|_x*dD]"}t|j|krp|j|j	t�qpW|j
t�S)NTrJrKrL)rJrKrL)� _build_set_policy_rules_ct_rulesrzrNrOrPrQrR�
TABLE_NAMErSrbr�)rTZsaved_rule_to_handleZsaved_rule_ref_countrZ�
policy_keyr]r4r4r5�build_flush_rules�s 


znftables.build_flush_rulesc
Cslddd�|}g}xTdD]L}|j|ddtd	d
|fddd
diiddddgid�iddigd�ii�qW|S)NrWrY)TFrr r!rZrJz%s_%sr(r)�ctr`�state�in�set�established�related)r.r/r0�accept)r]r~rmr})rr r!)r2�TABLE_NAME_POLICY)rT�enable�add_delr��hookr4r4r5r��s


z)nftables._build_set_policy_rules_ct_rulescCstg}|dkrt|jdddtd�ii�|jdjt�x>dD]6}|jdddtd	d
|fd|dtd
dd�ii�q:W|dk�r�|jdddtd�ii�|jdjt�x>dD]6}|jdddtd	d|fd|dtd
dd�ii�q�W||jd�7}nz|dk�rfx4|jd�D]&}|j|�}||jk�r|j|��qW||jt�7}t|jdk�rp|jdjt�n
t	t
d�|S)NZPANICrWr~rJ)r]r�rr!rmz%s_%sr%r(i,r<�drop)r]r~r�r+r��prio�policy�DROPrr rT�ACCEPTFznot implemented)rr!i���)rr r!)r2r�rS�NFT_HOOK_OFFSETr�rzrNr�rbr	r
)rTr�r�r�rZr�r4r4r5�build_set_policy_rules�sH













znftables.build_set_policy_rulescCs<t�}x,|r|gntj�D]}|jt|j��qWt|�S)N)r��ICMP_TYPES_FRAGMENTSrp�updater�)rT�ipvZ	supportedZ_ipvr4r4r5�supported_icmp_types�sznftables.supported_icmp_typescCs>g}x4dD],}|jdd|td�ii�|j|jt�q
W|S)NrJrKrLrWr~)r]r�)rJrKrL)r2r�rS)rTZdefault_tablesr]r4r4r5�build_default_tabless

znftables.build_default_tables�offcCs�g}x�tdj�D]�}|jdddtd|ddtd|dtd|d	d
�ii�xz|jjrlddd
dgndd
dgD]X}|jdddtd||fd�ii�|jdddtd|ddd||fiigd�ii�qvWqWx�d?D]�}x�tdj�D]�}|jdd|td|ddtd|dtd|d	d
�ii�x~|jj�rJddd
dgndd
dgD]Z}|jdd|td||fd�ii�|jdd|td|ddd||fiigd�ii��qTWq�Wq�WxVtdj�D]F}|jdddtd|ddtd|dtd|d	d
�ii��q�W|jdddtddddddiid d!d"d#gid$�id%digd�ii�|jdddtdddddd&iid d'd$�id%digd�ii�|jdddtdddd(dd)iid*d+d$�id%digd�ii�x~|jj�r�ddd
dgndd
dgD]Z}|jdddtd,d|fd�ii�|jdddtddddd,d|fiigd�ii��q�W|d-k�r�|jdddtddddddiid d!d.gid$�i|j|�d/d0d1iigd�ii�|jdddtddddddiid d!d.gid$�id2digd�ii�|d-k�r$|jdddtdd|j|�d/d0d3iigd�ii�|jdddtddd4d5d6d7�igd�ii�|jdddtdd8ddddiid d!d"d#gid$�id%digd�ii�|jdddtdd8dddd&iid d'd$�id%digd�ii�|jdddtdd8dd(dd)iid*d+d$�id%digd�ii�xbd@D]Z}|jdddtd,d8|fd�ii�|jdddtdd8ddd,d8|fiigd�ii��qWx�dAD]�}xz|jj�r�dd
gnd
gD]^}|jdddtd;d8||fd�ii�|jdddtdd8ddd;d8||fiigd�ii��q�W�qvWxbdBD]Z}|jdddtd,d8|fd�ii�|jdddtdd8ddd,d8|fiigd�ii��qW|d-k�r�|jdddtdd8ddddiid d!d.gid$�i|j|�d/d0d1iigd�ii�|jdddtdd8ddddiid d!d.gid$�id2digd�ii�|d-k�r6|jdddtdd8|j|�d/d0d3iigd�ii�|jdddtdd8d4d5d6d7�igd�ii�|jdddtdd<ddddiid d!d"d#gid$�id%digd�ii�|jdddtd=dd(dd>iid*d+d$�id%digd�ii�xbdCD]Z}|jdddtd,d<|fd�ii�|jdddtdd<ddd,d<|fiigd�ii��q�WxbdDD]Z}|jdddtd,d<|fd�ii�|jdddtdd<ddd,d<|fiigd�ii��qHW|S)ENr&rWrmrJz	mangle_%sr(z%srr<)r]r~r�r+r�r��POLICIES_preZZONES_SOURCEZZONES�
POLICIES_postzmangle_%s_%s)r]r~r�rZ�jump�target)r]r~rmr}rKrLr'znat_%sz	nat_%s_%sz	filter_%sr"r)r�r`r�r�r�r�r�)r.r/r0r�Zstatus�dnat�meta�iifnamez==�lozfilter_%s_%sr�Zinvalidr�prefixzSTATE_INVALID_DROP: r�zFINAL_REJECT: �reject�icmpxzadmin-prohibited)r+r}r#�IN�OUTzfilter_%s_%s_%sr$�
filter_OUTPUT�oifname)rKrL)r�)r�r�)r�)r�)r�)r�rpr2r�rMrd�_pkttype_match_fragment)rTr�Z
default_rulesrmZdispatch_suffixr]�	directionr4r4r5�build_default_ruless�
$

(

&

.
 


&

&











&


.


&










&


&znftables.build_default_rulescCs4|dkrdddgS|dkr dgS|dkr0ddgSgS)	Nr(r"�
FORWARD_IN�FORWARD_OUTr&rr'rr4)rTr~r4r4r5�get_zone_table_chains�s
znftables.get_zone_table_chainsrJc
s��dkr\�dkr\g}
|
j�j�|��||||dd�	�|
j�j�|��||||dd�	�|
S�jjj|���jdkrxdnd��dkr��d	kr�d
nd}�jjj|�t|��g}g}
|r�|jdd
ddiiddt	|�id�i�|�r|
jdd
ddiiddt	|�id�i�ddd�}|�rlxT|D]L}�dk�rT�jj
j|�}||k�rT�||k�rT�q|j�jd|���qW|�r�xT|D]L}�dk�r��jj
j|�}||k�r��||k�r��qx|
j�jd|���qxW��������fdd�}g}
|�rHx�|D]P}|
�rxB|
D]}|
j|||���qWn"�dk�r0|�r0n|
j||d���q�Wn\�dk�rZ|�rZnJ|
�r�xB|
D]}|
j|d|���qfWn"�dk�r�|�r�n|
j|dd��|
S)Nr'rJrK)r]rLr�pre�postrTFr)r�r`r�z==r�)r.r/r0r�)rGrH�saddr�daddrcs�g}|r|j|�|r |j|�|jddd��fii��td���f|d�}|j�j����rrdd|iiSdd|iiSdS)	Nr�r�z%s_%sz%s_%s_POLICIES_%s)r]r~rmr}rWrZrY)r2r�r��_policy_priority_fragment)�ingress_fragment�egress_fragment�expr_fragmentsrZ)�_policyrm�chain_suffixr�r]�p_objrTr~r4r5�_generate_policy_dispatch_rules

zRnftables.build_policy_ingress_egress_rules.<locals>._generate_policy_dispatch_rule)
�extend�!build_policy_ingress_egress_rulesrMr�Z
get_policyrr�policy_base_chain_name�POLICY_CHAIN_PREFIXr2r�r[Zcheck_source�_rule_addr_fragment)rTr�r�r~rmZingress_interfacesZegress_interfacesZingress_sourcesZegress_sourcesr]r��isSNATZingress_fragmentsZegress_fragmentsZ
ipv_to_family�srcr��dstr�r�r�r4)r�rmr�r�r]r�rTr~r5r��sv









z*nftables.build_policy_ingress_egress_rulesFc	
Cs�|dkrT|dkrTg}	|	j|j|||||||d��|	j|j|||||||d��|	S|dkrh|dkrhdnd}
|jjj||t|
d�}d	d
d	d	d
d
d�|}|t|�dd
kr�|dt|�d�d}d}
|dkr�|
dd||fiig}n,ddd|iid|d�i|
dd||fiig}|�rL|�rLd}|td||f|d�}|j|j	��nP|�rnd}|td||f|d�}n.d}|td||f|d�}|�s�|j|j	��|d|iigS)Nr'rJrKrLrTF)r�r�r�)rrr"r�r�r$r<�+�*�gotor�z%s_%sr)r�r`z==)r.r/r0rXz%s_%s_ZONES)r]r~rmr}rWrYrZ)
r��!build_zone_source_interface_rulesrMr�r�r�rer�r��_zone_interface_fragment)rTr�r[r��	interfacer~rmr2r]r�r�r��opt�actionr�rfrZr4r4r5r�Qs\



z*nftables.build_zone_source_interface_rulesc	Csn|dkr�|dkr�g}|jd�r6|j|td�d��}	nd}	td|�sTt|�sT|	dkrp|j|j||||||d��td|�s�t|�s�|	dkr�|j|j||||||d��|S|dkr�|dkr�d	nd
}
|jjj	||t
|
d�}dd
d�|}ddddddd�|}
|jj�rd||f}nd||f}d}|t||j
|
|�|dd||fiigd�}|j|j||��|d|iigS)Nr'rJzipset:rGrKrHrLrTF)r�rXrY)TFr�r�)rrr"r�r�r$z%s_%s_ZONES_SOURCEz%s_%s_ZONESr�r�z%s_%s)r]r~rmr}rZ)�
startswith�_set_get_familyrerrr��build_zone_source_address_rulesrMr�r�r�rdr�r�r��_zone_source_fragment)rTr�r[r�r\r~rmr]r�Zipset_familyr�r�r�r�Zzone_dispatch_chainr�rZr4r4r5r��sB


z(nftables.build_zone_source_address_rulesc
Cs|dkrH|dkrHg}|j|j||||d��|j|j||||d��|Sddd�|}|dkrj|dkrjd	nd
}|jjj||t|d�}	g}|j|d|td
||	fd�ii�x0d!D](}
|j|d|td||	|
fd�ii�q�WxDd"D]<}
|j|d|td
||	fddd||	|
fiigd�ii�q�W|jjj|j	}|jj
�dk�r�|dk�r�|d#k�r�|}|dk�rhd}|j|d|td
||	f|j|jj
��ddd|	|fiigd�ii�|dk�r|d$k�r|d%k�r�|j�}
n|j
�di}
|j|d|td
||	f|
gd�ii�|�s|j�|S)&Nr'rJrKrLrWrY)TFrTF)r�rmz%s_%s)r]r~r�r�r�deny�allowr�z%s_%s_%srZr�r�)r]r~rmr}r�r(�REJECT�
%%REJECT%%r�r�z"filter_%s_%s: "r�)r�rr�r�r�)r�rr�r�r�)r�r�r�)r�r�r�r�)r�r�)r��build_policy_chain_rulesrMr�r�r�r2r�Z	_policiesr��get_log_deniedr��_reject_fragment�lower�reverse)rTr�r�r~rmr]r�r�r�r�r�r�Z
log_suffix�target_fragmentr4r4r5r��sZ





&




 





z!nftables.build_policy_chain_rulescCs<|dkriS|dkr,ddddiid	|d
�iSttd|��dS)
N�all�unicast�	broadcast�	multicastr)r�r`�pkttypez==)r.r/r0zInvalid pkttype "%s")r�r�r�)r	r)rTr�r4r4r5r��s
z nftables._pkttype_match_fragmentcCsdddd�idddd�idddd�idddd�idddd�idddd�idddd�idddd�idddd�idddd�iddd	d�iddd	d�iddd
d�iddd
d�iddd
d�idddd�idddd�iddd
d�iddd
d�idddd�idddd�idddiidddiid�}||S)Nr�r7zhost-prohibited)r+r}znet-prohibitedzadmin-prohibitedrFznet-unreachablezhost-unreachablezport-unreachabler�zprot-unreachablezaddr-unreachablezno-router+z	tcp reset)zicmp-host-prohibitedzhost-prohibzicmp-net-prohibitedz
net-prohibzicmp-admin-prohibitedzadmin-prohibzicmp6-adm-prohibitedzadm-prohibitedzicmp-net-unreachableznet-unreachzicmp-host-unreachablezhost-unreachzicmp-port-unreachablezicmp6-port-unreachablezport-unreachzicmp-proto-unreachablez
proto-unreachzicmp6-addr-unreachablezaddr-unreachzicmp6-no-routezno-routez	tcp-resetztcp-rstr4)rTZreject_typeZfragsr4r4r5�_reject_types_fragment�s0
znftables._reject_types_fragmentcCsdddd�iS)Nr�r�zadmin-prohibited)r+r}r4)rTr4r4r5r�sznftables._reject_fragmentcCs ddddiiddddgid	�iS)
Nr)r�r`�l4protoz==r�r7rF)r.r/r0r4)rTr4r4r5�_icmp_match_fragment"sznftables._icmp_match_fragmentcCsP|siSddddd�}|j�\}}|||d�}|j�}|dk	rH||d<d|iS)	N�secondZminuteZhourZday)�s�m�h�d)�rateZper�burst�limit)Zvalue_parseZburst_parse)rTr�Zrich_to_nftr�Zdurationr�r�r4r4r5�_rich_rule_limit_fragment'sz"nftables._rich_rule_limit_fragmentcCs�t|j�tttgkrn<|jrHt|j�tttt	gkrRt
tdt|j���n
t
td��|jdkr�t|j�ttgks�t|j�tt	gkr�dSt|j�tgks�t|j�ttgkr�dSn|jdkr�dSdSdS)NzUnknown action %szNo rule action specified.rr�r�r�r�)
r+�elementrrrr�rrrrr	rrr)rT�	rich_ruler4r4r5�_rich_rule_chain_suffix?s 


z nftables._rich_rule_chain_suffixcCs>|jr|jrttd��|jdkr(dS|jdkr6dSdSdS)NzNot log or auditrrr�r�)r�auditr	rrr)rTr�r4r4r5� _rich_rule_chain_suffix_from_logUs


z)nftables._rich_rule_chain_suffix_from_logcCsddiS)Nz%%ZONE_INTERFACE%%r4)rTr4r4r5r�`sz!nftables._zone_interface_fragmentcCsNtd|�rt|�}n,td|�r@|jd�}t|d�d|d}d||d�iS)NrH�/rr<z%%ZONE_SOURCE%%)r[r\)rrr�split)rTr[r\Z
addr_splitr4r4r5r�cs



znftables._zone_source_fragmentcCs
d|jiS)Nz%%POLICY_PRIORITY%%)rr)rTr�r4r4r5r�ksz"nftables._policy_priority_fragmentcCs|s|jdkriSd|jiS)Nrz%%RICH_RULE_PRIORITY%%)rr)rTr�r4r4r5�_rich_rule_priority_fragmentnsz%nftables._rich_rule_priority_fragmentcCs�|js
iS|jjj||t�}ddd�|}|j|�}i}	|jjrPd|jj|	d<|jjr|d|jjkrhdn|jj}
d|
|	d<d	td
|||f||j	|jj
�d|	igd�}|j|j|��|d
|iiS)NrWrY)TFz%sr�Zwarning�warn�levelrJz%s_%s_%sr)r]r~rmr}rZ)
rrMr�r�r�r�r�rr�r�r�r�r�)rTr�r�r�r~r�r�r�r�Zlog_optionsrrZr4r4r5�_rich_rule_logss&
znftables._rich_rule_logc
Cs�|js
iS|jjj||t�}ddd�|}|j|�}dtd|||f||j|jj�dddiigd	�}	|	j	|j
|��|d
|	iiS)NrWrY)TFrJz%s_%s_%srrr�)r]r~rmr}rZ)r�rMr�r�r�r�r�r�r�r�r�)
rTr�r�r�r~r�r�r�r�rZr4r4r5�_rich_rule_audit�s
znftables._rich_rule_auditc
Cs�|js
iS|jjj||t�}ddd�|}|j|�}d|||f}	t|j�tkr\ddi}
�nt|j�tkr�|jjr�|j	|jj�}
nddi}
n�t|j�t
kr�ddi}
n�t|j�tk�rHd}|jjj||t�}d|||f}	|jjj
d	�}t|�d
k�r,dddd
iiddddd
ii|d
gi|dgid�i}
ndddd
ii|dd�i}
nttdt|j���dt|	||j|jj�|
gd�}|j|j|��|d|iiS)NrWrY)TFz%s_%s_%sr�r�r�r&r�r<r�r`�mark�^�&r)r`�valuezUnknown action %srJ)r]r~rmr}rZ)r�rMr�r�r�r�r+rrr�rrr�r�rer	rr�r�r�r�r�)
rTr�r�r�r~r�r�r�r�rmZrule_actionrrZr4r4r5�_rich_rule_action�sB


,znftables._rich_rule_actioncCs�|jd�r0|j|td�d�d|kr(dnd|�St|�r>d}n�td|�rNd}nvtd|�r�d}tj|dd�}d	|jj	|j
d
�i}nDtd|�r�d}t|�}n,d}|jd
�}d	t|d�t
|d�d
�i}dd||d�i|r�dnd|d�iSdS)Nzipset:r�TF�etherrGrK)�strictr�)�addrrerHrLr�rr<r)r*)r,r-z!=z==)r.r/r0)r��_set_match_fragmentrerrr�	ipaddressZIPv4NetworkZnetwork_addressZ
compressedZ	prefixlenrr�rn)rTZ
addr_fieldr\�invertr]Znormalized_addressZaddr_lenr4r4r5r��s(
&





znftables._rule_addr_fragmentcCs6|siS|d
krttd|��ddddiid|d	�iS)NrGrHzInvalid familyr)r�r`�nfprotoz==)r.r/r0)rGrH)r	r)rTZrich_familyr4r4r5�_rich_rule_family_fragment�s
z#nftables._rich_rule_family_fragmentcCs8|siS|jr|j}n|jr&d|j}|jd||jd�S)Nzipset:r�)r)r�ipsetr�r)rTZ	rich_destr\r4r4r5�_rich_rule_destination_fragment�s
z(nftables._rich_rule_destination_fragmentcCsZ|siS|jr|j}n2t|d�r.|jr.|j}nt|d�rH|jrHd|j}|jd||jd�S)N�macrzipset:r�)r)r�hasattrrrr�r)rTZrich_sourcer\r4r4r5�_rich_rule_source_fragment�s
z#nftables._rich_rule_source_fragmentcCsPt|�}t|t�r$|dkr$tt��n(t|�dkr8|dSd|d|dgiSdS)Nrr<�range)r�
isinstancernr	rre)rT�portrr4r4r5�_port_fragments
znftables._port_fragmentc	Csbddd�|}d}|jjj||t�}	g}
|r>|
j|j|j��|rT|
j|jd|��|r||
j|j|j	��|
j|j
|j��|
jdd|dd	�id
|j|�d�i�|s�t
|j�tkr�|
jddd
diiddddgid�i�g}|�r0|j|j|||||
��|j|j|||||
��|j|j|||||
��n.|j|ddtd||	f|
ddigd�ii�|S)NrWrY)TFr(r�r)r*�dport)r,r-z==)r.r/r0r�r`r�r�r��new�	untrackedrZrJz%s_%s_allowr�)r]r~rmr})rMr�r�r�r2rr]r�r�destinationr�sourcerr+r�rrrrr�)rTr�r��protorrr�r�r~r�r�r�r4r4r5�build_policy_ports_ruless:


z!nftables.build_policy_ports_rulesc	CsZddd�|}d}|jjj||t�}g}	|r>|	j|j|j��|rT|	j|jd|��|r||	j|j|j	��|	j|j
|j��|	jdddd	iid
|d�i�|s�t|j
�tkr�|	jdddd
iiddddgid�i�g}
|�r(|
j|j|||||	��|
j|j|||||	��|
j|j|||||	��n.|
j|ddtd||f|	ddigd�ii�|
S)NrWrY)TFr(r�r)r�r`r�z==)r.r/r0r�r�r�r�rrrZrJz%s_%s_allowr�)r]r~rmr})rMr�r�r�r2rr]r�rrrrr+r�rrrrr�)rTr�r�r,rr�r�r~r�r�r�r4r4r5�build_policy_protocol_rules2s8

z$nftables.build_policy_protocol_rulesc	Csbddd�|}d}|jjj||t�}	g}
|r>|
j|j|j��|rT|
j|jd|��|r||
j|j|j	��|
j|j
|j��|
jdd|dd	�id
|j|�d�i�|s�t
|j�tkr�|
jddd
diiddddgid�i�g}|�r0|j|j|||||
��|j|j|||||
��|j|j|||||
��n.|j|ddtd||	f|
ddigd�ii�|S)NrWrY)TFr(r�r)r*�sport)r,r-z==)r.r/r0r�r`r�r�r�rrrZrJz%s_%s_allowr�)r]r~rmr})rMr�r�r�r2rr]r�rrrrrr+r�rrrrr�)rTr�r�rrrr�r�r~r�r�r�r4r4r5�build_policy_source_ports_rulesUs:


z(nftables.build_policy_source_ports_rulesc
	Cs�d}|jjj||t�}	ddd�|}
g}|rR|jdddtd||f||d�ii�g}|rl|j|jd	|��|jd
d|dd
�id|j|�d�i�|jdd||fi�|j|
ddtd|	|d�ii�|S)Nr(rWrY)TFz	ct helperrJzhelper-%s-%s)r]r~r�r+r,r�r)r*r)r,r-z==)r.r/r0rZzfilter_%s_allow)r]r~rmr})rMr�r�r�r2r�r�r)
rTr�r�rrrZhelper_nameZmodule_short_namer~r�r�r�r�r4r4r5�build_policy_helper_ports_ruleszs.



z(nftables.build_policy_helper_ports_rulescCs�ddd�|}|jjj||t�}g}	|rv|t|�ddkrT|dt|�d�d}ddd	d
iid|d�id
dig}
n|jd|�d
dig}
dtd||
d�}|	j|d|ii�|	S)NrWrY)TFr<r�r�r)r�r`r�z==)r.r/r0r�r�rJzfilter_%s_allow)r]r~rmr}rZ)rMr�r�r�rer�r�r2)rTr�r[r�r~r�rr�r�r�r}rZr4r4r5�build_zone_forward_rules�s"z!nftables.build_zone_forward_rulesc	Cs�d}|jjj||tdd�}ddd�|}g}|r`|j|j|j��|j|j|j��|j	|�}	nd}	|t
d||	f|d	d
ddiid
dd�iddigd�}
|
j|j|��|d|
iigS)Nr'T)r�rWrY)TFr�z	nat_%s_%sr)r�r`r�z!=r�)r.r/r0Z
masquerade)r]r~rmr}rZ)
rMr�r�r�r2rrrrr�r�r�r�)rTr�r�r]r�r~r�r�r�r�rZr4r4r5�"_build_policy_masquerade_nat_rules�s&
z+nftables._build_policy_masquerade_nat_rulesc
Cs^g}|rD|jr|jdks,|jrDtd|jj�rD|j|j||d|��nV|r�|jrX|jdksl|jr�td|jj�r�|j|j||d|��n|j|j||d|��d}|jjj||t	�}ddd�|}g}|r�|j
|j|j��|j
|j
|j��|j|�}	nd	}	d
td||	f|dd
ddiiddddgid�iddigd�}
|
j|j|��|j
|d|
ii�|S)NrHrLrGrKr(rWrY)TFr�rJzfilter_%s_%sr)r�r`r�r�r�rr)r.r/r0r�)r]r~rmr}rZ)r]rrrr�r&rMr�r�r�r2rrrr�r�r�r�)rTr�r�r�r�r~r�r�r�r�rZr4r4r5�build_policy_masquerade_rules�s8
z&nftables.build_policy_masquerade_rulesc	Cs$d}	|jjj||	t�}
ddd�|}g}|r\|j|j|j��|j|j|j��|j	|�}
nd}
|jdd|dd	�id
|j
|�d�i�|r�td|�r�t|�}|r�|d
kr�|jd||j
|�d�i�q�|jdd|ii�n|jdd|j
|�ii�|t
d|
|
f|d�}|j|j|��|d|iigS)Nr'rWrY)TFr�r)r*r)r,r-z==)r.r/r0rHr�r�)rrrr;rz	nat_%s_%s)r]r~rmr}rZ)rMr�r�r�r2rrrrr�rrrr�r�r�)rTr�r�rr,�toaddr�toportr]r�r~r�r�r�r�rZr4r4r5�$_build_policy_forward_port_nat_rules�s4


z-nftables._build_policy_forward_port_nat_rulesc	
Cs�g}|rF|jr|jdks&|rFtd|�rF|j|j||||||d|��n�|r�|jrZ|jdksh|r�td|�r�|j|j||||||d|��nL|r�td|�r�|j|j||||||d|��n|j|j||||||d|��|S)NrHrLrGrK)r]rr�r*)	rTr�r�rr,r)r(r�r�r4r4r5�build_policy_forward_port_rulessz(nftables.build_policy_forward_port_rulescCs2|t|krt||Sttd||j|f��dS)Nz)ICMP type '%s' not supported by %s for %s)r�r	rr�)rTr�Z	icmp_typer4r4r5�_icmp_types_to_nft_fragments(sz%nftables._icmp_types_to_nft_fragmentscCsBd}|jjj||t�}ddd�|}|r6|jr6|j}n<|jrjg}d|jkrT|jd�d|jkrr|jd�nddg}g}	�x�|D�]�}
|jjj|�r�d||f}ddi}nd	||f}|j�}g}
|r�|
j|j	|j
��|
j|j|j��|
j|j|j
��|
j|j|
|j��|�r�|	j|j|||||
��|	j|j|||||
��|j�rf|	j|j|||||
��nN|j|�}d
td|||f|
|j�gd�}|j|j|��|	j|d
|ii�q~|jj�dk�r|jjj|��r|	j|d
d
t||
|j|jj��ddd||fiigd�ii�|	j|d
d
t||
|gd�ii�q~W|	S)Nr(rWrY)TFrGrHz%s_%s_allowr�z
%s_%s_denyrJz%s_%s_%s)r]r~rmr}rZr�rr�z"%s_%s_ICMP_BLOCK: ")rMr�r�r��ipvsrr2�query_icmp_block_inversionr�rr]rrrr�r,r�rrr�rr�r�r�r�r�r�)rTr�r�Zictr�r~r�r�r-r�r�Zfinal_chainr�r�r�rZr4r4r5�build_policy_icmp_block_rules/sb





"
"
z&nftables.build_policy_icmp_block_rulescCs�d}|jjj||t�}g}ddd�|}|jjj|�r@|j�}nddi}|j|ddtd||fd	|j�|gd
�ii�|jj	�dkr�|jjj|�r�|j|ddtd||fd	|j�|j
|jj	��dd
d||fiigd
�ii�|S)Nr(rWrY)TFr�rZrJz%s_%sr9)r]r~rmrar}r�rr�z%s_%s_ICMP_BLOCK: )rMr�r�r�r.r�r2r�r�r�r�)rTr�r�r~r�r�r�r�r4r4r5�'build_policy_icmp_block_inversion_rulesks,




 z0nftables.build_policy_icmp_block_inversion_rulescCs�g}ddddiiddd�iddd	d
dgdd
�iddd�ig}|dkrV|jdddii�|jddi�|jdddtd|d�ii�|jdddtdddddd�iddddgid�id digd�ii�|S)!Nr)r�r`rz==rH)r.r/r0Zfibr�ZiifrZoif)�flags�resultFr�rr�zrpfilter_DROP: r�rXrZrJZfilter_PREROUTING)r]r~rmr}r*rFr+)r,r-r�znd-router-advertznd-neighbor-solicitr�)r2r�)rTr�r�r�r4r4r5�build_rpfilter_rules�s0

znftables.build_rpfilter_rulesc	Cs�ddddddddd	g	}d
d�|D�}dd
ddd�idd|id�ig}|jjd"krb|jdddii�|j|jd��g}|jdddtdd|d�ii�|jdddtd d!|d�ii�|S)#Nz::0.0.0.0/96z::ffff:0.0.0.0/96z2002:0000::/24z2002:0a00::/24z2002:7f00::/24z2002:ac10::/28z2002:c0a8::/32z2002:a9fe::/32z2002:e000::/19cSs2g|]*}d|jd�dt|jd�d�d�i�qS)r�r�rr<)rre)r�rn)�.0r^r4r4r5�
<listcomp>�sz5nftables.build_rfc3964_ipv4_rules.<locals>.<listcomp>r)r*rLr�)r,r-z==r�)r.r/r0r�r�rr�zRFC3964_IPv4_REJECT: zaddr-unreachrWrZrJr�r<)r]r~rmrar}Zfilter_FORWARDrB)r�r�)rMZ_log_deniedr2r�r�)rTZ	daddr_setr�r�r4r4r5�build_rfc3964_ipv4_rules�s:

z!nftables.build_rfc3964_ipv4_rulescCs�d}g}|j|j|j��|j|j|j��|j|j|j��g}|j|j|||||��|j|j|||||��|j|j	|||||��|S)Nr()
r2rr]rrrrrrr)rTr�r�r�r~r�r�r4r4r5�*build_policy_rich_source_destination_rules�sz3nftables.build_policy_rich_source_destination_rulescCs|dkrdSdS)NrGrH�ebTF)rGrHr8r4)rTr�r4r4r5�is_ipv_supported�sznftables.is_ipv_supportedc
Cs�ddd�}||||ddg||dd||g||dd||g||dg||||||g||ddg||dd||g||dgdd	�}||kr�||Sttd
|��dS)NZ	ipv4_addrZ	ipv6_addr)rGrHZ
inet_protoZinet_servicerZifnameZ
ether_addr)zhash:ipzhash:ip,portzhash:ip,port,ipzhash:ip,port,netzhash:ip,markzhash:netzhash:net,netz
hash:net,portzhash:net,port,netzhash:net,ifacezhash:macz!ipset type name '%s' is not valid)r	r
)rTr�r+Zipv_addr�typesr4r4r5�_set_type_list�s"

znftables._set_type_listc
Cs�|rd|kr|ddkrd}nd}t||j||�d�}x0|jd�djd�D]}|dkrLdg|d
<PqLW|r�d|kr�|d|d<d|kr�|d|d<g}x0dD](}d|i}	|	j|�|jdd|	ii�q�W|S)Nr]�inet6rHrG)r~r�r+�:r<�,rK�netrZintervalr1ZtimeoutZmaxelem�sizerJrLrWr�)rKr?r)rJrKrL)r�r;r�r�r2)
rTr�r+�optionsr�Zset_dict�tr�r]Z	rule_dictr4r4r5�build_set_create_rules�s*


znftables.build_set_create_rulescCs$|j|||�}|j||jj��dS)N)rCr�rMr�)rTr�r+rAr�r4r4r5�
set_createsznftables.set_createcCs8x2dD]*}dd|t|d�ii}|j||jj��qWdS)NrJrKrLrYr�)r]r~r�)rJrKrL)r�r�rMr�)rTr�r]rZr4r4r5�set_destroys

znftables.set_destroycCs6|jjj|�jjd�djd�}g}x�tt|��D]�}||dkrr|jdddii�|jdd	|rdd
ndd�i�q2||dkr�|jd|j|�|r�dndd�i�q2||dkr�|jdd|r�dndii�q2||dkr�|jdddii�q2t	d||��q2Wdt|�dk�rd|in|d|�r&dndd|d�iS)Nr=r<r>rr�r`r�r*Zthrr")r,r-rKr?rr�r�Zifacer�r�rz-Unsupported ipset type for match fragment: %sr)�concatrz!=z==�@)r.r/r0)rKr?r)
rMr�	get_ipsetr+r�rrer2r�r	)rTr�Z
match_destr�type_formatr3�ir4r4r5r s$ znftables._set_match_fragmentcCsN|jjj|�}|jjd�djd�}|jd�}t|�t|�krHttd��g}�x�tt|��D�]�}||dk�r,y||j	d�}Wn&t
k
r�|jd�||}	Yn,X|j||d|��|||dd�}	y|	j	d�}Wn t
k
�r|j|	�Yn(X|jd|	d|�|	|dd�gi�q\||dk�r d||k�rb|jd||jd�i�n�y||j	d�}WnLt
k
�r�||}
d|jk�r�|jdd
k�r�t
|
�}
|j|
�Yn^X||d|�}
d|jk�r�|jdd
k�r�t
|
�}
|jd|
t|||dd��d�i�q\|j||�q\Wt|�dk�rJd|igS|S)Nr=r<r>z+Number of values does not match ipset type.rZtcp�-rrKr?r�r]r<r�)rrerF)rKr?)rMrrHr+r�rer	rrrar�r2rArrn)rTr��entry�objrIZentry_tokensZfragmentrJraZport_strrr4r4r5�_set_entry_fragment7sL

("znftables._set_entry_fragmentc	Cs>g}|j||�}x(dD] }|jdd|t||d�ii�qW|S)NrJrKrLrWr�)r]r~r��elem)rJrKrL)rNr2r�)rTr�rLr�r�r]r4r4r5�build_set_add_rulesks

znftables.build_set_add_rulescCs"|j||�}|j||jj��dS)N)rPr�rMr�)rTr�rLr�r4r4r5�set_addusznftables.set_addcCsF|j||�}x4dD],}dd|t||d�ii}|j||jj��qWdS)NrJrKrLrYr�)r]r~r�rO)rJrKrL)rNr�r�rMr�)rTr�rLr�r]rZr4r4r5�
set_deleteys
znftables.set_deletecCs4g}x*dD]"}dd|t|d�ii}|j|�q
W|S)NrJrKrLr{r�)r]r~r�)rJrKrL)r�r2)rTr�r�r]rZr4r4r5�build_set_flush_rules�s
znftables.build_set_flush_rulescCs |j|�}|j||jj��dS)N)rSr�rMr�)rTr�r�r4r4r5�	set_flush�s
znftables.set_flushcCsJ|jjj|�}|jdkrd}n(|jrBd|jkrB|jddkrBd}nd}|S)Nzhash:macr	r]r<rLrK)rMrrHr+rA)rTr�rr]r4r4r5r��s
znftables._set_get_familyc	Cs�g}|j|j|||��|j|j|��d}x^|D]D}|j|j||��|d7}|dkr2|j||jj��|j�d}q2W|j||jj��dS)Nrr<i�)r�rCrSrPr�rMr��clear)	rTZset_nameZ	type_nameZentriesZcreate_optionsZ
entry_optionsr��chunkrLr4r4r5�set_restore�s
znftables.set_restore)N)N)r�)rJ)FrJ)rJ)rJ)F)NN)NN)NN)NN)N)N)N)N)N)F)N)N)F)NN)I�__name__�
__module__�__qualname__r�Zpolicies_supportedrVrhrlrtrzr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrr�rrrrr r!r#r$r%r&r'r*r+r,r/r0r3r6r7r9r;rCrDrErrNrPrQrRrSrTr�rWr4r4r4r5rI�s�/.`

4


R
i
;
-
9
 +


	
$
$
$


'
$

<
#


4
		rIij���i����)N)(Z
__future__rrirwr
Zfirewall.core.loggerrZfirewall.functionsrrrrrZfirewall.errorsr	r
rrr
rrZfirewall.core.richrrrrrrrZnftables.nftablesrr�r�r�r�r�r6r��objectrIr4r4r4r5�<module>s�$$





































core/__pycache__/fw_policies.cpython-36.pyc000064400000004432150351351730014643 0ustar003

��g�
�@sVdgZddlmZddlmZddlmZddlmZddlm	Z	Gdd�de
�ZdS)	�FirewallPolicies�)�config)�log)�LockdownWhitelist)�errors)�
FirewallErrorc@sDeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dS)rcCsd|_ttj�|_dS)NF)�	_lockdownrrZLOCKDOWN_WHITELIST�lockdown_whitelist)�self�r�!/usr/lib/python3.6/fw_policies.py�__init__szFirewallPolicies.__init__cCsd|j|j|jfS)Nz
%s(%r, %r))�	__class__rr	)r
rrr�__repr__#s
zFirewallPolicies.__repr__cCsd|_|jj�dS)NF)rr	�cleanup)r
rrrr'szFirewallPolicies.cleanupcCs�|dkr2tjd|�|jj|�r�tjd�dSn�|dkrdtjd|�|jj|�r�tjd�dSnb|dkr�tjd	|�|jj|�r�tjd
�dSn0|dkr�tjd|�|jj|�r�tjd
�dSdS)N�contextz#Doing access check for context "%s"zcontext matches.TZuidzDoing access check for uid %dzuid matches.�userz Doing access check for user "%s"z
user matches.Zcommandz#Doing access check for command "%s"zcommand matches.F)rZdebug2r	Z
match_contextZdebug3Z	match_uidZ
match_userZ
match_command)r
�key�valuerrr�access_check-s*



zFirewallPolicies.access_checkcCs|jrttjd��d|_dS)Nzenable_lockdown()T)rrrZALREADY_ENABLED)r
rrr�enable_lockdownDsz FirewallPolicies.enable_lockdowncCs|jsttjd��d|_dS)Nzdisable_lockdown()F)rrrZNOT_ENABLED)r
rrr�disable_lockdownIsz!FirewallPolicies.disable_lockdowncCs|jS)N)r)r
rrr�query_lockdownNszFirewallPolicies.query_lockdownN)
�__name__�
__module__�__qualname__r
rrrrrrrrrrrsN)�__all__ZfirewallrZfirewall.core.loggerrZ#firewall.core.io.lockdown_whitelistrrZfirewall.errorsr�objectrrrrr�<module>score/__pycache__/fw_zone.cpython-36.opt-1.pyc000064400000077522150351351730014760 0ustar003

��gy��@s�ddlZddlZddlmZmZmZddlmZddlm	Z	ddl
mZddlm
Z
mZmZmZmZmZmZmZmZddlmZmZmZddlmZdd	lmZdd
lmZGdd�de �Z!dS)
�N)�	SHORTCUTS�DEFAULT_ZONE_TARGET�SOURCE_IPSET_TYPES)�FirewallTransaction)�Policy)�log)	�Rich_Service�	Rich_Port�
Rich_Protocol�Rich_SourcePort�Rich_ForwardPort�Rich_IcmpBlock�
Rich_IcmpType�Rich_Masquerade�	Rich_Mark)�checkIPnMask�
checkIP6nMask�	check_mac)�errors)�
FirewallError)�LastUpdatedOrderedDictc@sNeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd�dd �Zd!d"�Zd#d$�Zd%d&�Zd�d'd(�Zd)d*�Zd+d,�Zd-d.�Zd�d/d0�Zd�d1d2�Zd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Z d=d>�Z!d�d@dA�Z"dBdC�Z#d�dDdE�Z$d�dFdG�Z%d�dHdI�Z&dJdK�Z'dLdM�Z(dNdO�Z)d�dQdR�Z*d�dSdT�Z+d�dUdV�Z,dWdX�Z-d�dYdZ�Z.d�d[d\�Z/d]d^�Z0d_d`�Z1dadb�Z2d�dcdd�Z3dedf�Z4dgdh�Z5didj�Z6dkdl�Z7dmdn�Z8dodp�Z9d�dqdr�Z:dsdt�Z;dudv�Z<dwdx�Z=d�dydz�Z>d{d|�Z?d}d~�Z@dd��ZAd�d�d��ZBd�d��ZCd�d��ZDd�d��ZEd�d��ZFd�d�d��ZGd�d��ZHd�d��ZId�d��ZJd�d�d��ZKd�d��ZLd�d��ZMd�d��ZNd�d�d��ZOd�d��ZPd�d��ZQd�d�d��ZRd�d�d��ZSd�d�d��ZTd�d��ZUd�d�d��ZVd�d��ZWd�d��ZXd�d��ZYd�d�d��ZZd�d��Z[d�d��Z\d�d��Z]d�d��Z^d�d��Z_d�d�d��Z`d�d��Zad�d�d„Zbd�dĄZcd�dƄZddS)��FirewallZonercCs||_i|_i|_dS)N)�_fw�_zones�_zone_policies)�self�fw�r�/usr/lib/python3.6/fw_zone.py�__init__&szFirewallZone.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r)rrrr�__repr__+szFirewallZone.__repr__cCs|jj�|jj�dS)N)r�clearr)rrrr�cleanup.s
zFirewallZone.cleanupcCs
t|j�S)N)rr)rrrr�new_transaction2szFirewallZone.new_transactioncCsdj||d�S)Nzzone_{fromZone}_{toZone})�fromZone�toZone)�format)rr%r&rrr�policy_name_from_zones5sz#FirewallZone.policy_name_from_zonescCst|jj��S)N)�sortedr�keys)rrrr�	get_zones:szFirewallZone.get_zonescCs8g}x.|j�D]"}|j|�s&|j|�r|j|�qW|S)N)r+�list_interfaces�list_sources�append)rZactive_zones�zonerrr�get_active_zones=s
zFirewallZone.get_active_zonescCs6|j|�}x&|jD]}||j|jdkr|SqWdS)N�
interfaces)�_FirewallZone__interface_idr�settings)r�	interface�interface_idr/rrr�get_zone_of_interfaceDs

z"FirewallZone.get_zone_of_interfacecCs6|j|�}x&|jD]}||j|jdkr|SqWdS)N�sources)�_FirewallZone__source_idrr3)r�source�	source_idr/rrr�get_zone_of_sourceLs

zFirewallZone.get_zone_of_sourcecCs|jj|�}|j|S)N)r�
check_zoner)rr/�zrrr�get_zoneTszFirewallZone.get_zonecCsBt�}|j|_|j||�|_|j|_|j|_|g|_|g|_�x�dD�]�}||jkr~|d	kr~|dkr~t	||t
jt||���qD|d
kr�||jkr�|d
kr�t	||t
jt||���qD||jko�|d
ko�|dk�r�t	||t
jt||���qD|dkrDg|_
xB|j
D]8}|j||�}||j|j|�k�r�|j
jt
j|���q�WqDW|S)N�services�ports�
masquerade�
forward_ports�source_ports�icmp_blocks�rules�	protocols�HOST�ANY)r?r@rArBrCrDrErF)r?r@rCrDrF)rA)rDrB)rE)r�nameZderived_from_zoner(�ZONE_POLICY_PRIORITYZpriority�targetZ
ingress_zonesZegress_zones�setattr�copy�deepcopy�getattrrE�_rich_rule_to_policiesr.)r�z_objr%r&�p_objZsetting�ruleZcurrent_policyrrr�policy_obj_from_zone_objXs6

z%FirewallZone.policy_obj_from_zone_objcCs�dd�d	D�|_||j|j<g|j|j<xX|jdfd|jf|jdfgD]8\}}|j|||�}|jjj|�|j|jj|j�qFW|j	|j�dS)
NcSsi|]}t�|�qSr)r)�.0�xrrr�
<dictcomp>sz)FirewallZone.add_zone.<locals>.<dictcomp>r1r7�icmp_block_inversion�forwardrGrH)r1r7rXrY)
r3rrIrrTr�policyZ
add_policyr.�copy_permanent_to_runtime)r�objr%r&rRrrr�add_zone~s

zFirewallZone.add_zonecCsn|j|}x|jD]}|j||dd�qWx|jD]}|j||dd�q2W|jrZ|j|�|jrj|j|�dS)NF)�allow_apply)	rr1�
add_interfacer7�
add_sourcerY�add_forwardrX�add_icmp_block_inversion)rr/r\�argrrrr[�s

z&FirewallZone.copy_permanent_to_runtimecCs8|j|}|jr|j|�|jj�|j|=|j|=dS)N)r�applied�unapply_zone_settingsr3r"r)rr/r\rrr�remove_zone�s


zFirewallZone.remove_zoneNcCsVxP|j�D]D}|j|}t|j�dks4t|j�dkr
tjd|�|j||d�q
WdS)NrzApplying zone '%s')�use_transaction)r+r�lenr1r7r�debug1�apply_zone_settings)rrgr/rQrrr�apply_zones�s

zFirewallZone.apply_zonescCs|j|}||_dS)N)rrd)rr/rdr\rrr�set_zone_applied�s
zFirewallZone.set_zone_appliedcCs�d|krdS|jd�}t|�dkr&dSd}x tD]}|dt|kr0|}q0W|dk	r�|d|j�krhdSt|�dks�t|�dkr�|ddkr�|d|fSdS)N�_�r���prer�deny�allow�post)rqrrrrsrt)�splitrhrr+)r�chainZsplits�_chainrVrrr�zone_from_chain�s 

zFirewallZone.zone_from_chaincCst|j|�}|dkrdS|\}}|d	kr0|}d}n4|d
krB|}d}n"|dkrTd}|}nttjd|��|j||�|fS)N�
PREROUTING�
FORWARD_INrH�INPUTrG�POSTROUTING�FORWARD_OUTz&chain '%s' can't be mapped to a policy)ryrz)r{)r|r})rxrrZ
INVALID_CHAINr()rrvrVr/rwr%r&rrr�policy_from_chain�s
zFirewallZone.policy_from_chainc	Csj|dkrf|j|�}|dk	rf|j|�\}}|dkr:|j�}n|}|jjj|d|||�|dkrf|jd�dS)N�ipv4�ipv6T)rr�)r~r$rrZZgen_chain_rules�execute)	r�ipv�tablervrgrVrZrw�transactionrrr�create_zone_base_by_chain�s

z&FirewallZone.create_zone_base_by_chaincCstj�||d�}|S)N)Zdate�sender�timeout)�time)rr�r��retrrrZ__gen_settings�szFirewallZone.__gen_settingscCs|j|�jS)N)r>r3)rr/rrr�get_settings�szFirewallZone.get_settingscCs�|j|�}x�|D]z}xt||D]h}|dkr<|j||||�q|dkr`|j|||d|d|�q|dkrlqq|dkrvqtjd|||�qWqW|r�|j|||�dS)Nr1r7rrorXrYz3Zone '%s': Unknown setting '%s:%s', unable to apply)r��
_interface�_sourcerZwarning�_icmp_block_inversion)r�enabler/r�r3�key�argsrrr�_zone_settingss

zFirewallZone._zone_settingscCs�|jj|�}|j|}|jr dSd|_|dkr8|j�}n|}x2|j|D]$}tjd||�|jjj	||d�qHW|j
d||�|dkr�|jd�dS)NTz+Applying policy (%s) derived from zone '%s')rg)rr<rrdr$rrrirZ�apply_policy_settingsr�r�)rr/rg�_zoner\r�rZrrrrjs

z FirewallZone.apply_zone_settingscCs�|jj|�}|j|}|js dS|dkr2|j�}n|}x$|j|D]}|jjj||d�qBW|jd||�|dkr||j	d�dS)N)rgFT)
rr<rrdr$rrZ�unapply_policy_settingsr�r�)rr/rgr�r\r�rZrrrre,s

z"FirewallZone.unapply_zone_settingscCs~|j|�}|j|�}g}x\td�D]P}|j|d|krZ|jtjt||j|d���q"|j||j|d�q"Wt|�S)zH
        :return: exported config updated with runtime settings
        �r)	r>�get_config_with_settings_dict�rangeZIMPORT_EXPORT_STRUCTUREr.rMrNrO�tuple)rr/r\Z	conf_dictZ	conf_list�irrr�get_config_with_settings?s

"z%FirewallZone.get_config_with_settingsc
Cs�|j|�j�}|dtkr"d|d<|j|�|j|�|j|�|j|�|j|�|j|�|j	|�|j
|�|j|�|j|�|j
|�|j|�d�}|jj||�S)zH
        :return: exported config updated with runtime settings
        rK�default)r?r@rDrArBr1r7�	rules_strrFrCrXrY)r>Zexport_config_dictr�
list_services�
list_ports�list_icmp_blocks�query_masquerade�list_forward_portsr,r-�
list_rules�list_protocols�list_source_ports�query_icmp_block_inversion�
query_forwardrZ'combine_runtime_with_permanent_settings)rr/Z	permanentZruntimerrrr�Os z*FirewallZone.get_config_with_settings_dictc
sddlm�d��fdd�	}��fdd�}�j�jf�j�jf�j�jf�j�j	f�j
�jf�j�j
f�j�jf||f�j�jf�j�jf�j�jf�j�jfd�}�j|�}�jj||�\}}	xv|	D]n}
t|	|
t��r$xX|	|
D]:}t|t��r||
d|f|��q�||
d||�q�Wq�||
d|�q�Wx�|D]�}
t||
t��r�x�||
D]l}|
dk�r�||
d|||d�nDt|t��r�||
d|f|�d|d��n||
d||d|d��q\Wn6|
dk�r�||
d||d�n||
d|d|d��q>WdS)Nr)�	Rich_Rulecs�j|�|d�d|d�dS)N)�rule_strr)r�r�)�add_rule)r/r�r�r�)r�rrr�add_rule_wrapperhszDFirewallZone.set_config_with_settings_dict.<locals>.add_rule_wrappercs�j|�|d��dS)N)r�)�remove_rule)r/r�)r�rrr�remove_rule_wrapperjszGFirewallZone.set_config_with_settings_dict.<locals>.remove_rule_wrapper)r?r@rDrArBr1r7r�rFrCrXrYror1r7)r�)r�r�rX)rN)r1r7)rX)�firewall.core.richr��add_service�remove_service�add_port�remove_port�add_icmp_block�remove_icmp_block�add_masquerade�remove_masquerade�add_forward_port�remove_forward_portr_�remove_interfacer`�
remove_source�add_protocol�remove_protocol�add_source_port�remove_source_portrb�remove_icmp_block_inversionra�remove_forwardr�rZget_added_and_removed_settings�
isinstance�listr�)rr/r3r�r�r�Z
setting_to_fnZold_settingsZadd_settingsZremove_settingsr�r�r)r�rr�set_config_with_settings_dictesF













  
z*FirewallZone.set_config_with_settings_dictcCs|jj|�dS)N)r�check_interface)rr4rrrr��szFirewallZone.check_interfacecCs\|jj|�}|j|}|j|�}||jdkrX|jd|}d|krX|ddk	rX|dSdS)Nr1r�)rr<rr2r3)rr/r4r��_objr5r3rrr�interface_get_sender�s

z!FirewallZone.interface_get_sendercCs|j|�|S)N)r�)rr4rrrZ__interface_id�s
zFirewallZone.__interface_idTc
Cs|jj�|jj|�}|j|}|j|�}||jdkrLttjd||f��|j	|�dk	rjttj
d|��tjd||f�|dkr�|j
�}	n|}	|jr�|r�|j||	d�|	j|j|d�|r�|jd|||	�|j||||�|	j|j||�|dk�r|	jd�|S)Nr1z'%s' already bound to '%s'z'%s' already bound to a zonez&Setting zone of interface '%s' to '%s')rgFT)r�check_panicr<rr2r3rr�ZONE_ALREADY_SETr6�
ZONE_CONFLICTrrir$rdrj�add_failrlr��!_FirewallZone__register_interface�#_FirewallZone__unregister_interfacer�)
rr/r4r�rgr^r�r�r5r�rrrr_�s8









zFirewallZone.add_interfacecCs6|jd|�|jd|<|p"|dk|jd|d<dS)Nrr1��__default__)�_FirewallZone__gen_settingsr3)rr�r5r/r�rrrZ__register_interface�sz!FirewallZone.__register_interfacecCsR|jj�|j|�}|jj|�}||kr,|S|dk	r@|j||�|j|||�}|S)N)rr�r6r<r�r_)rr/r4r��	_old_zone�	_new_zoner�rrr�change_zone_of_interface�s

z%FirewallZone.change_zone_of_interfacecCsz|jj�|dkr|j�}n|}|j||�|jd|d|dd�|dk	rd|dkrd|jd|d|dd�|dkrv|jd�dS)NT�+)r.r�F)rr�r$rjr�r�)rZold_zoneZnew_zonergr�rrr�change_default_zone�s

z FirewallZone.change_default_zonec	Cs�|jj�|j|�}|dkr,ttjd|��|dkr8|n
|jj|�}||krbttjd|||f��|dkrt|j�}n|}|j	|}|j
|�}|j|j||�|j
d|||�|dkr�|jd�|S)Nz'%s' is not in any zoner�z"remove_interface(%s, %s): zoi='%s'FT)rr�r6rrZUNKNOWN_INTERFACEr<r�r$rr2�add_postr�r�r�)	rr/r4rgZzoir�r�r�r5rrrr��s(






zFirewallZone.remove_interfacecCs||jdkr|jd|=dS)Nr1)r3)rr�r5rrrZ__unregister_interfacesz#FirewallZone.__unregister_interfacecCs|j|�|j|�dkS)Nr1)r2r�)rr/r4rrr�query_interfaceszFirewallZone.query_interfacecCs|j|�dj�S)Nr1)r�r*)rr/rrrr,"szFirewallZone.list_interfacesFcCsxt|�rdSt|�rdSt|�r$dS|jd�rh|j|dd��|rV|j|dd��|j|dd��Sttj	|��dS)Nrr�r�zipset:�)
rrr�
startswith�_check_ipset_type_for_source�_check_ipset_applied�
_ipset_familyrrZINVALID_ADDR)rr9rdrrr�check_source's
zFirewallZone.check_sourcecCs|j||d�}||fS)N)rd)r�)rr9rdr�rrrZ__source_id6szFirewallZone.__source_idc
Cs|jj�|jj|�}|j|}t|�r0|j�}|j||d�}||jdkr`tt	j
d||f��|j|�dk	r~tt	jd|��|dkr�|j
�}	n|}	|jr�|r�|j||	d�|	j|j|d�|r�|jd||d|d	|	�|j||||�|	j|j||�|dk�r|	jd�|S)
N)rdr7z'%s' already bound to '%s'z'%s' already bound to a zone)rgFTrro)rr�r<rr�upperr8r3rrr�r;r�r$rdrjr�rlr��_FirewallZone__register_source� _FirewallZone__unregister_sourcer�)
rr/r9r�rgr^r�r�r:r�rrrr`:s4





zFirewallZone.add_sourcecCs6|jd|�|jd|<|p"|dk|jd|d<dS)Nrr7r�r�)r�r3)rr�r:r/r�rrrZ__register_sourceaszFirewallZone.__register_sourcecCsb|jj�|j|�}|jj|�}||kr,|St|�r<|j�}|dk	rP|j||�|j|||�}|S)N)rr�r;r<rr�r�r`)rr/r9r�r�r�r�rrr�change_zone_of_sourcegs

z"FirewallZone.change_zone_of_sourcec	Cs�|jj�t|�r|j�}|j|�}|dkr<ttjd|��|dkrH|n
|jj|�}||krrttj	d|||f��|dkr�|j
�}n|}|j|}|j|�}|j
|j||�|jd||d|d|�|dkr�|jd�|S)Nz'%s' is not in any zoner�zremove_source(%s, %s): zos='%s'FrroT)rr�rr�r;rrZUNKNOWN_SOURCEr<r�r$rr8r�r�r�r�)	rr/r9rgZzosr�r�r�r:rrrr�ys,






zFirewallZone.remove_sourcecCs||jdkr|jd|=dS)Nr7)r3)rr�r:rrrZ__unregister_source�sz FirewallZone.__unregister_sourcecCs(t|�r|j�}|j|�|j|�dkS)Nr7)rr�r8r�)rr/r9rrr�query_source�szFirewallZone.query_sourcecCsdd�|j|�dj�D�S)NcSsg|]}|d�qS)ror)rU�krrr�
<listcomp>�sz-FirewallZone.list_sources.<locals>.<listcomp>r7)r�r*)rr/rrrr-�szFirewallZone.list_sourcescs�x��jj�D]�}|jsqxP�j|D]B}x<�jjj|�D]*\}}	|j||||||	|�}
|j||
�q8Wq$W�j|d�}�j	|�dr|d
kr|j
|||d|d�}
|j||
�qWxΈjjj�D]�}|�jjj|�kr�|�jjj
|�kr�q�|�jjj�k�rd�jjj|�j�rd|�r<t�j|��dk�r<�jjj||d�n&�jjjd	||�|j�fd
d�|�q�|r�|j�fdd�|�q�WdS)NrHrYr��*�filter)r4ro)rgFcs |�jjj�ko�jjjd|�S)NT)rrZ�)get_active_policies_not_derived_from_zone�!_ingress_egress_zones_transaction)�p)rrr�<lambda>�sz)FirewallZone._interface.<locals>.<lambda>cs|�jjj�ko�jjj|�S)N)rrZr�r�)r�)rrrr��s)r�r�)r�enabled_backends�policies_supportedrrZ�#_get_table_chains_for_zone_dispatchZ!build_zone_source_interface_rules�	add_rulesr(r��build_zone_forward_rules�"get_policies_not_derived_from_zone�list_ingress_zones�list_egress_zonesr��
get_policyrdrhr,r��_ingress_egress_zonesr�)rr�r/r4r�r.�backendrZr�rvrEr)rrr��s2$zFirewallZone._interfacecCs$|j|�dkrdS|jjj|dd�S)Nzhash:macF)rd)�_ipset_typer�ipsetZ
get_family)rrIrrrr��szFirewallZone._ipset_familycCs|jjj|dd�S)NF)rd)rr�Zget_type)rrIrrrr��szFirewallZone._ipset_typecCsdj|g|jjj|��S)N�,)�joinrr�Z
get_dimension)rrI�flagrrr�_ipset_match_flags�szFirewallZone._ipset_match_flagscCs|jjj|�S)N)rr�Z
check_applied)rrIrrrr��sz!FirewallZone._check_ipset_appliedcCs*|j|�}|tkr&ttjd||f��dS)Nz.ipset '%s' with type '%s' not usable as source)r�rrrZ
INVALID_IPSET)rrIZ_typerrrr��s
z)FirewallZone._check_ipset_type_for_sourcec
s�x�|r�jj|�gn�jj�D]�}|js*qxN�j|D]@}x:�jjj|�D](\}}	|j||||||	�}
|j||
�qJWq6W�j	|d�}�j
|�dr|j|||d|d�}
|j||
�qWxΈjjj�D]�}|�jjj
|�kr�|�jjj|�kr�q�|�jjj�k�rl�jjj|�j�rl|�rDt�j|��dk�rD�jjj||d�n&�jjjd||�|j�fdd	�|�q�|r�|j�fd
d	�|�q�WdS)NrHrYr�)r9ro)rgFcs |�jjj�ko�jjjd|�S)NT)rrZr�r�)r�)rrrr�sz&FirewallZone._source.<locals>.<lambda>cs|�jjj�ko�jjj|�S)N)rrZr�r�)r�)rrrr�
s)r�get_backend_by_ipvr�r�rrZr�Zbuild_zone_source_address_rulesr�r(r�r�r�r�r�r�r�rdrhr-r�r�r�)rr�r/r�r9r�r�rZr�rvrEr)rrr��s2"$zFirewallZone._sourcecCs0|jj|�}|j|d�}|jjj||||�|S)NrG)rr<r(rZr�)rr/�servicer�r��p_namerrrr�
szFirewallZone.add_servicecCs,|jj|�}|j|d�}|jjj||�|S)NrG)rr<r(rZr�)rr/r�r�rrrr�szFirewallZone.remove_servicecCs(|jj|�}|j|d�}|jjj||�S)NrG)rr<r(rZ�
query_service)rr/r�r�rrrr�szFirewallZone.query_servicecCs&|jj|�}|j|d�}|jjj|�S)NrG)rr<r(rZr�)rr/r�rrrr�szFirewallZone.list_servicescCs2|jj|�}|j|d�}|jjj|||||�|S)NrG)rr<r(rZr�)rr/�port�protocolr�r�r�rrrr�#szFirewallZone.add_portcCs.|jj|�}|j|d�}|jjj|||�|S)NrG)rr<r(rZr�)rr/r�r�r�rrrr�)szFirewallZone.remove_portcCs*|jj|�}|j|d�}|jjj|||�S)NrG)rr<r(rZ�
query_port)rr/r�r�r�rrrr/szFirewallZone.query_portcCs&|jj|�}|j|d�}|jjj|�S)NrG)rr<r(rZr�)rr/r�rrrr�4szFirewallZone.list_portscCs2|jj|�}|j|d�}|jjj|||||�|S)NrG)rr<r(rZr�)rr/�source_portr�r�r�r�rrrr�9szFirewallZone.add_source_portcCs.|jj|�}|j|d�}|jjj|||�|S)NrG)rr<r(rZr�)rr/rr�r�rrrr�?szFirewallZone.remove_source_portcCs*|jj|�}|j|d�}|jjj|||�S)NrG)rr<r(rZ�query_source_port)rr/rr�r�rrrrEszFirewallZone.query_source_portcCs&|jj|�}|j|d�}|jjj|�S)NrG)rr<r(rZr�)rr/r�rrrr�JszFirewallZone.list_source_portscCs�|jj|�}t|j�tkr(|j|d�gSt|j�ttt	t
gkrL|j|d�gSt|j�ttgkrv|j|d�|j|d�gSt|j�t
gkr�|j|d�gSt|j�tgkr�|jd|�gS|jdkr�|j|d�gStdt|j���dS)NrHrGz Rich rule type (%s) not handled.)rr<�type�actionrr(�elementrr	r
rr
rrrr)rr/rSrrrrPOs 

z#FirewallZone._rich_rule_to_policiescCs.x(|j||�D]}|jjj||||�qW|S)N)rPrrZr�)rr/rSr�r�r�rrrr�bszFirewallZone.add_rulecCs*x$|j||�D]}|jjj||�qW|S)N)rPrrZr�)rr/rSr�rrrr�gszFirewallZone.remove_rulecCs2d}x(|j||�D]}|o(|jjj||�}qW|S)NT)rPrrZ�
query_rule)rr/rSr�r�rrrrlszFirewallZone.query_rulecCs^|jj|�}t�}xB|j|d�|j|d�|jd|�gD]}|jt|jjj|���q6Wt|�S)NrHrG)rr<�setr(�updaterZr�r�)rr/r�r�rrrr�rs
zFirewallZone.list_rulescCs0|jj|�}|j|d�}|jjj||||�|S)NrG)rr<r(rZr�)rr/r�r�r�r�rrrr�{szFirewallZone.add_protocolcCs,|jj|�}|j|d�}|jjj||�|S)NrG)rr<r(rZr�)rr/r�r�rrrr��szFirewallZone.remove_protocolcCs(|jj|�}|j|d�}|jjj||�S)NrG)rr<r(rZ�query_protocol)rr/r�r�rrrr	�szFirewallZone.query_protocolcCs&|jj|�}|j|d�}|jjj|�S)NrG)rr<r(rZr�)rr/r�rrrr��szFirewallZone.list_protocolscCs.|jj|�}|jd|�}|jjj|||�|S)NrH)rr<r(rZr�)rr/r�r�r�rrrr��szFirewallZone.add_masqueradecCs*|jj|�}|jd|�}|jjj|�|S)NrH)rr<r(rZr�)rr/r�rrrr��szFirewallZone.remove_masqueradecCs&|jj|�}|jd|�}|jjj|�S)NrH)rr<r(rZr�)rr/r�rrrr��szFirewallZone.query_masqueradec	Cs6|jj|�}|j|d�}|jjj|||||||�|S)NrH)rr<r(rZr�)	rr/r�r��toport�toaddrr�r�r�rrrr��s
zFirewallZone.add_forward_portcCs2|jj|�}|j|d�}|jjj|||||�|S)NrH)rr<r(rZr�)rr/r�r�r
rr�rrrr��sz FirewallZone.remove_forward_portcCs.|jj|�}|j|d�}|jjj|||||�S)NrH)rr<r(rZ�query_forward_port)rr/r�r�r
rr�rrrr�szFirewallZone.query_forward_portcCs&|jj|�}|j|d�}|jjj|�S)NrH)rr<r(rZr�)rr/r�rrrr��szFirewallZone.list_forward_portscCsP|jj|�}|j|d�}|jjj||||�|j|d�}|jjj||||�|S)NrGrH)rr<r(rZr�)rr/�icmpr�r�r�rrrr��szFirewallZone.add_icmp_blockcCsH|jj|�}|j|d�}|jjj||�|j|d�}|jjj||�|S)NrGrH)rr<r(rZr�)rr/r
r�rrrr��szFirewallZone.remove_icmp_blockcCsD|jj|�}|j|d�}|j|d�}|jjj||�oB|jjj||�S)NrGrH)rr<r(rZ�query_icmp_block)rr/r
�p_name_host�
p_name_fwdrrrr�s
zFirewallZone.query_icmp_blockcCsH|jj|�}|j|d�}|j|d�}tt|jjj|�|jjj|���S)NrGrH)rr<r(r)rrZr�)rr/rrrrrr��s
zFirewallZone.list_icmp_blockscCsH|jj|�}|j|d�}|jjj||�|j|d�}|jjj||�|S)NrGrH)rr<r(rZrb)rr/r�r�rrrrb�sz%FirewallZone.add_icmp_block_inversioncCsL|jj|�}|j|d�}|jjj|||�|j|d�}|jjj|||�dS)NrGrH)rr<r(rZr�)rr�r/r�r�rrrr��s
z"FirewallZone._icmp_block_inversioncCsD|jj|�}|j|d�}|jjj|�|j|d�}|jjj|�|S)NrGrH)rr<r(rZr�)rr/r�rrrr��sz(FirewallZone.remove_icmp_block_inversioncCs@|jj|�}|j|d�}|j|d�}|jjj|�o>|jjj|�S)NrGrH)rr<r(rZr�)rr/rrrrrr��s
z'FirewallZone.query_icmp_block_inversionc
	Cs�|j|d�}xT|j|jdD]@}x:|jj�D],}|js:q.|j|||d|d�}|j||�q.WqWxj|j|jdD]V\}}	xL|r�|jj|�gn|jj�D],}|js�q�|j|||d|	d�}|j||�q�WqtWdS)NrHr1r�)r4r7)r9)	r(rr3rr�r�r�r�r�)
rr�r/r�r�r4r�rEr�r9rrr�_forward�s"zFirewallZone._forwardcCsdS)NTr)rrrrZ__forward_idszFirewallZone.__forward_idc	Cs�|jj|�}|jj|�|jj�|j|}|j�}||jdkrRttj	d|��|dkrd|j
�}n|}|jr||jd||�|j
||||�|j|j||�|dkr�|jd�|S)NrYzforward already enabled in '%s'T)rr<Z
check_timeoutr�r�_FirewallZone__forward_idr3rrZALREADY_ENABLEDr$rdr�_FirewallZone__register_forwardr��!_FirewallZone__unregister_forwardr�)	rr/r�r�rgr�r��
forward_idr�rrrras$




zFirewallZone.add_forwardcCs|j||�|jd|<dS)NrY)r�r3)rr�rr�r�rrrZ__register_forward.szFirewallZone.__register_forwardcCs�|jj|�}|jj�|j|}|j�}||jdkrFttjd|��|dkrX|j	�}n|}|j
rp|jd||�|j|j
||�|dkr�|jd�|S)NrYzforward not enabled in '%s'FT)rr<r�rrr3rrZNOT_ENABLEDr$rdrr�rr�)rr/rgr�r�rr�rrrr�2s 




zFirewallZone.remove_forwardcCs||jdkr|jd|=dS)NrY)r3)rr�rrrrZ__unregister_forwardKsz!FirewallZone.__unregister_forwardcCs|j�|j|�dkS)NrY)rr�)rr/rrrr�OszFirewallZone.query_forward)N)N)N)N)NNT)N)N)N)F)F)NNT)N)N)F)rN)rN)rN)rN)rN)rN)NNrN)NN)NN)rN)N)rNN)N)e�__name__�
__module__�__qualname__rJrr!r#r$r(r+r0r6r;r>rTr]r[rfrkrlrxr~r�r�r�r�rjrer�r�r�r�r�r2r_r�r�r�r�r�r�r,r�r8r`r�r�r�r�r�r-r�r�r�r�r�r�r�r�r�r�r�r�r�rr�r�r�rr�rPr�r�rr�r�r�r	r�r�r�r�r�r�rr�r�r�rr�rbr�r�r�rrrarr�rr�rrrrr#s�&



8
(





&


,(



	





		
		

r)"r�rMZfirewall.core.baserrrZfirewall.core.fw_transactionrZfirewall.core.io.policyrZfirewall.core.loggerrr�rr	r
rrr
rrrZfirewall.functionsrrrZfirewallrZfirewall.errorsrZfirewall.fw_typesr�objectrrrrr�<module>s,core/__pycache__/ebtables.cpython-36.pyc000064400000016336150351351730014127 0ustar003

��g�$�@s&dgZddlZddlmZddlmZddlmZm	Z	m
Z
ddlmZddl
mZddlmZmZddlZd	gd
ddgd
ddgd�ZiZiZiZx�ej�D]tZgee<e�ee<x\eeD]PZeejde�eejdeef�eejde�eejde�q�Wq�WGdd�de�ZdS)�ebtables�N)�runProg)�log)�tempFile�readfile�	splitArgs)�COMMANDS)�	ipXtables)�
FirewallError�INVALID_IPVZBROUTINGZ
PREROUTINGZPOSTROUTINGZOUTPUTZINPUTZFORWARD)ZbrouteZnat�filterz-N %s_directz-I %s 1 -j %s_directz-I %s_direct 1 -j RETURNz	%s_directc@s�eZdZdZdZdZdd�Zdd�Zdd�Zd	d
�Z	dd�Z
d
d�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zd/d d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd0d+d,�Zd-d.�ZdS)1rZebFcCsBt|j|_td|j|_|j�|_|j�|_|j�g|_	dS)Nz
%s-restore)
r�ipv�_command�_restore_command�_detect_restore_noflush_optionZrestore_noflush_option�_detect_concurrent_option�concurrent_option�fill_exists�available_tables)�self�r�/usr/lib/python3.6/ebtables.py�__init__9s

zebtables.__init__cCs$tjj|j�|_tjj|j�|_dS)N)�os�path�existsrZcommand_existsrZrestore_command_exists)rrrrrAszebtables.fill_existscCs(d}t|jddg�}|ddkr$d}|S)N�z--concurrentz-Lr)rr)rr�retrrrrEs
z"ebtables._detect_concurrent_optioncCs.g}y|j|d�Wntk
r(dSXdS)N�offFT)�	set_rules�
ValueError)r�rulesrrrrOsz'ebtables._detect_restore_noflush_optioncCs�g}|jr |j|kr |j|j�|dd�|D�7}tjd|j|jdj|��t|j|�\}}|dkr~td|jdj|�|f��|S)NcSsg|]}d|�qS)z%sr)�.0�itemrrr�
<listcomp>^sz"ebtables.__run.<locals>.<listcomp>z	%s: %s %s� rz'%s %s' failed: %s)	r�appendr�debug2�	__class__r�joinrr )r�argsZ_args�statusrrrrZ__runYszebtables.__runcCs(x"dD]}||krttd|��qWdS)N�
%%REJECT%%�%%ICMP%%�%%LOGTYPE%%z'%s' invalid for ebtables)r,r-r.)r
r)r�rule�strrrr�_rule_validatefs
zebtables._rule_validatecCs|tko|t|kS)N)�BUILT_IN_CHAINS)rr
�table�chainrrr�is_chain_builtinlszebtables.is_chain_builtincCsJg}|r4|jd|d|g�|jd|d|dddg�n|jd|d|g�|S)Nz-tz-Nz-I�1z-jZRETURNz-X)r&)r�addr3r4r!rrr�build_chain_rulespszebtables.build_chain_rulescCs8d|g}|r |d|t|�g7}n|d|g7}||7}|S)Nz-tz-Iz-D)r0)rr7r3r4�indexr*r/rrr�
build_rule{szebtables.build_rulecCs
tj|�S)N)r	Zcommon_reverse_rule)rr*rrr�reverse_rule�szebtables.reverse_rulecCstj|�dS)N)r	Zcommon_check_passthrough)rr*rrr�check_passthrough�szebtables.check_passthroughcCs
tj|�S)N)r	Zcommon_reverse_passthrough)rr*rrr�reverse_passthrough�szebtables.reverse_passthroughc
Cs<t�}d}i}x�|D]�}|dd�}|j|�xTdD]L}y|j|�}	Wntk
rZYq4Xt|�|	dkr4|j|	�|j|	�}q4Wx^tt|��D]N}	xHtjD]>}
|
||	kr�||	j	d�o�||	j
d�r�d||	||	<q�Wq�W|j|g�j|�qWxD|D]<}|j
d|�x&||D]}|j
dj|�d	��qW�qW|j�tj|j�}tjd
|j|jd|j|jf�g}|jd�t|j||jd
�\}
}tj�dk�rt|j�}|dk	�rd}	xH|D]@}tjd|	|fddd�|j
d	��s�tjddd�|	d7}	�q�Wtj|j�|
dk�r8td|jdj|�|f��dS)Nr�-t�--table��"z"%s"z*%s
r%�
z	%s: %s %sz%s: %dz	--noflush)�stdin�z%8d: %sr)�nofmt�nlr)rEz'%s %s' failed: %s)r>r?)rr1r9r �len�pop�range�stringZ
whitespace�
startswith�endswith�
setdefaultr&�writer)�closer�stat�namerr'r(r�st_sizerZgetDebugLogLevelrZdebug3�unlink)rr!�
log_deniedZ	temp_filer3Ztable_rulesZ_ruler/�opt�i�crPr*r+r�lines�linerrrr�sZ




 




zebtables.set_rulescCs|j|�|j|�S)N)r1�_ebtables__run)rr/rTrrr�set_rule�s
zebtables.set_ruleNcCs�g}|r|gntj�}xp|D]h}||jkr6|j|�qy*|jd|dg�|jj|�|j|�Wqtk
r�tjd|�YqXqW|S)Nz-tz-Lz#ebtables table '%s' does not exist.)r2�keysrr&rZr rZdebug1)rr3rZtablesrrr�get_available_tables�s

zebtables.get_available_tablescCsiS)Nr)rr3rrr�get_zone_table_chains�szebtables.get_zone_table_chainscCsFg}x<tj�D]0}||j�kr qxdD]}|jd||g�q&WqW|S)N�-F�-X�-Zz-t)r_r`ra)r2r\r]r&)rr!r3�flagrrr�build_flush_rules�s
zebtables.build_flush_rulescCs^g}|dkrdn|}xDtj�D]8}||j�kr0qx$t|D]}|jd|d||g�q:WqW|S)NZPANICZDROPz-tz-P)r2r\r]r&)rZpolicyr!Z_policyr3r4rrr�build_set_policy_rules�szebtables.build_set_policy_rulescCsgS)Nr)rrrr�build_default_tables�szebtables.build_default_tablesrcCs�g}x�tD]�}||j�krq
t|dd�}|dkrJ|tkrJ|jt|�d|g}x:|D]2}t|�tkrx|j||�qX|j|t|��qXWq
W|S)Nrz-t)�
DEFAULT_RULESr]�	LOG_RULES�extend�type�listr&r)rrTZ
default_rulesr3Z_default_rules�prefixr/rrr�build_default_rules�s

zebtables.build_default_rulescCs
||jkS)N)r
)rr
rrr�is_ipv_supportedszebtables.is_ipv_supported)N)r)�__name__�
__module__�__qualname__r
rQZpolicies_supportedrrrrrZr1r5r8r:r;r<r=rr[r]r^rcrdrerlrmrrrrr4s0


	@


)�__all__Zos.pathrZfirewall.core.progrZfirewall.core.loggerrZfirewall.functionsrrrZfirewall.configrZ
firewall.corer	Zfirewall.errorsr
rrJr2rfrgZ
OUR_CHAINSr\r3�setr4r&r7�objectrrrrr�<module>s.
core/__pycache__/fw_policy.cpython-36.opt-1.pyc000064400000154111150351351730015272 0ustar003

��g=V�@s�ddlZddlZddlmZddlmZmZmZmZm	Z	m
Z
mZmZm
Z
mZddlmZmZmZmZmZmZmZmZmZmZmZddlmZddlmZddlm Z ddl!m"Z"dd	l#m$Z$Gd
d�de%�Z&dS)�N)�log)
�portStr�checkIPnMask�
checkIP6nMask�
checkProtocol�enable_ip_forwarding�check_single_address�portInPortRange�get_nf_conntrack_short_name�coalescePortRange�breakPortRange)�	Rich_Rule�Rich_Accept�Rich_Service�	Rich_Port�
Rich_Protocol�Rich_Masquerade�Rich_ForwardPort�Rich_SourcePort�Rich_IcmpBlock�
Rich_IcmpType�	Rich_Mark)�FirewallTransaction)�errors)�
FirewallError)�LastUpdatedOrderedDict)�SOURCE_IPSET_TYPESc@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
�ddd�Zdd�Zdd�Zdd�Z�dd d!�Z�d
d"d#�Z�dd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Z�dd0d1�Zd2d3�Z�dd4d5�Zd6d7�Zd8d9�Zd:d;�Zd<d=�Zd>d?�Z �dd@dA�Z!dBdC�Z"�ddDdE�Z#dFdG�Z$dHdI�Z%dJdK�Z&dLdM�Z'dNdO�Z(dPdQ�Z)dRdS�Z*�ddTdU�Z+dVdW�Z,�ddXdY�Z-dZd[�Z.d\d]�Z/d^d_�Z0d`da�Z1dbdc�Z2�dddde�Z3dfdg�Z4�ddhdi�Z5djdk�Z6dldm�Z7dndo�Z8dpdq�Z9drds�Z:dtdu�Z;dvdw�Z<�ddxdy�Z=dzd{�Z>�dd|d}�Z?d~d�Z@d�d��ZAd�d��ZBd�d��ZCd�d��ZD�dd�d��ZEd�d��ZF�dd�d��ZGd�d��ZHd�d��ZId�d��ZJd�d��ZK�dd�d��ZLd�d��ZM�dd�d��ZNd�d��ZOd�d��ZPd�d��ZQd�d��ZR�dd�d��ZSd�d��ZT�dd�d��ZUd�d��ZVd�d��ZW�dd�d��ZX�d d�d��ZY�d!d�d��ZZd�d��Z[�d"d�d��Z\d�d��Z]�d#d�d��Z^d�d��Z_d�d��Z`d�d��Za�d$d�dÄZbd�dńZc�d%d�dDŽZdd�dɄZed�d˄Zfd�d̈́Zgd�dτZh�d&d�dфZid�dӄZjd�dՄZk�d'd�dׄZld�dلZmd�dۄZnd�d݄Zod�d߄Zpd�d�Zqd�d�Zrd�d�Zsd�d�Ztd�d�Zu�d(d�d�Zv�d)d�d�Zwd�d�Zxd�d�Zyd�d�Zzd�d��Z{�d*d�d��Z|d�d��Z}d�d��Z~d�d��Zd�d��Z��d�d�Z��d�d�Z��d�d�Z��d�d�Z��d+�d	�d
�Z�dS(,�FirewallPolicycCs||_i|_i|_dS)N)�_fw�_chains�	_policies)�self�fw�r#�/usr/lib/python3.6/fw_policy.py�__init__szFirewallPolicy.__init__cCsd|j|j|jfS)Nz
%s(%r, %r))�	__class__rr )r!r#r#r$�__repr__szFirewallPolicy.__repr__cCs|jj�|jj�dS)N)r�clearr )r!r#r#r$�cleanups
zFirewallPolicy.cleanupcCs
t|j�S)N)rr)r!r#r#r$�new_transaction$szFirewallPolicy.new_transactioncCst|jj��S)N)�sortedr �keys)r!r#r#r$�get_policies)szFirewallPolicy.get_policiescCs8g}x*|j�D]}|j|�}|js|j|�qWt|�S)N)r-�
get_policy�derived_from_zone�appendr+)r!Zpolicies�p�p_objr#r#r$�"get_policies_not_derived_from_zone,s
z1FirewallPolicy.get_policies_not_derived_from_zonecCs~g}xt|j�D]h}|j|�}t|d�t|jjj��tddg�B@rt|d�t|jjj��tddg�B@r|j|�qW|S)N�
ingress_zones�HOST�ANY�egress_zones)r3�get_settings�setr�zoneZget_active_zonesr0)r!Zactive_policies�policy�settingsr#r#r$�)get_active_policies_not_derived_from_zone4s
((z8FirewallPolicy.get_active_policies_not_derived_from_zonecCs|jj|�}|j|S)N)r�check_policyr )r!r;r1r#r#r$r.>szFirewallPolicy.get_policycCs,dd�dD�|_||j|j<|j|j�dS)NcSsi|]}t�|�qSr#)r)�.0�xr#r#r$�
<dictcomp>Csz-FirewallPolicy.add_policy.<locals>.<dictcomp>�services�ports�
masquerade�
forward_ports�source_ports�icmp_blocks�rules�	protocols�icmp_block_inversionr4r7)rBrCrDrErFrGrHrIrJr4r7)r<r �name�copy_permanent_to_runtime)r!�objr#r#r$�
add_policyBs
zFirewallPolicy.add_policycCs0|j|}|jr|j|�|jj�|j|=dS)N)r �applied�unapply_policy_settingsr<r()r!r;rMr#r#r$�
remove_policyNs



zFirewallPolicy.remove_policycCs�|j|}|jrdSx|jD]}|j||dd�qWx|jD]}|j||dd�q<Wx|jD]}|j||�q\Wx|jD]}|j	|f|��qxWx|j
D]}|j||�q�Wxf|jD]\}y|j
|f|��Wq�tk
�r}z$|jtjgkr�tj|�n|�WYdd}~Xq�Xq�Wx|jD]}|j||��qWxj|jD]`}y|j|f|��WnDtk
�r�}z&|jtjgk�r�tj|�n|�WYdd}~XnX�q:Wx|jD]}|j||��q�W|j�r�|j|�dS)NF)�allow_apply)r rOr4�add_ingress_zoner7�add_egress_zonerG�add_icmp_blockrE�add_forward_portrB�add_servicerC�add_portr�coder�ALREADY_ENABLEDr�warningrI�add_protocolrF�add_source_portrH�add_rulerD�add_masquerade)r!r;rM�args�errorr#r#r$rLUsB
z(FirewallPolicy.copy_permanent_to_runtimeNcCsNxH|j�D]<}|j|}|jr q
||j�kr
tjd|�|j||d�q
WdS)NzApplying policy '%s')�use_transaction)r-r r/r=rZdebug1�apply_policy_settings)r!rbr;r2r#r#r$�apply_policies|s
zFirewallPolicy.apply_policiescCs|j|}||_dS)N)r rO)r!r;rOrMr#r#r$�set_policy_applied�s
z!FirewallPolicy.set_policy_appliedcCstj�||d�}|S)N)Zdate�sender�timeout)�time)r!rgrf�retr#r#r$Z__gen_settings�szFirewallPolicy.__gen_settingscCs|j|�jS)N)r.r<)r!r;r#r#r$r8�szFirewallPolicy.get_settingscCsj|jj|�}|j|}|r |js.|r2|jr2dS|r<d|_|dkrN|j�}n|}|r�x8|jsh|j|�n|j|�D]\}}|j|d|||�qrW|j	|�}	|js�|j
|||��xV|	D�]L}
�xD|	|
D�]6}|
dkr�|j||||�q�|
dkr�q�q�|
dk�r|j|||f|��q�|
dk�r0|j
||||�q�|
dk�rV|j|||d|d|�q�|
d	k�rr|j||||�q�|
d
k�r�|j|||d|d|�q�|
dk�r�|j|||�q�|
dk�r�|j||t|d
�|�q�|
dk�r�q�q�|
dk�r�q�q�tjd||
|�q�Wq�W|�sRx<|j�s"|j|�n|j|�D]\}}|j|d|||��q,Wd|_|dk�rf|j|�dS)NTrGrJrErBrCr�rIrFrDrH)�rule_strr4r7z5Policy '%s': Unknown setting '%s:%s', unable to applyF)rr>r rOr*r/�%_get_table_chains_for_policy_dispatch�#_get_table_chains_for_zone_dispatch�gen_chain_rulesr8�_ingress_egress_zones�_icmp_block�
_forward_port�_service�_port�	_protocol�_source_port�_masquerade�_FirewallPolicy__ruler
rr[�execute)r!�enabler;rb�_policyrM�transaction�table�chainr<�keyr`r#r#r$�_policy_settings�sj













zFirewallPolicy._policy_settingscCs|jd||d�dS)NT)rb)r)r!r;rbr#r#r$rc�sz$FirewallPolicy.apply_policy_settingscCs|jd||d�dS)NF)rb)r)r!r;rbr#r#r$rP�sz&FirewallPolicy.unapply_policy_settingscCsr|j|�j�}|j|�|j|�|j|�|j|�|j|�|j|�|j|�|j	|�|j
|�|j|�d�
}|jj
||�S)zH
        :return: exported config updated with runtime settings
        )
rBrCrGrDrE�
rich_rulesrIrFr4r7)r.Zexport_config_dict�
list_services�
list_ports�list_icmp_blocks�query_masquerade�list_forward_ports�
list_rules�list_protocols�list_source_ports�list_ingress_zones�list_egress_zonesrZ'combine_runtime_with_permanent_settings)r!r;Z	permanentZruntimer#r#r$�get_config_with_settings_dict�sz,FirewallPolicy.get_config_with_settings_dictcs�ddlm�d
��fdd�	}��fdd�}�j�jf�j�jf�j�jf�j�j	f�j
�jf||f�j�j
f�j�jf�j�jf�j�jfd�
}�j|�}�jj||�\}}	xt|	D]l}
t|	|
t��rxV|	|
D]8}t|t�r�||
d|f|��q�||
d||�q�Wq�||
d|�q�Wx�|D]�}
t||
t��r�xn||
D]J}t|t��rv||
d|f|�d|d	��n||
d||d|d	��qFWn||
d|d|d	��q(WdS)Nr)r
cs�j|�|d�d|d�dS)N)rkr)rgrf)r^)r;rkrgrf)r
r!r#r$�add_rule_wrapper�szFFirewallPolicy.set_config_with_settings_dict.<locals>.add_rule_wrappercs�j|�|d��dS)N)rk)�remove_rule)r;rk)r
r!r#r$�remove_rule_wrapper�szIFirewallPolicy.set_config_with_settings_dict.<locals>.remove_rule_wrapper)
rBrCrGrDrEr�rIrFr4r7rj)rgrf)rN)�firewall.core.richr
rW�remove_servicerX�remove_portrU�remove_icmp_blockr_�remove_masqueraderV�remove_forward_portr\�remove_protocolr]�remove_source_portrS�remove_ingress_zonerT�remove_egress_zoner�rZget_added_and_removed_settings�
isinstance�list�tuple)r!r;r<rfr�r�Z
setting_to_fnZold_settingsZadd_settingsZremove_settingsr~r`r#)r
r!r$�set_config_with_settings_dict�s:











  z,FirewallPolicy.set_config_with_settings_dictcCs&|sttj��|dkr"|jj|�dS)Nr5r6)r5r6)rr�INVALID_ZONEr�
check_zone)r!r:r#r#r$�check_ingress_zones
z!FirewallPolicy.check_ingress_zonecCs|j|�|S)N)r�)r!r:r#r#r$Z__ingress_zone_id"s
z FirewallPolicy.__ingress_zone_idrTcCs�|jj|�}|jj|�|jj�|j|}|j|�}	|	|jdkrXttj	d||f��d|jdks�d|jdks�|dkr�|jdr�ttj
d��|dkr�d|jdkr�ttj
d��|dkr�|j�}
n|}
|�rJ|jr�|j
d||
�|j||	||�|
j|j||	�|j�s:||j�k�rH|j||
d	�|
j|j|d�n|j
d
||
�n |j||	||�|
j|j||	�|dk�r~|
jd
�dS)Nr4z'%s' already in '%s'r6r5zI'ingress-zones' may only contain one of: many regular zones, ANY, or HOSTr7zF'HOST' can only appear in either ingress or egress zones, but not bothF)rbT)r6r5)rr>�
check_timeout�check_panicr � _FirewallPolicy__ingress_zone_idr<rrrZr�r*rOro�&_FirewallPolicy__register_ingress_zone�add_fail�(_FirewallPolicy__unregister_ingress_zoner=rcrerx)r!r;r:rgrfrbrRrz�_obj�zone_idr{r#r#r$rS&s<




zFirewallPolicy.add_ingress_zonecCs|j||�|jd|<dS)Nr4)�_FirewallPolicy__gen_settingsr<)r!r�r�rgrfr#r#r$Z__register_ingress_zoneSsz&FirewallPolicy.__register_ingress_zonecCs�|jj|�}|jj�|j|}|j|�}||jdkrLttjd||f��|dkr^|j	�}n|}|j
r�t|jd�dkr�|j||�n|j
d||�|j||�|j|j||dd�||j�kr�|j
d||�n|j|j||�|dkr�|jd�|S)Nr4z'%s' not in '%s'rjFT)rr>r�r r�r<rr�NOT_ENABLEDr*rO�lenrPror�r�r�r=�add_postrx)r!r;r:rbrzr�r�r{r#r#r$r�Vs,




z"FirewallPolicy.remove_ingress_zonecCs||jdkr|jd|=dS)Nr4)r<)r!r�r�r#r#r$Z__unregister_ingress_zoneysz(FirewallPolicy.__unregister_ingress_zonecCs|j|�|j|�dkS)Nr4)r�r8)r!r;r:r#r#r$�query_ingress_zone}sz!FirewallPolicy.query_ingress_zonecCst|j|�dj��S)Nr4)r�r8r,)r!r;r#r#r$r��sz!FirewallPolicy.list_ingress_zonescCs&|sttj��|dkr"|jj|�dS)Nr5r6)r5r6)rrr�rr�)r!r:r#r#r$�check_egress_zone�s
z FirewallPolicy.check_egress_zonecCs|j|�|S)N)r�)r!r:r#r#r$Z__egress_zone_id�s
zFirewallPolicy.__egress_zone_idcCs�|jj|�}|jj|�|jj�|j|}|j|�}	|	|jdkrXttj	d||f��d|jdks�d|jdks�|dkr�|jdr�ttj
d��|dkr�d|jdkr�ttj
d��|dkr�|j�}
n|}
|�rJ|jr�|j
d||
�|j||	||�|
j|j||	�|j�s:||j�k�rH|j||
d	�|
j|j|d�n|j
d
||
�n |j||	||�|
j|j||	�|dk�r~|
jd
�dS)Nr7z'%s' already in '%s'r6r5zH'egress-zones' may only contain one of: many regular zones, ANY, or HOSTr4zF'HOST' can only appear in either ingress or egress zones, but not bothF)rbT)r6r5)rr>r�r�r �_FirewallPolicy__egress_zone_idr<rrrZr�r*rOro�%_FirewallPolicy__register_egress_zoner��'_FirewallPolicy__unregister_egress_zoner=rcrerx)r!r;r:rgrfrbrRrzr�r�r{r#r#r$rT�s<




zFirewallPolicy.add_egress_zonecCs|j||�|jd|<dS)Nr7)r�r<)r!r�r�rgrfr#r#r$Z__register_egress_zone�sz%FirewallPolicy.__register_egress_zonecCs�|jj|�}|jj�|j|}|j|�}||jdkrLttjd||f��|dkr^|j	�}n|}|j
r�t|jd�dkr�|j||�n|j
d||�|j||�|j|j||dd�||j�kr�|j
d||�n|j|j||�|dkr�|jd�|S)Nr7z'%s' not in '%s'rjFT)rr>r�r r�r<rrr�r*rOr�rPror�r�r�r=r�rx)r!r;r:rbrzr�r�r{r#r#r$r��s,




z!FirewallPolicy.remove_egress_zonecCs||jdkr|jd|=dS)Nr7)r<)r!r�r�r#r#r$Z__unregister_egress_zone�sz'FirewallPolicy.__unregister_egress_zonecCs|j|�|j|�dkS)Nr7)r�r8)r!r;r:r#r#r$�query_egress_zone�sz FirewallPolicy.query_egress_zonecCst|j|�dj��S)Nr7)r�r8r,)r!r;r#r#r$r��sz FirewallPolicy.list_egress_zonescCs|j�dS)N)Zcheck)r!�ruler#r#r$�
check_rule�szFirewallPolicy.check_rulecCs|j|�t|�S)N)r��str)r!r�r#r#r$Z	__rule_id�s
zFirewallPolicy.__rule_idcCsx|sdS|jr,t|j�rdSt|j�rtdSnHt|d�r@|jr@dSt|d�rt|jrt|j|j�|j|j�|j|j�SdS)N�ipv4�ipv6�mac��ipset)	Zaddrrr�hasattrr�r��_check_ipset_type_for_source�_check_ipset_applied�
_ipset_family)r!�sourcer#r#r$�_rule_source_ipv�s

zFirewallPolicy._rule_source_ipvcCs|j||||�dS)N)�
_rule_prepare)r!ryr;r�r{r#r#r$Z__ruleszFirewallPolicy.__rulecCsL|jj|�}|jj|�|jj�|j|}|j|�}||jdkrh|jrP|jn|}	tt	j
d||	f��|j�s�|jr�t|jt
�r�d|jdkr�tt	jd��d|jdkr�tt	jd��x6|jdD](}
|
dkr�q�|jjj|
�r�tt	jd	��q�W|j�r�t|jt��r�d|jdk�r,|jj�r�tt	jd
��nb|jd�r�|jj�sNtt	jd��x>|jdD]0}
|
dk�rl�qZ|jjj|
��rZtt	jd���qZW|j�r�t|jt��r�x>|jdD]0}
|
dk�rq�|jjj|
��r�tt	jd
���q�W|dk�r�|j�}n|}|j�r|jd|||�|j||||�|j|j||�|dk�rH|jd�|S)NrHz'%s' already in '%s'r5r7z.'masquerade' is invalid for egress zone 'HOST'r4z/'masquerade' is invalid for ingress zone 'HOST'r6zR'masquerade' cannot be used in a policy if an ingress zone has assigned interfaceszAA 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'zC'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zonezS'forward-port' cannot be used in a policy if an egress zone has assigned interfaceszR'mark' action cannot be used in a policy if an egress zone has assigned interfacesT)r6r5)rr>r�r�r �_FirewallPolicy__rule_idr<r/rrrZ�elementr�rr�r:�list_interfacesr�
to_address�INVALID_FORWARD�actionrr*rOrw�_FirewallPolicy__register_ruler�� _FirewallPolicy__unregister_rulerx)r!r;r�rgrfrbrzr��rule_id�_namer:r{r#r#r$r^
s`










zFirewallPolicy.add_rulecCs|j||�|jd|<dS)NrH)r�r<)r!r�r�rgrfr#r#r$Z__register_ruleEszFirewallPolicy.__register_rulec	Cs�|jj|�}|jj�|j|}|j|�}||jdkr\|jrD|jn|}ttj	d||f��|dkrn|j
�}n|}|jr�|jd|||�|j
|j||�|dkr�|jd�|S)NrHz'%s' not in '%s'FT)rr>r�r r�r<r/rrr�r*rOrwr�r�rx)	r!r;r�rbrzr�r�r�r{r#r#r$r�Is"




zFirewallPolicy.remove_rulecCs||jdkr|jd|=dS)NrH)r<)r!r�r�r#r#r$Z__unregister_ruledsz FirewallPolicy.__unregister_rulecCs|j|�|j|�dkS)NrH)r�r8)r!r;r�r#r#r$�
query_rulehszFirewallPolicy.query_rulecCst|j|�dj��S)NrH)r�r8r,)r!r;r#r#r$r�kszFirewallPolicy.list_rulescCs|jj|�dS)N)r�
check_service)r!�servicer#r#r$r�pszFirewallPolicy.check_servicecCs|j|�|S)N)r�)r!r�r#r#r$Z__service_idss
zFirewallPolicy.__service_idcCs�|jj|�}|jj|�|jj�|j|}|j|�}||jdkrh|jrP|jn|}	tt	j
d||	f��|dkrz|j�}
n|}
|jr�|j
d|||
�|j||||�|
j|j||�|dkr�|
jd�|S)NrBz'%s' already in '%s'T)rr>r�r�r �_FirewallPolicy__service_idr<r/rrrZr*rOrr�!_FirewallPolicy__register_servicer��#_FirewallPolicy__unregister_servicerx)r!r;r�rgrfrbrzr��
service_idr�r{r#r#r$rWws&




zFirewallPolicy.add_servicecCs|j||�|jd|<dS)NrB)r�r<)r!r�r�rgrfr#r#r$Z__register_service�sz!FirewallPolicy.__register_servicec	Cs�|jj|�}|jj�|j|}|j|�}||jdkr\|jrD|jn|}ttj	d||f��|dkrn|j
�}n|}|jr�|jd|||�|j
|j||�|dkr�|jd�|S)NrBz'%s' not in '%s'FT)rr>r�r r�r<r/rrr�r*rOrrr�r�rx)	r!r;r�rbrzr�r�r�r{r#r#r$r��s"




zFirewallPolicy.remove_servicecCs||jdkr|jd|=dS)NrB)r<)r!r�r�r#r#r$Z__unregister_service�sz#FirewallPolicy.__unregister_servicecCs|j|�|j|�dkS)NrB)r�r8)r!r;r�r#r#r$�
query_service�szFirewallPolicy.query_servicecCs|j|�dj�S)NrB)r8r,)r!r;r#r#r$r��szFirewallPolicy.list_servicescCsTg}xJ|D]B}y|jjj|�}Wn tk
r@ttj|��YnX|j|�q
W|S)N)r�helper�
get_helperrr�INVALID_HELPERr0)r!�helpers�_helpersr��_helperr#r#r$�get_helpers_for_service_helpers�s
z.FirewallPolicy.get_helpers_for_service_helperscCs�g}x�|D]�}y|jjj|�}Wn tk
r@ttj|��YnXt|j�dkr�t|j	�}y|jjj|�}|j
|�Wq�tk
r�|r�tjd|�w
Yq�Xq
|j
|�q
W|S)NrjzHelper '%s' is not available)
rr�r�rrr�r�rCr
�moduler0rr[)r!�modulesryr�r�r��_module_short_namer�r#r#r$�get_helpers_for_service_modules�s"


z.FirewallPolicy.get_helpers_for_service_modulescCs|jj|�|jj|�dS)N)r�
check_port�check_tcpudp)r!�port�protocolr#r#r$r��szFirewallPolicy.check_portcCs|j||�t|d�|fS)N�-)r�r)r!r�r�r#r#r$Z	__port_id�szFirewallPolicy.__port_idcs�|jj|�}|jj|�|jj�|j|}tt�fdd�|jd��}	x@|	D]8}
t||
d�rN|j	rl|j	n|}t
tjd|�|f��qNWt
|dd�|	D��\}}
|dkr�|j�}n|}|j�rx$|D]}|jd|t|d	��|�q�Wx$|
D]}|jd
|t|d	��|�q�Wx:|D]2}|j|��}
|j||
||�|j|j||
��qWx*|
D]"}|j|��}
|j|j||
��qNW|dk�r�|jd�|S)Ncs|d�kS)Nrjr#)r@)r�r#r$�<lambda>�sz)FirewallPolicy.add_port.<locals>.<lambda>rCrz'%s:%s' already in '%s'cSsg|]\}}|�qSr#r#)r?rsrtr#r#r$�
<listcomp>�sz+FirewallPolicy.add_port.<locals>.<listcomp>Tr�F)rr>r�r�r r��filterr<r	r/rrrZrr*rOrsr�_FirewallPolicy__port_id�_FirewallPolicy__register_portr�� _FirewallPolicy__unregister_portr�rx)r!r;r�r�rgrfrbrzr��existing_port_ids�port_idr��added_ranges�removed_rangesr{�ranger#)r�r$rX�s:









zFirewallPolicy.add_portcCs|j||�|jd|<dS)NrC)r�r<)r!r�r�rgrfr#r#r$Z__register_portszFirewallPolicy.__register_portcs�|jj|�}|jj�|j|}tt�fdd�|jd��}xB|D]}t||d�rBPqBW|jrf|jn|}	t	t
jd|�|	f��t|dd�|D��\}
}|dkr�|j
�}n|}|j�rx$|
D]}
|jd|t|
d	��|�q�Wx$|D]}
|jd
|t|
d	��|�q�Wx:|
D]2}
|j|
��}|j||dd�|j|j||��qWx*|D]"}
|j|
��}|j|j||��qDW|dk�r~|jd�|S)Ncs|d�kS)Nrjr#)r@)r�r#r$r�sz,FirewallPolicy.remove_port.<locals>.<lambda>rCrz'%s:%s' not in '%s'cSsg|]\}}|�qSr#r#)r?rsrtr#r#r$r�#sz.FirewallPolicy.remove_port.<locals>.<listcomp>Tr�F)rr>r�r r�r�r<r	r/rrr�rr*rOrsrr�r�r�r�r�rx)r!r;r�r�rbrzr�r�r�r�r�r�r{r�r#)r�r$r�s:









zFirewallPolicy.remove_portcCs||jdkr|jd|=dS)NrC)r<)r!r�r�r#r#r$Z__unregister_port=sz FirewallPolicy.__unregister_portcCs6x0|j|�dD]\}}t||�r||krdSqWdS)NrCTF)r8r	)r!r;r�r�rsrtr#r#r$�
query_portAszFirewallPolicy.query_portcCst|j|�dj��S)NrC)r�r8r,)r!r;r#r#r$r�HszFirewallPolicy.list_portscCst|�sttj|��dS)N)rrrZINVALID_PROTOCOL)r!r�r#r#r$�check_protocolMszFirewallPolicy.check_protocolcCs|j|�|S)N)r�)r!r�r#r#r$Z
__protocol_idQs
zFirewallPolicy.__protocol_idcCs�|jj|�}|jj|�|jj�|j|}|j|�}||jdkrh|jrP|jn|}	tt	j
d||	f��|dkrz|j�}
n|}
|jr�|j
d|||
�|j||||�|
j|j||�|dkr�|
jd�|S)NrIz'%s' already in '%s'T)rr>r�r�r �_FirewallPolicy__protocol_idr<r/rrrZr*rOrt�"_FirewallPolicy__register_protocolr��$_FirewallPolicy__unregister_protocolrx)r!r;r�rgrfrbrzr��protocol_idr�r{r#r#r$r\Us&




zFirewallPolicy.add_protocolcCs|j||�|jd|<dS)NrI)r�r<)r!r�r�rgrfr#r#r$Z__register_protocolrsz"FirewallPolicy.__register_protocolc	Cs�|jj|�}|jj�|j|}|j|�}||jdkr\|jrD|jn|}ttj	d||f��|dkrn|j
�}n|}|jr�|jd|||�|j
|j||�|dkr�|jd�|S)NrIz'%s' not in '%s'FT)rr>r�r r�r<r/rrr�r*rOrtr�r�rx)	r!r;r�rbrzr�r�r�r{r#r#r$r�vs$





zFirewallPolicy.remove_protocolcCs||jdkr|jd|=dS)NrI)r<)r!r�r�r#r#r$Z__unregister_protocol�sz$FirewallPolicy.__unregister_protocolcCs|j|�|j|�dkS)NrI)r�r8)r!r;r�r#r#r$�query_protocol�szFirewallPolicy.query_protocolcCst|j|�dj��S)NrI)r�r8r,)r!r;r#r#r$r��szFirewallPolicy.list_protocolscCs|j||�t|d�|fS)Nr�)r�r)r!r�r�r#r#r$Z__source_port_id�szFirewallPolicy.__source_port_idcs�|jj|�}|jj|�|jj�|j|}tt�fdd�|jd��}	x@|	D]8}
t||
d�rN|j	rl|j	n|}t
tjd|�|f��qNWt
|dd�|	D��\}}
|dkr�|j�}n|}|j�rx$|D]}|jd|t|d	��|�q�Wx$|
D]}|jd
|t|d	��|�q�Wx:|D]2}|j|��}
|j||
||�|j|j||
��qWx*|
D]"}|j|��}
|j|j||
��qNW|dk�r�|jd�|S)Ncs|d�kS)Nrjr#)r@)r�r#r$r��sz0FirewallPolicy.add_source_port.<locals>.<lambda>rFrz'%s:%s' already in '%s'cSsg|]\}}|�qSr#r#)r?rsrtr#r#r$r��sz2FirewallPolicy.add_source_port.<locals>.<listcomp>Tr�F)rr>r�r�r r�r�r<r	r/rrrZrr*rOrur�_FirewallPolicy__source_port_id�%_FirewallPolicy__register_source_portr��'_FirewallPolicy__unregister_source_portr�rx)r!r;r�r�rgrfrbrzr�r�r�r�r�r�r{r�r#)r�r$r]�s:









zFirewallPolicy.add_source_portcCs|j||�|jd|<dS)NrF)r�r<)r!r�r�rgrfr#r#r$Z__register_source_port�sz%FirewallPolicy.__register_source_portcs�|jj|�}|jj�|j|}tt�fdd�|jd��}xB|D]}t||d�rBPqBW|jrf|jn|}	t	t
jd|�|	f��t|dd�|D��\}
}|dkr�|j
�}n|}|j�rx$|
D]}
|jd|t|
d	��|�q�Wx$|D]}
|jd
|t|
d	��|�q�Wx:|
D]2}
|j|
��}|j||dd�|j|j||��qWx*|D]"}
|j|
��}|j|j||��qDW|dk�r~|jd�|S)Ncs|d�kS)Nrjr#)r@)r�r#r$r��sz3FirewallPolicy.remove_source_port.<locals>.<lambda>rFrz'%s:%s' not in '%s'cSsg|]\}}|�qSr#r#)r?rsrtr#r#r$r��sz5FirewallPolicy.remove_source_port.<locals>.<listcomp>Tr�F)rr>r�r r�r�r<r	r/rrr�rr*rOrurr�r�r�r�r�rx)r!r;r�r�rbrzr�r�r�r�r�r�r{r�r#)r�r$r��s:









z!FirewallPolicy.remove_source_portcCs||jdkr|jd|=dS)NrF)r<)r!r�r�r#r#r$Z__unregister_source_port�sz'FirewallPolicy.__unregister_source_portcCs6x0|j|�dD]\}}t||�r||krdSqWdS)NrFTF)r8r	)r!r;r�r�rsrtr#r#r$�query_source_port�sz FirewallPolicy.query_source_portcCst|j|�dj��S)NrF)r�r8r,)r!r;r#r#r$r�sz FirewallPolicy.list_source_portscCsdS)NTr#)r!r#r#r$Z__masquerade_idszFirewallPolicy.__masquerade_idcCs8|jj|�}|jj|�|jj�|j|}|j�}||jdkrb|jrN|jn|}tt	j
d|��|js�d|jdkr�tt	jd��d|jdkr�tt	jd��x6|jdD](}	|	dkr�q�|jjj
|	�r�tt	jd	��q�W|dkr�|j�}
n|}
|j�r|jd
||
�|j||||�|
j|j||�|dk�r4|
jd
�|S)NrDz"masquerade already enabled in '%s'r5r7z.'masquerade' is invalid for egress zone 'HOST'r4z/'masquerade' is invalid for ingress zone 'HOST'r6zR'masquerade' cannot be used in a policy if an ingress zone has assigned interfacesT)rr>r�r�r �_FirewallPolicy__masquerade_idr<r/rrrZr�r:r�r*rOrv�$_FirewallPolicy__register_masquerader��&_FirewallPolicy__unregister_masqueraderx)r!r;rgrfrbrzr��
masquerade_idr�r:r{r#r#r$r_
s:





zFirewallPolicy.add_masqueradecCs|j||�|jd|<dS)NrD)r�r<)r!r�r�rgrfr#r#r$Z__register_masquerade2sz$FirewallPolicy.__register_masqueradecCs�|jj|�}|jj�|j|}|j�}||jdkrV|jrB|jn|}ttj	d|��|dkrh|j
�}n|}|jr�|jd||�|j
|j||�|dkr�|jd�|S)NrDzmasquerade not enabled in '%s'FT)rr>r�r r�r<r/rrr�r*rOrvr�r�rx)r!r;rbrzr�r�r�r{r#r#r$r�6s"




z FirewallPolicy.remove_masqueradecCs||jdkr|jd|=dS)NrD)r<)r!r�r�r#r#r$Z__unregister_masqueradePsz&FirewallPolicy.__unregister_masqueradecCs|j�|j|�dkS)NrD)r�r8)r!r;r#r#r$r�TszFirewallPolicy.query_masqueradecCs^|jj|�|jj|�|r(|jj|�|rBt||�sBttj|��|rZ|rZttjd��dS)Nz.port-forwarding is missing to-port AND to-addr)rr�r�rrrZINVALID_ADDRr�)r!�ipvr�r��toport�toaddrr#r#r$�check_forward_portYs
z!FirewallPolicy.check_forward_portcCsLtd|�r|jd||||�n|jd||||�t|d�|t|d�t|�fS)Nr�r�r�)rrrr�)r!r�r�r�r�r#r#r$Z__forward_port_idfs


z FirewallPolicy.__forward_port_idc	CsZ|jj|�}	|jj|�|jj�|j|	}
|j||||�}||
jdkrt|
jrV|
jn|	}tt	j
d|||||f��|
js�d|
jdkr�|r�tt	jd��nR|
jdr�|s�tt	jd��x6|
jdD](}
|
dkr�q�|jjj
|
�r�tt	jd��q�W|dk�r|j�}n|}|
j�r"|jd	|	|||||�|j|
|||�|j|j|
|�|dk�rV|jd	�|	S)
NrEz'%s:%s:%s:%s' already in '%s'r5r7zAA 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'zC'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zoner6zS'forward-port' cannot be used in a policy if an egress zone has assigned interfacesT)rr>r�r�r � _FirewallPolicy__forward_port_idr<r/rrrZr�r:r�r�r*rOrq�&_FirewallPolicy__register_forward_portr��(_FirewallPolicy__unregister_forward_portrx)r!r;r�r�r�r�rgrfrbrzr��
forward_idr�r:r{r#r#r$rVnsB






zFirewallPolicy.add_forward_portcCs|j||�|jd|<dS)NrE)r�r<)r!r�rrgrfr#r#r$Z__register_forward_port�sz&FirewallPolicy.__register_forward_portcCs�|jj|�}|jj�|j|}|j||||�}	|	|jdkrh|jrJ|jn|}
ttj	d|||||
f��|dkrz|j
�}n|}|jr�|jd||||||�|j
|j||	�|dkr�|jd�|S)NrEz'%s:%s:%s:%s' not in '%s'FT)rr>r�r rr<r/rrr�r*rOrqr�rrx)r!r;r�r�r�r�rbrzr�rr�r{r#r#r$r��s&



z"FirewallPolicy.remove_forward_portcCs||jdkr|jd|=dS)NrE)r<)r!r�rr#r#r$Z__unregister_forward_port�sz(FirewallPolicy.__unregister_forward_portcCs"|j||||�}||j|�dkS)NrE)rr8)r!r;r�r�r�r�rr#r#r$�query_forward_port�sz!FirewallPolicy.query_forward_portcCst|j|�dj��S)NrE)r�r8r,)r!r;r#r#r$r��sz!FirewallPolicy.list_forward_portscCs|jj|�dS)N)rZcheck_icmptype)r!�icmpr#r#r$�check_icmp_block�szFirewallPolicy.check_icmp_blockcCs|j|�|S)N)r)r!rr#r#r$Z__icmp_block_id�s
zFirewallPolicy.__icmp_block_idcCs�|jj|�}|jj|�|jj�|j|}|j|�}||jdkrh|jrP|jn|}	tt	j
d||	f��|dkrz|j�}
n|}
|jr�|j
d|||
�|j||||�|
j|j||�|dkr�|
jd�|S)NrGz'%s' already in '%s'T)rr>r�r�r �_FirewallPolicy__icmp_block_idr<r/rrrZr*rOrp�$_FirewallPolicy__register_icmp_blockr��&_FirewallPolicy__unregister_icmp_blockrx)r!r;rrgrfrbrzr��icmp_idr�r{r#r#r$rU�s&




zFirewallPolicy.add_icmp_blockcCs|j||�|jd|<dS)NrG)r�r<)r!r�rrgrfr#r#r$Z__register_icmp_block�sz$FirewallPolicy.__register_icmp_blockc	Cs�|jj|�}|jj�|j|}|j|�}||jdkr\|jrD|jn|}ttj	d||f��|dkrn|j
�}n|}|jr�|jd|||�|j
|j||�|dkr�|jd�|S)NrGz'%s' not in '%s'FT)rr>r�r rr<r/rrr�r*rOrpr�r
rx)	r!r;rrbrzr�rr�r{r#r#r$r��s"




z FirewallPolicy.remove_icmp_blockcCs||jdkr|jd|=dS)NrG)r<)r!r�rr#r#r$Z__unregister_icmp_blocksz&FirewallPolicy.__unregister_icmp_blockcCs|j|�|j|�dkS)NrG)rr8)r!r;rr#r#r$�query_icmp_blockszFirewallPolicy.query_icmp_blockcCs|j|�dj�S)NrG)r8r,)r!r;r#r#r$r�szFirewallPolicy.list_icmp_blockscCsdS)NTr#)r!r#r#r$Z__icmp_block_inversion_idsz(FirewallPolicy.__icmp_block_inversion_idc
Cs|jj|�}|jj�|j|}|j�}||jdkrV|jrB|jn|}ttj	d|��|dkrh|j
�}n|}|jr�x&|j|�dD]}	|j
d||	|�q�W|jd||�|j|||�|j|j|||�|j�rx&|j|�dD]}	|j
d||	|�q�W|jd||�|dk�r|jd�|S)NrJz,icmp-block-inversion already enabled in '%s'rGFT)rr>r�r �(_FirewallPolicy__icmp_block_inversion_idr<r/rrrZr*rOr8rp�_icmp_block_inversion�._FirewallPolicy__register_icmp_block_inversionr��*_FirewallPolicy__undo_icmp_block_inversionrx)
r!r;rfrbrzr��icmp_block_inversion_idr�r{r`r#r#r$�add_icmp_block_inversions6





z'FirewallPolicy.add_icmp_block_inversioncCs|jd|�|jd|<dS)NrrJ)r�r<)r!r�rrfr#r#r$Z__register_icmp_block_inversionEsz.FirewallPolicy.__register_icmp_block_inversioncCs�|j�}|jr6x&|j|�dD]}|jd|||�qW||jdkrP|jd|=|jr~x&|j|�dD]}|jd|||�qfW|jd�dS)NrGFrJT)r*rOr8rpr<rx)r!rzr�rr{r`r#r#r$Z__undo_icmp_block_inversionJsz*FirewallPolicy.__undo_icmp_block_inversionc	Cs|jj|�}|jj�|j|}|j�}||jdkrV|jrB|jn|}ttj	d|��|dkrh|j
�}n|}|jr�x&|j|�dD]}|j
d|||�q�W|jd||�|j||�|j|j||d�|j�rx&|j|�dD]}|j
d|||�q�W|jd||�|dk�r|jd�|S)NrJz(icmp-block-inversion not enabled in '%s'rGFT)rr>r�r r
r<r/rrr�r*rOr8rpr�0_FirewallPolicy__unregister_icmp_block_inversionr�rrx)	r!r;rbrzr�rr�r{r`r#r#r$�remove_icmp_block_inversion\s6






z*FirewallPolicy.remove_icmp_block_inversioncCs||jdkr|jd|=dS)NrJ)r<)r!r�rr#r#r$Z!__unregister_icmp_block_inversion�sz0FirewallPolicy.__unregister_icmp_block_inversioncCs|j�|j|�dkS)NrJ)r
r8)r!r;r#r#r$�query_icmp_block_inversion�sz)FirewallPolicy.query_icmp_block_inversionc
Cs�|jjj|�}|jr*|jjj|jd}n|}|rT||jkrt||f|j|krtdSn ||jksp||f|j|krtdSx@|jj�D]2}|jr�||j	�kr�|j
||||�}	|j||	�q�W|j||||fg�|j
|j||||fg�dS)Nr)rr;r.r/r:Z_zone_policiesr�enabled_backends�policies_supportedZget_available_tablesZbuild_policy_chain_rules�	add_rules�_register_chainsr�)
r!r;�creater|r}r{rMZtracking_policy�backendrHr#r#r$rn�s$

zFirewallPolicy.gen_chain_rulescCsbx\|D]T\}}|r,|jj|g�j||f�q|j|j||f�t|j|�dkr|j|=qWdS)Nr)r�
setdefaultr0�remover�)r!r;rZtablesr|r}r#r#r$r�szFirewallPolicy._register_chainscCs$|jjj|�dkrdS|jjj|�S)Nzhash:mac)rr��get_typeZ
get_family)r!rKr#r#r$r��szFirewallPolicy._ipset_familycCs|jjj|�S)N)rr�r)r!rKr#r#r$Z__ipset_type�szFirewallPolicy.__ipset_typecCsdj|g|jjj|��S)N�,)�joinrr�Z
get_dimension)r!rK�flagr#r#r$�_ipset_match_flags�sz!FirewallPolicy._ipset_match_flagscCs|jjj|�S)N)rr�Z
check_applied)r!rKr#r#r$r��sz#FirewallPolicy._check_ipset_appliedcCs*|j|�}|tkr&ttjd||f��dS)Nz.ipset '%s' with type '%s' not usable as source)�_FirewallPolicy__ipset_typerrrZ
INVALID_IPSET)r!rKZ_typer#r#r$r��s
z+FirewallPolicy._check_ipset_type_for_sourcecs�t|j�tkr��jjj|jj�}|dkr2|jjg}xR|jD]H}||krHq:�j|�|j	|�t
j|�}||j_�j|||||d�q:Wg}	|j
r�|j
g}	nH|jr�t|jt�s�t|jt�r�jjj|jj���jr�fdd�dD�}	�j|j�}
|
�r&|j
�r |j
|
k�r&ttjd|
|j
f��n|
g}	|	�s4ddg}	�fdd�|	D�}	|	|_�x2t�fdd�|	D��D�]}t|j�tk�r��jjj|jj�}g}t|j�d	k�r�|j�r�ttjd
��xB|	D].}
|
|jk�r�|j|
��r�|j	|j|
��q�Wn
|j	d��x~|D�]�}t|j�tk�r�j|j |�}|�j!|j"�7}t#t|�dd�d
�}g}x�|D]�}|j$}t%|�}|j&dd�}|j	|�|j
dk�r�|j|j
��r��qTt|j'�dk�r�|j	|�n:x8|j'D].\}}|j(||||||j|�}|j)||��q�W�qTW|j*|�x4|j'D]*\}}|j+||||||�}|j)||��q
Wx.|j,D]$}|j-|||||�}|j)||��q@Wx4|j.D]*\}}|j/||||||�}|j)||��qpW�qW�qft|j�t0k�r�|jj1}|jj2}�j3||�|j+||||d|�}|j)||��qft|j�t4k�r<|jj5}�j6|�|j-|||d|�}|j)||��qft|j�t7k�r�|�rzx&|	D]}
|j|
��rX|j8t9|
��qXW|j:|||�}|j)||��qft|j�t;k�r4|jj1}|jj2}|jj<}|jj=}xD|	D]<}
|j|
��r�j>|
||||�|�r�|�r�|j8t9|
��q�W|j?|||||||�}|j)||��qft|j�t@k�r�|jj1}|jj2}�j3||�|j/||||d|�}|j)||�n�t|j�tk�s�t|j�tk�r>�jjj|jj��|j
�r�j�r�|j
�jk�r�ttjAd|j
|jjf��t|j�tk�r |j�r t|j�tk�r ttjd��|jB||�|�}|j)||�n>|jdk�rf|jC|||�}|j)||�nttjdt|j����qfWdS)N)�included_servicescsg|]}|�jkr|�qSr#)�destination)r?r�)�ictr#r$r��sz0FirewallPolicy._rule_prepare.<locals>.<listcomp>r�r�z;Source address family '%s' conflicts with rule family '%s'.csg|]}�jj|�r|�qSr#)r�is_ipv_enabled)r?r�)r!r#r$r��scsg|]}�jj|��qSr#)r�get_backend_by_ipv)r?r@)r!r#r$r��srz"Destination conflict with service.cSs|jS)N)rK)r@r#r#r$r�sz.FirewallPolicy._rule_prepare.<locals>.<lambda>)r~�	conntrack�natr�rjz3rich rule family '%s' conflicts with icmp type '%s'z'IcmpBlock not usable with accept actionzUnknown element %s)r�r�)D�typer�rrr��get_servicerK�includesr�r0�copy�deepcopyr��familyr�rr�config�get_icmptyper%r�r�rrZINVALID_RULE�ipvsr9r��is_ipv_supportedr�rr�r�r�r�r+r�r
�replacerC�build_policy_helper_ports_rulesrZadd_modules�build_policy_ports_rulesrI�build_policy_protocol_rulesrF�build_policy_source_ports_rulesrr�r�r�r�valuer�rr�r�build_policy_masquerade_rulesrZto_portr�r�build_policy_forward_port_rulesrZINVALID_ICMPTYPE�build_policy_icmp_block_rulesZ*build_policy_rich_source_destination_rules)r!ryr;r�r{r$�svc�includeZ_ruler3Z
source_ipvrZdestinationsr�r%r�r�r�r�r��
nat_moduler��protorHr�r�r�r#)r&r!r$r��s




 









zFirewallPolicy._rule_preparecCsb|jjj|�}|j|j|�}||j|j�7}tt|�dd�d�}|dkrN|g}x@|j	D]6}||krdqV|j
|�|j|�|j|||||d�qVWg}	xndD]f}
|jj
|
�s�q�|jj|
�}t|j�dkr�|
|jkr�|	j||j|
f�q�|df|	kr�|	j|df�q�W�xV|	D�]L\}}x�|D]�}
|
j}t|�}|
jjdd	�}|j|�|
jd
k�rf|j|
j��rf�qt|
j�dk�r�|j|�n:x8|
jD].\}}|j||||||
j|�}|j||��q�W�qWx2|jD](\}}|j|||||�}|j||��q�Wx,|jD]"}|j||||�}|j||��q�Wx2|jD](\}}|j|||||�}|j||��q,W�qWdS)
NcSs|jS)N)rK)r@r#r#r$r��sz)FirewallPolicy._service.<locals>.<lambda>)r~)r$r�r�rr)r*r�rj)r�r�) rr�r,r�r�r�r�r+r9r-r�r0rrr'r(r�r%r�r
r5Z
add_moduler0r4rCr6rKrr7rIr8rFr9)r!ryr;r�r{r$r>r�r?Zbackends_ipvr�rr%r�r�r�r@r�rArHr�r#r#r$rr�sb






zFirewallPolicy._servicecCs<x6|jj�D](}|jsq|j||||�}|j||�qWdS)N)rrrr7r)r!ryr;r�r�r{rrHr#r#r$rs�s
zFirewallPolicy._portcCs:x4|jj�D]&}|jsq|j|||�}|j||�qWdS)N)rrrr8r)r!ryr;r�r{rrHr#r#r$rt�s
zFirewallPolicy._protocolcCs<x6|jj�D](}|jsq|j||||�}|j||�qWdS)N)rrrr9r)r!ryr;r�r�r{rrHr#r#r$ru�s
zFirewallPolicy._source_portcCs8d}|jt|�|jj|�}|j||�}|j||�dS)Nr�)r�rrr(r;r)r!ryr;r{r�rrHr#r#r$rv�s
zFirewallPolicy._masqueradecCsXtd|�rd}nd}|r(|r(|jt|�|jj|�}	|	j||||||�}
|j|	|
�dS)Nr�r�)rr�rrr(r<r)r!ryr;r{r�r�r�r�r�rrHr#r#r$rq�s

zFirewallPolicy._forward_portc
Cs�|jjj|�}xl|jj�D]^}|js&qd}|jrXx&dD]}||jkr6|j|�s6d}Pq6W|r^q|j|||�}	|j||	�qWdS)NFr�r�T)r�r�)	rr1r2rrr%r4r=r)
r!ryr;rr{r&rZskip_backendr�rHr#r#r$rp�s


zFirewallPolicy._icmp_blockcCsh|j|j}|dkrdS|j|�r0|dkr0dSx2|jj�D]$}|jsHq<|j||�}|j||�q<WdS)N�DROP�
%%REJECT%%�REJECTZACCEPT)rBrCrD)r �targetrrrrZ'build_policy_icmp_block_inversion_rulesr)r!ryr;r{rErrHr#r#r$rsz$FirewallPolicy._icmp_block_inversionc	Cs�x|D]}|j|�qWx|D]}|j|�qWd|ks@d|krXt|�dkrXttjd��d|kshd|kr�t|�dkr�ttjd��|s�|r�|r�|r�d|kr�d|kr�ttjd|��|s�|r�|r�|r�d|kr�d|kr�ttjd|��dS)Nr6r5rjzI'ingress-zones' may only contain one of: many regular zones, ANY, or HOSTzH'egress-zones' may only contain one of: many regular zones, ANY, or HOSTzpolicy "%s" has no ingresszpolicy "%s" has no egress)r�r�r�rrr�)	r!r;r4r7�ingress_interfaces�egress_interfaces�ingress_sources�egress_sourcesr:r#r#r$�check_ingress_egress"s$

z#FirewallPolicy.check_ingress_egressc

Cs�|dkr&|dkr�|r�ttjd|��n�|dkrtd|krFttjd|��d|kr^ttjd|��|r�ttjd|��n||d	kr�d|kr�ttjd|��d|kr�ttjd|��nB|d
kr�d|kr�ttjd|��n |dkr�d|kr�ttjd
|��dS)N�
PREROUTING�rawzFpolicy "%s" egress-zones may not include a zone with added interfaces.�POSTROUTINGr5z/policy "%s" ingress-zones may not include HOST.z.policy "%s" egress-zones may not include HOST.zGpolicy "%s" ingress-zones may not include a zone with added interfaces.�FORWARD�INPUTz0policy "%s" egress-zones must include only HOST.�OUTPUTz1policy "%s" ingress-zones must include only HOST.)rrr�)
r!r;r|r}r4r7rFrGrHrIr#r#r$�check_ingress_egress_chain<s,z)FirewallPolicy.check_ingress_egress_chaincCs$|j�}|j|||�|jd�dS)NT)r*rorx)r!ryr;r{r#r#r$�!_ingress_egress_zones_transactionYsz0FirewallPolicy._ingress_egress_zones_transactioncCsL|j|}|jd}|jd}t�}t�}t�}	t�}
xB|D]:}|dkrJq<|t|jjj|��O}|	t|jjj|��O}	q<WxB|D]:}|dkr�q�|t|jjj|��O}|
t|jjj|��O}
q�W|j||||||	|
�xr|jj�D]d}|j	s�q�xV|j
|�D]H\}
}|j||
||||||	|
�	|j|||
||||	|
�}|j
||��q�Wq�WdS)Nr4r7r6r5)r6r5)r6r5)r r<r9rr:r�Zlist_sourcesrJrrrlrQZ!build_policy_ingress_egress_rulesr)r!ryr;r{rMr4r7rFrGrHrIr:rr|r}rHr#r#r$ro^s@






z$FirewallPolicy._ingress_egress_zonescCs6|j|}d|jdkrFd|jdkrFdddg}|jjsB|jd�|Sd|jdkrpdg}|jjsl|jd�|Sd|jdkr�dgSd|jdko�d|jdk�r�ddddg}|jj�s�|jd�|Sd|jdk�r.dddg}|jj�s�|jd�x4|jdD]}|jjj|�d�rP�qW|jd �|Sd|jdk�r�d!d"g}|jj�sZ|jd#�x>|jdD]}|jjj|�d�rfP�qfW|jd$�|jd%�|Sd&g}|jj�s�|jd'�x4|jdD]}|jjj|�d�r�P�q�W|jd(�x>|jdD]}|jjj|�d�r�P�q�W|jd)�|jd*�|SdS)+z:Create a list of (table, chain) needed for policy dispatchr6r4r5r7r�rOr*rK�manglerLrPrNrMZ
interfacesN)r�rO)r*rK)rSrK)rLrK)r�rO)rLrK)r�rP)r�rN)r*rK)r*rM)rSrK)rLrK)r�rN)r*rK)rSrK)rLrK)r*rM)r�rN)r*rM)rLrK)r*rK)rSrK)r�rN)rLrK)r*rM)r*rK)rSrK)r r<r�nftables_enabledr0r:r8)r!r;rM�tcr:r#r#r$rl�sj
















z4FirewallPolicy._get_table_chains_for_policy_dispatchcCsr|j|}d|jdkr4dg}|jjs0|jd�|Sd|jdkrLdddgSd|jdkrbddgStd|�SdS)z8Create a list of (table, chain) needed for zone dispatchr5r7r�rOrLrKr6�
FORWARD_INr*rSr4�FORWARD_OUTrMzInvalid policy: %sN)r�rO)rLrK)r�rV)r*rK)rSrK)r�rW)r*rM)r r<rrTr0r)r!r;rMrUr#r#r$rm�s

z2FirewallPolicy._get_table_chains_for_zone_dispatchFcCs�|jjj|�}|jr|j}n||}d|jdkrl|dkrBd|S|dkrRd|S|jsh|dkrhd|S�nJd|jd	kr�|js�|dkr�d
|S�n"d|jdk�r�|dkr�|jr�d|Sd
|Sn0|dkr�|r�d|Sd|Sn|dk�r�d|Sn�d|jd	k�rh|dk�r*|j�r d|Sd
|Sn<|dk�rL|�rBd|Sd|Sn|dk�r�|j�s�d|SnN|j�s�|dk�r�d
|S|dk�r�|�r�d|Sd|Sn|dk�r�d|Std|||f�S)Nr5r7r�ZIN_rLZPRE_rSr*r4ZOUT_r6ZFWDI_ZFWD_ZPOST_ZFWDO_z.Can't convert policy to chain name: %s, %s, %s)rSr*)rSrL)rSrL)rSrL)rr;r.r/r<r)r!r;r|Z
policy_prefixZisSNATrM�suffixr#r#r$�policy_base_chain_name�sb













z%FirewallPolicy.policy_base_chain_name)N)N)N)N)rNNT)N)rNNT)N)rNN)N)rNN)N)rNN)N)rNN)N)rNN)N)rNN)N)NN)NN)NNrNN)NNN)NN)rNN)N)NN)N)N)N)NN)F)��__name__�
__module__�__qualname__r%r'r)r*r-r3r=r.rNrQrLrdrer�r8rrcrPr�r�r�r�rSr�r�r�r�r�r�r�rTr�r�r�r�r�r�r�r�rwr^r�r�r�r�r�r�r�rWr�r�r�r�r�r�r�r�r�rXr�r�r�r�r�r�r�r\r�r�r�r�r�r�r]r�r�r�r�r�r�r_r�r�r�r�rrrVrr�rrr�rrrUr	r�r
rr�r
rrrrrrrnrr�r#r"r�r�r�rrrsrtrurvrqrprrJrQrRrorlrmrYr#r#r#r$rs$
'	?.,#,#:
'('('
+))@@		(Pr)'rhr.Zfirewall.core.loggerrZfirewall.functionsrrrrrrr	r
rrr�r
rrrrrrrrrrZfirewall.core.fw_transactionrZfirewallrZfirewall.errorsrZfirewall.fw_typesrZfirewall.core.baser�objectrr#r#r#r$�<module>s04core/__pycache__/fw_nm.cpython-36.pyc000064400000011713150351351730013446 0ustar003

��g�@s dZddddddddgZd	d
lZd	dlmZyejdd
�Wnek
rTdZYn8Xyd	dlmZdZWn e	eej
fk
r�dZYnXd
ad	dlm
Z
d	dlmZd	dlmZd	d
lZdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d�Zd"d�Zd#d�Zd
S)$z(Functions for NetworkManager interaction�check_nm_imported�nm_is_imported�nm_get_zone_of_connection�nm_set_zone_of_connection�nm_get_connections�nm_get_connection_of_interface�nm_get_bus_name�nm_get_dbus_interface�N)�GLib�NMz1.0F)rT)�errors)�
FirewallError)�logcCststtjd��dS)zNCheck function to raise a MISSING_IMPORT error if the import of NM failed
    zgi.repository.NM = 1.0N)�_nm_importedr
rZMISSING_IMPORT�rr�/usr/lib/python3.6/fw_nm.pyr0scCstS)znReturns true if NM has been properly imported
    @return True if import was successful, False otherwirse
    )rrrrrr6scCststjjd�atS)z�Returns the NM client object or None if the import of NM failed
    @return NM.Client instance if import was successful, None otherwise
    N)�
_nm_clientrZClient�newrrrr�
nm_get_client<srcCs�t�t�j|�}|dkrdS|j�}|dkr2dSy |j�tjjtjjB@rPdSWn t	k
rr|j
�rndSYnX|j�}|dkr�d}|S)z�Get zone of connection from NM
    @param connection name
    @return zone string setting of connection, empty string if not set, None if connection is unknown
    N�)rr�get_connection_by_uuid�get_setting_connection�	get_flagsr�SettingsConnectionFlags�NM_GENERATED�NM_VOLATILE�AttributeError�get_unsavedZget_zone)�
connection�con�setting_con�zonerrrrEs$
cCsVt�t�j|�}|dkrdS|j�}|dkr2dS|dkr>d}|jd|�|jdd�S)zSet the zone for a connection
    @param zone name
    @param connection name
    @return True if zone was set, else False
    NFrr!T)rrrrZset_propertyZcommit_changes)r!rrr rrrrcsc	Cs~|j�|j�t�t�j�}xX|D]P}|j�r4q&|j�}|j�}|j�}|||<x |D]}|j�}|rZ|||<qZWq&WdS)znGet active connections from NM
    @param connections return dict
    @param connections_name return dict
    N)	�clearrr�get_active_connections�get_vpnZget_id�get_uuid�get_devices�get_ip_iface)	ZconnectionsZconnections_nameZactive_connections�
active_con�nameZuuidZdevices�dev�ip_ifacerrrrxs


cCs�t�g}x�t�j�D]|}|j�r$qy&|j�}|j�tjjtjj	B@rHwWnt
k
rh|j�rdwYnXx&|j�D]}|j
�}|rt|j|�qtWqW|S)zGGet active interfaces from NM
    @returns list of interface names
    )rrr#r$�get_connectionrrrrrrrr&r'�append)Zactive_interfacesr(rr*r+rrr�nm_get_interfaces�s$r.cCs6g}x,t�D]"}t|�}|t|�kr|j|�qW|S)N)r.rrr-)r!Z
interfaces�	interfaceZconnrrr�nm_get_interfaces_in_zone�sr0cCs<t�x0t�j�D]"}|j�}|dkr(q||kr|SqWdS)zzGet device from NM which has the given IP interface
    @param interface name
    @returns NM.Device instance or None
    N)rrr&r')r/�devicer+rrr�nm_get_device_by_ip_iface�sr2cCsxt�t|�}|dkrdS|j�}|dkr.dSy |j�}|j�tjj@rLdSWn tk
rn|j	�rjdSYnX|j
�S)z�Get connection from NM that is using the interface
    @param interface name
    @returns connection that is using interface or None
    N)rr2Zget_active_connectionr,rrrrrrr%)r/r1r(rrrrr�s
cCsRtsdSy&tj�}|jtjtj�}|j}~~|Stk
rLt	j
d�YnXdS)Nz(Failed to get bus name of NetworkManager)r�dbusZ	SystemBusZ
get_objectr�DBUS_INTERFACEZ	DBUS_PATHZbus_name�	ExceptionrZdebug2)Zbus�objr)rrrr�scCstsdStjS)Nr)rrr4rrrrr�s)�__doc__�__all__ZgiZ
gi.repositoryr
Zrequire_version�
ValueErrorrr�ImportError�ErrorrZfirewallrZfirewall.errorsr
Zfirewall.core.loggerrr3rrrrrrr.r0r2rrrrrrr�<module>s@

	 	
core/__pycache__/fw_zone.cpython-36.pyc000064400000077522150351351730014021 0ustar003

��gy��@s�ddlZddlZddlmZmZmZddlmZddlm	Z	ddl
mZddlm
Z
mZmZmZmZmZmZmZmZddlmZmZmZddlmZdd	lmZdd
lmZGdd�de �Z!dS)
�N)�	SHORTCUTS�DEFAULT_ZONE_TARGET�SOURCE_IPSET_TYPES)�FirewallTransaction)�Policy)�log)	�Rich_Service�	Rich_Port�
Rich_Protocol�Rich_SourcePort�Rich_ForwardPort�Rich_IcmpBlock�
Rich_IcmpType�Rich_Masquerade�	Rich_Mark)�checkIPnMask�
checkIP6nMask�	check_mac)�errors)�
FirewallError)�LastUpdatedOrderedDictc@sNeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd�dd �Zd!d"�Zd#d$�Zd%d&�Zd�d'd(�Zd)d*�Zd+d,�Zd-d.�Zd�d/d0�Zd�d1d2�Zd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Z d=d>�Z!d�d@dA�Z"dBdC�Z#d�dDdE�Z$d�dFdG�Z%d�dHdI�Z&dJdK�Z'dLdM�Z(dNdO�Z)d�dQdR�Z*d�dSdT�Z+d�dUdV�Z,dWdX�Z-d�dYdZ�Z.d�d[d\�Z/d]d^�Z0d_d`�Z1dadb�Z2d�dcdd�Z3dedf�Z4dgdh�Z5didj�Z6dkdl�Z7dmdn�Z8dodp�Z9d�dqdr�Z:dsdt�Z;dudv�Z<dwdx�Z=d�dydz�Z>d{d|�Z?d}d~�Z@dd��ZAd�d�d��ZBd�d��ZCd�d��ZDd�d��ZEd�d��ZFd�d�d��ZGd�d��ZHd�d��ZId�d��ZJd�d�d��ZKd�d��ZLd�d��ZMd�d��ZNd�d�d��ZOd�d��ZPd�d��ZQd�d�d��ZRd�d�d��ZSd�d�d��ZTd�d��ZUd�d�d��ZVd�d��ZWd�d��ZXd�d��ZYd�d�d��ZZd�d��Z[d�d��Z\d�d��Z]d�d��Z^d�d��Z_d�d�d��Z`d�d��Zad�d�d„Zbd�dĄZcd�dƄZddS)��FirewallZonercCs||_i|_i|_dS)N)�_fw�_zones�_zone_policies)�self�fw�r�/usr/lib/python3.6/fw_zone.py�__init__&szFirewallZone.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r)rrrr�__repr__+szFirewallZone.__repr__cCs|jj�|jj�dS)N)r�clearr)rrrr�cleanup.s
zFirewallZone.cleanupcCs
t|j�S)N)rr)rrrr�new_transaction2szFirewallZone.new_transactioncCsdj||d�S)Nzzone_{fromZone}_{toZone})�fromZone�toZone)�format)rr%r&rrr�policy_name_from_zones5sz#FirewallZone.policy_name_from_zonescCst|jj��S)N)�sortedr�keys)rrrr�	get_zones:szFirewallZone.get_zonescCs8g}x.|j�D]"}|j|�s&|j|�r|j|�qW|S)N)r+�list_interfaces�list_sources�append)rZactive_zones�zonerrr�get_active_zones=s
zFirewallZone.get_active_zonescCs6|j|�}x&|jD]}||j|jdkr|SqWdS)N�
interfaces)�_FirewallZone__interface_idr�settings)r�	interface�interface_idr/rrr�get_zone_of_interfaceDs

z"FirewallZone.get_zone_of_interfacecCs6|j|�}x&|jD]}||j|jdkr|SqWdS)N�sources)�_FirewallZone__source_idrr3)r�source�	source_idr/rrr�get_zone_of_sourceLs

zFirewallZone.get_zone_of_sourcecCs|jj|�}|j|S)N)r�
check_zoner)rr/�zrrr�get_zoneTszFirewallZone.get_zonecCsBt�}|j|_|j||�|_|j|_|j|_|g|_|g|_�x�dD�]�}||jkr~|d	kr~|dkr~t	||t
jt||���qD|d
kr�||jkr�|d
kr�t	||t
jt||���qD||jko�|d
ko�|dk�r�t	||t
jt||���qD|dkrDg|_
xB|j
D]8}|j||�}||j|j|�k�r�|j
jt
j|���q�WqDW|S)N�services�ports�
masquerade�
forward_ports�source_ports�icmp_blocks�rules�	protocols�HOST�ANY)r?r@rArBrCrDrErF)r?r@rCrDrF)rA)rDrB)rE)r�nameZderived_from_zoner(�ZONE_POLICY_PRIORITYZpriority�targetZ
ingress_zonesZegress_zones�setattr�copy�deepcopy�getattrrE�_rich_rule_to_policiesr.)r�z_objr%r&�p_objZsetting�ruleZcurrent_policyrrr�policy_obj_from_zone_objXs6

z%FirewallZone.policy_obj_from_zone_objcCs�dd�d	D�|_||j|j<g|j|j<xX|jdfd|jf|jdfgD]8\}}|j|||�}|jjj|�|j|jj|j�qFW|j	|j�dS)
NcSsi|]}t�|�qSr)r)�.0�xrrr�
<dictcomp>sz)FirewallZone.add_zone.<locals>.<dictcomp>r1r7�icmp_block_inversion�forwardrGrH)r1r7rXrY)
r3rrIrrTr�policyZ
add_policyr.�copy_permanent_to_runtime)r�objr%r&rRrrr�add_zone~s

zFirewallZone.add_zonecCsn|j|}x|jD]}|j||dd�qWx|jD]}|j||dd�q2W|jrZ|j|�|jrj|j|�dS)NF)�allow_apply)	rr1�
add_interfacer7�
add_sourcerY�add_forwardrX�add_icmp_block_inversion)rr/r\�argrrrr[�s

z&FirewallZone.copy_permanent_to_runtimecCs8|j|}|jr|j|�|jj�|j|=|j|=dS)N)r�applied�unapply_zone_settingsr3r"r)rr/r\rrr�remove_zone�s


zFirewallZone.remove_zoneNcCsVxP|j�D]D}|j|}t|j�dks4t|j�dkr
tjd|�|j||d�q
WdS)NrzApplying zone '%s')�use_transaction)r+r�lenr1r7r�debug1�apply_zone_settings)rrgr/rQrrr�apply_zones�s

zFirewallZone.apply_zonescCs|j|}||_dS)N)rrd)rr/rdr\rrr�set_zone_applied�s
zFirewallZone.set_zone_appliedcCs�d|krdS|jd�}t|�dkr&dSd}x tD]}|dt|kr0|}q0W|dk	r�|d|j�krhdSt|�dks�t|�dkr�|ddkr�|d|fSdS)N�_�r���prer�deny�allow�post)rqrrrrsrt)�splitrhrr+)r�chainZsplits�_chainrVrrr�zone_from_chain�s 

zFirewallZone.zone_from_chaincCst|j|�}|dkrdS|\}}|d	kr0|}d}n4|d
krB|}d}n"|dkrTd}|}nttjd|��|j||�|fS)N�
PREROUTING�
FORWARD_INrH�INPUTrG�POSTROUTING�FORWARD_OUTz&chain '%s' can't be mapped to a policy)ryrz)r{)r|r})rxrrZ
INVALID_CHAINr()rrvrVr/rwr%r&rrr�policy_from_chain�s
zFirewallZone.policy_from_chainc	Csj|dkrf|j|�}|dk	rf|j|�\}}|dkr:|j�}n|}|jjj|d|||�|dkrf|jd�dS)N�ipv4�ipv6T)rr�)r~r$rrZZgen_chain_rules�execute)	r�ipv�tablervrgrVrZrw�transactionrrr�create_zone_base_by_chain�s

z&FirewallZone.create_zone_base_by_chaincCstj�||d�}|S)N)Zdate�sender�timeout)�time)rr�r��retrrrZ__gen_settings�szFirewallZone.__gen_settingscCs|j|�jS)N)r>r3)rr/rrr�get_settings�szFirewallZone.get_settingscCs�|j|�}x�|D]z}xt||D]h}|dkr<|j||||�q|dkr`|j|||d|d|�q|dkrlqq|dkrvqtjd|||�qWqW|r�|j|||�dS)Nr1r7rrorXrYz3Zone '%s': Unknown setting '%s:%s', unable to apply)r��
_interface�_sourcerZwarning�_icmp_block_inversion)r�enabler/r�r3�key�argsrrr�_zone_settingss

zFirewallZone._zone_settingscCs�|jj|�}|j|}|jr dSd|_|dkr8|j�}n|}x2|j|D]$}tjd||�|jjj	||d�qHW|j
d||�|dkr�|jd�dS)NTz+Applying policy (%s) derived from zone '%s')rg)rr<rrdr$rrrirZ�apply_policy_settingsr�r�)rr/rg�_zoner\r�rZrrrrjs

z FirewallZone.apply_zone_settingscCs�|jj|�}|j|}|js dS|dkr2|j�}n|}x$|j|D]}|jjj||d�qBW|jd||�|dkr||j	d�dS)N)rgFT)
rr<rrdr$rrZ�unapply_policy_settingsr�r�)rr/rgr�r\r�rZrrrre,s

z"FirewallZone.unapply_zone_settingscCs~|j|�}|j|�}g}x\td�D]P}|j|d|krZ|jtjt||j|d���q"|j||j|d�q"Wt|�S)zH
        :return: exported config updated with runtime settings
        �r)	r>�get_config_with_settings_dict�rangeZIMPORT_EXPORT_STRUCTUREr.rMrNrO�tuple)rr/r\Z	conf_dictZ	conf_list�irrr�get_config_with_settings?s

"z%FirewallZone.get_config_with_settingsc
Cs�|j|�j�}|dtkr"d|d<|j|�|j|�|j|�|j|�|j|�|j|�|j	|�|j
|�|j|�|j|�|j
|�|j|�d�}|jj||�S)zH
        :return: exported config updated with runtime settings
        rK�default)r?r@rDrArBr1r7�	rules_strrFrCrXrY)r>Zexport_config_dictr�
list_services�
list_ports�list_icmp_blocks�query_masquerade�list_forward_portsr,r-�
list_rules�list_protocols�list_source_ports�query_icmp_block_inversion�
query_forwardrZ'combine_runtime_with_permanent_settings)rr/Z	permanentZruntimerrrr�Os z*FirewallZone.get_config_with_settings_dictc
sddlm�d��fdd�	}��fdd�}�j�jf�j�jf�j�jf�j�j	f�j
�jf�j�j
f�j�jf||f�j�jf�j�jf�j�jf�j�jfd�}�j|�}�jj||�\}}	xv|	D]n}
t|	|
t��r$xX|	|
D]:}t|t��r||
d|f|��q�||
d||�q�Wq�||
d|�q�Wx�|D]�}
t||
t��r�x�||
D]l}|
dk�r�||
d|||d�nDt|t��r�||
d|f|�d|d��n||
d||d|d��q\Wn6|
dk�r�||
d||d�n||
d|d|d��q>WdS)Nr)�	Rich_Rulecs�j|�|d�d|d�dS)N)�rule_strr)r�r�)�add_rule)r/r�r�r�)r�rrr�add_rule_wrapperhszDFirewallZone.set_config_with_settings_dict.<locals>.add_rule_wrappercs�j|�|d��dS)N)r�)�remove_rule)r/r�)r�rrr�remove_rule_wrapperjszGFirewallZone.set_config_with_settings_dict.<locals>.remove_rule_wrapper)r?r@rDrArBr1r7r�rFrCrXrYror1r7)r�)r�r�rX)rN)r1r7)rX)�firewall.core.richr��add_service�remove_service�add_port�remove_port�add_icmp_block�remove_icmp_block�add_masquerade�remove_masquerade�add_forward_port�remove_forward_portr_�remove_interfacer`�
remove_source�add_protocol�remove_protocol�add_source_port�remove_source_portrb�remove_icmp_block_inversionra�remove_forwardr�rZget_added_and_removed_settings�
isinstance�listr�)rr/r3r�r�r�Z
setting_to_fnZold_settingsZadd_settingsZremove_settingsr�r�r)r�rr�set_config_with_settings_dictesF













  
z*FirewallZone.set_config_with_settings_dictcCs|jj|�dS)N)r�check_interface)rr4rrrr��szFirewallZone.check_interfacecCs\|jj|�}|j|}|j|�}||jdkrX|jd|}d|krX|ddk	rX|dSdS)Nr1r�)rr<rr2r3)rr/r4r��_objr5r3rrr�interface_get_sender�s

z!FirewallZone.interface_get_sendercCs|j|�|S)N)r�)rr4rrrZ__interface_id�s
zFirewallZone.__interface_idTc
Cs|jj�|jj|�}|j|}|j|�}||jdkrLttjd||f��|j	|�dk	rjttj
d|��tjd||f�|dkr�|j
�}	n|}	|jr�|r�|j||	d�|	j|j|d�|r�|jd|||	�|j||||�|	j|j||�|dk�r|	jd�|S)Nr1z'%s' already bound to '%s'z'%s' already bound to a zonez&Setting zone of interface '%s' to '%s')rgFT)r�check_panicr<rr2r3rr�ZONE_ALREADY_SETr6�
ZONE_CONFLICTrrir$rdrj�add_failrlr��!_FirewallZone__register_interface�#_FirewallZone__unregister_interfacer�)
rr/r4r�rgr^r�r�r5r�rrrr_�s8









zFirewallZone.add_interfacecCs6|jd|�|jd|<|p"|dk|jd|d<dS)Nrr1��__default__)�_FirewallZone__gen_settingsr3)rr�r5r/r�rrrZ__register_interface�sz!FirewallZone.__register_interfacecCsR|jj�|j|�}|jj|�}||kr,|S|dk	r@|j||�|j|||�}|S)N)rr�r6r<r�r_)rr/r4r��	_old_zone�	_new_zoner�rrr�change_zone_of_interface�s

z%FirewallZone.change_zone_of_interfacecCsz|jj�|dkr|j�}n|}|j||�|jd|d|dd�|dk	rd|dkrd|jd|d|dd�|dkrv|jd�dS)NT�+)r.r�F)rr�r$rjr�r�)rZold_zoneZnew_zonergr�rrr�change_default_zone�s

z FirewallZone.change_default_zonec	Cs�|jj�|j|�}|dkr,ttjd|��|dkr8|n
|jj|�}||krbttjd|||f��|dkrt|j�}n|}|j	|}|j
|�}|j|j||�|j
d|||�|dkr�|jd�|S)Nz'%s' is not in any zoner�z"remove_interface(%s, %s): zoi='%s'FT)rr�r6rrZUNKNOWN_INTERFACEr<r�r$rr2�add_postr�r�r�)	rr/r4rgZzoir�r�r�r5rrrr��s(






zFirewallZone.remove_interfacecCs||jdkr|jd|=dS)Nr1)r3)rr�r5rrrZ__unregister_interfacesz#FirewallZone.__unregister_interfacecCs|j|�|j|�dkS)Nr1)r2r�)rr/r4rrr�query_interfaceszFirewallZone.query_interfacecCs|j|�dj�S)Nr1)r�r*)rr/rrrr,"szFirewallZone.list_interfacesFcCsxt|�rdSt|�rdSt|�r$dS|jd�rh|j|dd��|rV|j|dd��|j|dd��Sttj	|��dS)Nrr�r�zipset:�)
rrr�
startswith�_check_ipset_type_for_source�_check_ipset_applied�
_ipset_familyrrZINVALID_ADDR)rr9rdrrr�check_source's
zFirewallZone.check_sourcecCs|j||d�}||fS)N)rd)r�)rr9rdr�rrrZ__source_id6szFirewallZone.__source_idc
Cs|jj�|jj|�}|j|}t|�r0|j�}|j||d�}||jdkr`tt	j
d||f��|j|�dk	r~tt	jd|��|dkr�|j
�}	n|}	|jr�|r�|j||	d�|	j|j|d�|r�|jd||d|d	|	�|j||||�|	j|j||�|dk�r|	jd�|S)
N)rdr7z'%s' already bound to '%s'z'%s' already bound to a zone)rgFTrro)rr�r<rr�upperr8r3rrr�r;r�r$rdrjr�rlr��_FirewallZone__register_source� _FirewallZone__unregister_sourcer�)
rr/r9r�rgr^r�r�r:r�rrrr`:s4





zFirewallZone.add_sourcecCs6|jd|�|jd|<|p"|dk|jd|d<dS)Nrr7r�r�)r�r3)rr�r:r/r�rrrZ__register_sourceaszFirewallZone.__register_sourcecCsb|jj�|j|�}|jj|�}||kr,|St|�r<|j�}|dk	rP|j||�|j|||�}|S)N)rr�r;r<rr�r�r`)rr/r9r�r�r�r�rrr�change_zone_of_sourcegs

z"FirewallZone.change_zone_of_sourcec	Cs�|jj�t|�r|j�}|j|�}|dkr<ttjd|��|dkrH|n
|jj|�}||krrttj	d|||f��|dkr�|j
�}n|}|j|}|j|�}|j
|j||�|jd||d|d|�|dkr�|jd�|S)Nz'%s' is not in any zoner�zremove_source(%s, %s): zos='%s'FrroT)rr�rr�r;rrZUNKNOWN_SOURCEr<r�r$rr8r�r�r�r�)	rr/r9rgZzosr�r�r�r:rrrr�ys,






zFirewallZone.remove_sourcecCs||jdkr|jd|=dS)Nr7)r3)rr�r:rrrZ__unregister_source�sz FirewallZone.__unregister_sourcecCs(t|�r|j�}|j|�|j|�dkS)Nr7)rr�r8r�)rr/r9rrr�query_source�szFirewallZone.query_sourcecCsdd�|j|�dj�D�S)NcSsg|]}|d�qS)ror)rU�krrr�
<listcomp>�sz-FirewallZone.list_sources.<locals>.<listcomp>r7)r�r*)rr/rrrr-�szFirewallZone.list_sourcescs�x��jj�D]�}|jsqxP�j|D]B}x<�jjj|�D]*\}}	|j||||||	|�}
|j||
�q8Wq$W�j|d�}�j	|�dr|d
kr|j
|||d|d�}
|j||
�qWxΈjjj�D]�}|�jjj|�kr�|�jjj
|�kr�q�|�jjj�k�rd�jjj|�j�rd|�r<t�j|��dk�r<�jjj||d�n&�jjjd	||�|j�fd
d�|�q�|r�|j�fdd�|�q�WdS)NrHrYr��*�filter)r4ro)rgFcs |�jjj�ko�jjjd|�S)NT)rrZ�)get_active_policies_not_derived_from_zone�!_ingress_egress_zones_transaction)�p)rrr�<lambda>�sz)FirewallZone._interface.<locals>.<lambda>cs|�jjj�ko�jjj|�S)N)rrZr�r�)r�)rrrr��s)r�r�)r�enabled_backends�policies_supportedrrZ�#_get_table_chains_for_zone_dispatchZ!build_zone_source_interface_rules�	add_rulesr(r��build_zone_forward_rules�"get_policies_not_derived_from_zone�list_ingress_zones�list_egress_zonesr��
get_policyrdrhr,r��_ingress_egress_zonesr�)rr�r/r4r�r.�backendrZr�rvrEr)rrr��s2$zFirewallZone._interfacecCs$|j|�dkrdS|jjj|dd�S)Nzhash:macF)rd)�_ipset_typer�ipsetZ
get_family)rrIrrrr��szFirewallZone._ipset_familycCs|jjj|dd�S)NF)rd)rr�Zget_type)rrIrrrr��szFirewallZone._ipset_typecCsdj|g|jjj|��S)N�,)�joinrr�Z
get_dimension)rrI�flagrrr�_ipset_match_flags�szFirewallZone._ipset_match_flagscCs|jjj|�S)N)rr�Z
check_applied)rrIrrrr��sz!FirewallZone._check_ipset_appliedcCs*|j|�}|tkr&ttjd||f��dS)Nz.ipset '%s' with type '%s' not usable as source)r�rrrZ
INVALID_IPSET)rrIZ_typerrrr��s
z)FirewallZone._check_ipset_type_for_sourcec
s�x�|r�jj|�gn�jj�D]�}|js*qxN�j|D]@}x:�jjj|�D](\}}	|j||||||	�}
|j||
�qJWq6W�j	|d�}�j
|�dr|j|||d|d�}
|j||
�qWxΈjjj�D]�}|�jjj
|�kr�|�jjj|�kr�q�|�jjj�k�rl�jjj|�j�rl|�rDt�j|��dk�rD�jjj||d�n&�jjjd||�|j�fdd	�|�q�|r�|j�fd
d	�|�q�WdS)NrHrYr�)r9ro)rgFcs |�jjj�ko�jjjd|�S)NT)rrZr�r�)r�)rrrr�sz&FirewallZone._source.<locals>.<lambda>cs|�jjj�ko�jjj|�S)N)rrZr�r�)r�)rrrr�
s)r�get_backend_by_ipvr�r�rrZr�Zbuild_zone_source_address_rulesr�r(r�r�r�r�r�r�r�rdrhr-r�r�r�)rr�r/r�r9r�r�rZr�rvrEr)rrr��s2"$zFirewallZone._sourcecCs0|jj|�}|j|d�}|jjj||||�|S)NrG)rr<r(rZr�)rr/�servicer�r��p_namerrrr�
szFirewallZone.add_servicecCs,|jj|�}|j|d�}|jjj||�|S)NrG)rr<r(rZr�)rr/r�r�rrrr�szFirewallZone.remove_servicecCs(|jj|�}|j|d�}|jjj||�S)NrG)rr<r(rZ�
query_service)rr/r�r�rrrr�szFirewallZone.query_servicecCs&|jj|�}|j|d�}|jjj|�S)NrG)rr<r(rZr�)rr/r�rrrr�szFirewallZone.list_servicescCs2|jj|�}|j|d�}|jjj|||||�|S)NrG)rr<r(rZr�)rr/�port�protocolr�r�r�rrrr�#szFirewallZone.add_portcCs.|jj|�}|j|d�}|jjj|||�|S)NrG)rr<r(rZr�)rr/r�r�r�rrrr�)szFirewallZone.remove_portcCs*|jj|�}|j|d�}|jjj|||�S)NrG)rr<r(rZ�
query_port)rr/r�r�r�rrrr/szFirewallZone.query_portcCs&|jj|�}|j|d�}|jjj|�S)NrG)rr<r(rZr�)rr/r�rrrr�4szFirewallZone.list_portscCs2|jj|�}|j|d�}|jjj|||||�|S)NrG)rr<r(rZr�)rr/�source_portr�r�r�r�rrrr�9szFirewallZone.add_source_portcCs.|jj|�}|j|d�}|jjj|||�|S)NrG)rr<r(rZr�)rr/rr�r�rrrr�?szFirewallZone.remove_source_portcCs*|jj|�}|j|d�}|jjj|||�S)NrG)rr<r(rZ�query_source_port)rr/rr�r�rrrrEszFirewallZone.query_source_portcCs&|jj|�}|j|d�}|jjj|�S)NrG)rr<r(rZr�)rr/r�rrrr�JszFirewallZone.list_source_portscCs�|jj|�}t|j�tkr(|j|d�gSt|j�ttt	t
gkrL|j|d�gSt|j�ttgkrv|j|d�|j|d�gSt|j�t
gkr�|j|d�gSt|j�tgkr�|jd|�gS|jdkr�|j|d�gStdt|j���dS)NrHrGz Rich rule type (%s) not handled.)rr<�type�actionrr(�elementrr	r
rr
rrrr)rr/rSrrrrPOs 

z#FirewallZone._rich_rule_to_policiescCs.x(|j||�D]}|jjj||||�qW|S)N)rPrrZr�)rr/rSr�r�r�rrrr�bszFirewallZone.add_rulecCs*x$|j||�D]}|jjj||�qW|S)N)rPrrZr�)rr/rSr�rrrr�gszFirewallZone.remove_rulecCs2d}x(|j||�D]}|o(|jjj||�}qW|S)NT)rPrrZ�
query_rule)rr/rSr�r�rrrrlszFirewallZone.query_rulecCs^|jj|�}t�}xB|j|d�|j|d�|jd|�gD]}|jt|jjj|���q6Wt|�S)NrHrG)rr<�setr(�updaterZr�r�)rr/r�r�rrrr�rs
zFirewallZone.list_rulescCs0|jj|�}|j|d�}|jjj||||�|S)NrG)rr<r(rZr�)rr/r�r�r�r�rrrr�{szFirewallZone.add_protocolcCs,|jj|�}|j|d�}|jjj||�|S)NrG)rr<r(rZr�)rr/r�r�rrrr��szFirewallZone.remove_protocolcCs(|jj|�}|j|d�}|jjj||�S)NrG)rr<r(rZ�query_protocol)rr/r�r�rrrr	�szFirewallZone.query_protocolcCs&|jj|�}|j|d�}|jjj|�S)NrG)rr<r(rZr�)rr/r�rrrr��szFirewallZone.list_protocolscCs.|jj|�}|jd|�}|jjj|||�|S)NrH)rr<r(rZr�)rr/r�r�r�rrrr��szFirewallZone.add_masqueradecCs*|jj|�}|jd|�}|jjj|�|S)NrH)rr<r(rZr�)rr/r�rrrr��szFirewallZone.remove_masqueradecCs&|jj|�}|jd|�}|jjj|�S)NrH)rr<r(rZr�)rr/r�rrrr��szFirewallZone.query_masqueradec	Cs6|jj|�}|j|d�}|jjj|||||||�|S)NrH)rr<r(rZr�)	rr/r�r��toport�toaddrr�r�r�rrrr��s
zFirewallZone.add_forward_portcCs2|jj|�}|j|d�}|jjj|||||�|S)NrH)rr<r(rZr�)rr/r�r�r
rr�rrrr��sz FirewallZone.remove_forward_portcCs.|jj|�}|j|d�}|jjj|||||�S)NrH)rr<r(rZ�query_forward_port)rr/r�r�r
rr�rrrr�szFirewallZone.query_forward_portcCs&|jj|�}|j|d�}|jjj|�S)NrH)rr<r(rZr�)rr/r�rrrr��szFirewallZone.list_forward_portscCsP|jj|�}|j|d�}|jjj||||�|j|d�}|jjj||||�|S)NrGrH)rr<r(rZr�)rr/�icmpr�r�r�rrrr��szFirewallZone.add_icmp_blockcCsH|jj|�}|j|d�}|jjj||�|j|d�}|jjj||�|S)NrGrH)rr<r(rZr�)rr/r
r�rrrr��szFirewallZone.remove_icmp_blockcCsD|jj|�}|j|d�}|j|d�}|jjj||�oB|jjj||�S)NrGrH)rr<r(rZ�query_icmp_block)rr/r
�p_name_host�
p_name_fwdrrrr�s
zFirewallZone.query_icmp_blockcCsH|jj|�}|j|d�}|j|d�}tt|jjj|�|jjj|���S)NrGrH)rr<r(r)rrZr�)rr/rrrrrr��s
zFirewallZone.list_icmp_blockscCsH|jj|�}|j|d�}|jjj||�|j|d�}|jjj||�|S)NrGrH)rr<r(rZrb)rr/r�r�rrrrb�sz%FirewallZone.add_icmp_block_inversioncCsL|jj|�}|j|d�}|jjj|||�|j|d�}|jjj|||�dS)NrGrH)rr<r(rZr�)rr�r/r�r�rrrr��s
z"FirewallZone._icmp_block_inversioncCsD|jj|�}|j|d�}|jjj|�|j|d�}|jjj|�|S)NrGrH)rr<r(rZr�)rr/r�rrrr��sz(FirewallZone.remove_icmp_block_inversioncCs@|jj|�}|j|d�}|j|d�}|jjj|�o>|jjj|�S)NrGrH)rr<r(rZr�)rr/rrrrrr��s
z'FirewallZone.query_icmp_block_inversionc
	Cs�|j|d�}xT|j|jdD]@}x:|jj�D],}|js:q.|j|||d|d�}|j||�q.WqWxj|j|jdD]V\}}	xL|r�|jj|�gn|jj�D],}|js�q�|j|||d|	d�}|j||�q�WqtWdS)NrHr1r�)r4r7)r9)	r(rr3rr�r�r�r�r�)
rr�r/r�r�r4r�rEr�r9rrr�_forward�s"zFirewallZone._forwardcCsdS)NTr)rrrrZ__forward_idszFirewallZone.__forward_idc	Cs�|jj|�}|jj|�|jj�|j|}|j�}||jdkrRttj	d|��|dkrd|j
�}n|}|jr||jd||�|j
||||�|j|j||�|dkr�|jd�|S)NrYzforward already enabled in '%s'T)rr<Z
check_timeoutr�r�_FirewallZone__forward_idr3rrZALREADY_ENABLEDr$rdr�_FirewallZone__register_forwardr��!_FirewallZone__unregister_forwardr�)	rr/r�r�rgr�r��
forward_idr�rrrras$




zFirewallZone.add_forwardcCs|j||�|jd|<dS)NrY)r�r3)rr�rr�r�rrrZ__register_forward.szFirewallZone.__register_forwardcCs�|jj|�}|jj�|j|}|j�}||jdkrFttjd|��|dkrX|j	�}n|}|j
rp|jd||�|j|j
||�|dkr�|jd�|S)NrYzforward not enabled in '%s'FT)rr<r�rrr3rrZNOT_ENABLEDr$rdrr�rr�)rr/rgr�r�rr�rrrr�2s 




zFirewallZone.remove_forwardcCs||jdkr|jd|=dS)NrY)r3)rr�rrrrZ__unregister_forwardKsz!FirewallZone.__unregister_forwardcCs|j�|j|�dkS)NrY)rr�)rr/rrrr�OszFirewallZone.query_forward)N)N)N)N)NNT)N)N)N)F)F)NNT)N)N)F)rN)rN)rN)rN)rN)rN)NNrN)NN)NN)rN)N)rNN)N)e�__name__�
__module__�__qualname__rJrr!r#r$r(r+r0r6r;r>rTr]r[rfrkrlrxr~r�r�r�r�rjrer�r�r�r�r�r2r_r�r�r�r�r�r�r,r�r8r`r�r�r�r�r�r-r�r�r�r�r�r�r�r�r�r�r�r�r�rr�r�r�rr�rPr�r�rr�r�r�r	r�r�r�r�r�r�rr�r�r�rr�rbr�r�r�rrrarr�rr�rrrrr#s�&



8
(





&


,(



	





		
		

r)"r�rMZfirewall.core.baserrrZfirewall.core.fw_transactionrZfirewall.core.io.policyrZfirewall.core.loggerrr�rr	r
rrr
rrrZfirewall.functionsrrrZfirewallrZfirewall.errorsrZfirewall.fw_typesr�objectrrrrr�<module>s,core/__pycache__/fw_direct.cpython-36.pyc000064400000031230150351351730014302 0ustar003

��g�W�@sndgZddlmZddlmZddlmZddlmZddlm	Z	ddl
mZddlm
Z
Gd	d�de�Zd
S)�FirewallDirect�)�LastUpdatedOrderedDict)�	ipXtables)�ebtables)�FirewallTransaction)�log)�errors)�
FirewallErrorc@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dNdd�Zdd�Zdd�Z
dOdd�Zdd�Zdd�Zdd�Zd d!�ZdPd"d#�ZdQd$d%�Zd&d'�Zd(d)�Zd*d+�ZdRd,d-�ZdSd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�ZdTd<d=�Z dUd>d?�Z!d@dA�Z"dBdC�Z#dDdE�Z$dFdG�Z%dHdI�Z&dJdK�Z'dLdM�Z(dS)VrcCs||_|j�dS)N)�_fw�_FirewallDirect__init_vars)�self�fw�r�/usr/lib/python3.6/fw_direct.py�__init__'szFirewallDirect.__init__cCsd|j|j|j|jfS)Nz%s(%r, %r, %r))�	__class__�_chains�_rules�_rule_priority_positions)rrrr�__repr__+szFirewallDirect.__repr__cCs"i|_i|_i|_i|_d|_dS)N)rrr�
_passthroughs�_obj)rrrrZ__init_vars/s
zFirewallDirect.__init_varscCs|j�dS)N)r)rrrr�cleanup6szFirewallDirect.cleanupcCs
t|j�S)N)rr
)rrrr�new_transaction;szFirewallDirect.new_transactioncCs
||_dS)N)r)r�objrrr�set_permanent_config@sz#FirewallDirect.set_permanent_configcCs*t|j�t|j�t|j�dkr&dSdS)NrTF)�lenrrr)rrrr�has_runtime_configurationCs"z(FirewallDirect.has_runtime_configurationcCsB|j�rdSt|jj��t|jj��t|jj��dkr>dSdS)NTrF)rrr�get_all_chains�
get_all_rules�get_all_passthroughs)rrrr�has_configurationHsz FirewallDirect.has_configurationNcCsP|dkr|j�}n|}|j|jj�|jj�|jj�f|�|dkrL|jd�dS)NT)r�
set_configrrrr �execute)r�use_transaction�transactionrrr�apply_directQs

zFirewallDirect.apply_directcCsi}i}i}xL|jD]B}|\}}x4|j|D]&}|jj|||�s,|j|g�j|�q,WqWxf|jD]\}|\}}}xL|j|D]>\}	}
|jj||||	|
�s|||kr�t�||<|	|||	|
f<q|WqbWxP|jD]F}x@|j|D]2}
|jj	||
�s�||k�r�g||<||j|
�q�Wq�W|||fS)N)
rr�query_chain�
setdefault�appendr�
query_rulerr�query_passthrough)rZchains�rulesZpassthroughs�table_id�ipv�table�chain�chain_id�priority�argsrrr�get_runtime_configbs,


z!FirewallDirect.get_runtime_configcCs|j|j|jfS)N)rrr)rrrr�
get_config�szFirewallDirect.get_configcCs�|dkr|j�}n|}|\}}}x||D]t}|\}}	xf||D]Z}
|j||	|
�s<y|j||	|
|d�Wq<tk
r�}ztjt|��WYdd}~Xq<Xq<Wq&Wx�|D]�}|\}}	}
xt||D]h\}
}|j||	|
|
|�s�y|j||	|
|
||d�Wq�tk
�r"}ztjt|��WYdd}~Xq�Xq�Wq�Wxx|D]p}xh||D]\}|j	||��s@y|j
|||d�Wn2tk
�r�}ztjt|��WYdd}~XnX�q@W�q2W|dk�r�|jd�dS)N)r$T)rr'�	add_chainr	rZwarning�strr*�add_ruler+�add_passthroughr#)rZconfr$r%rrrr-r.r/r0�errorr1r2r3rrrr"�s@



(

(
,
zFirewallDirect.set_configcCs*dddg}||kr&ttjd||f��dS)N�ipv4�ipv6Zebz'%s' not in '%s')r	rZINVALID_IPV)rr.Zipvsrrr�
_check_ipv�s
zFirewallDirect._check_ipvcCsF|j|�|dkrtjj�ntjj�}||krBttjd||f��dS)Nr;r<z'%s' not in '%s')r;r<)r=r�BUILT_IN_CHAINS�keysrr	rZ
INVALID_TABLE)rr.r/Ztablesrrr�_check_ipv_table�s

zFirewallDirect._check_ipv_tablecCs�|dkr4tj|}|jjr i}qH|jj|�j|}ntj|}tj|}||kr`tt	j
d|��||krxtt	j
d|��|dkr�|jjj|�dk	r�tt	j
d|��dS)Nr;r<zchain '%s' is built-in chainzchain '%s' is reservedzChain '%s' is reserved)r;r<)r;r<)rr>r
�nftables_enabled�get_direct_backend_by_ipv�
our_chainsrZ
OUR_CHAINSr	rZ
BUILTIN_CHAIN�zoneZzone_from_chainZ
INVALID_CHAIN)rr.r/r0Zbuilt_in_chainsrCrrr�_check_builtin_chain�s"




z#FirewallDirect._check_builtin_chaincCsH|r|jj|g�j|�n*|j|j|�t|j|�dkrD|j|=dS)Nr)rr(r)�remover)rr-r0�addrrr�_register_chain�s
zFirewallDirect._register_chaincCsV|dkr|j�}n|}|jj�r.|j|jj�|jd||||�|dkrR|jd�dS)NT)rr
�may_skip_flush_direct_backends�add_pre�flush_direct_backends�_chainr#)rr.r/r0r$r%rrrr6�s

zFirewallDirect.add_chaincCs>|dkr|j�}n|}|jd||||�|dkr:|jd�dS)NFT)rrLr#)rr.r/r0r$r%rrr�remove_chain�s
zFirewallDirect.remove_chaincCs:|j||�|j|||�||f}||jko8||j|kS)N)r@rEr)rr.r/r0r-rrrr'�s

zFirewallDirect.query_chaincCs,|j||�||f}||jkr(|j|SgS)N)r@r)rr.r/r-rrr�
get_chains�s


zFirewallDirect.get_chainscCsDg}x:|jD]0}|\}}x"|j|D]}|j|||f�q$WqW|S)N)rr))r�r�keyr.r/r0rrrrszFirewallDirect.get_all_chainscCsZ|dkr|j�}n|}|jj�r.|j|jj�|jd||||||�|dkrV|jd�dS)NT)rr
rIrJrK�_ruler#)rr.r/r0r2r3r$r%rrrr8	s

zFirewallDirect.add_rulecCsB|dkr|j�}n|}|jd||||||�|dkr>|jd�dS)NFT)rrQr#)rr.r/r0r2r3r$r%rrr�remove_rules
zFirewallDirect.remove_rulecCs2|j||�|||f}||jko0||f|j|kS)N)r@r)rr.r/r0r2r3r1rrrr*#s

zFirewallDirect.query_rulecCs6|j||�|||f}||jkr2t|j|j��SgS)N)r@r�listr?)rr.r/r0r1rrr�	get_rules)s


zFirewallDirect.get_rulesc	CsRg}xH|jD]>}|\}}}x.|j|D] \}}|j||||t|�f�q&WqW|S)N)rr)rS)rrOrPr.r/r0r2r3rrrr0s
 zFirewallDirect.get_all_rulescCs�|rr||jkrt�|j|<||j||<||jkr<i|j|<||j|krb|j|||7<q�||j||<n<|j||=t|j|�dkr�|j|=|j|||8<dS)Nr)rrrr)r�rule_idr1r2�enable�countrrr�_register_rule8s


zFirewallDirect._register_rulecCsVy|jj|jj|�j|�Stk
rP}ztj|�ttj	|��WYdd}~XnXdS)N)
r
�rulerB�name�	ExceptionrZdebug2r	rZCOMMAND_FAILED)rr.r3�msgrrr�passthroughLs

zFirewallDirect.passthroughcCsX|r*||jkrg|j|<|j|j|�n*|j|j|�t|j|�dkrT|j|=dS)Nr)rr)rFr)rr.r3rVrrr�_register_passthroughTs

z$FirewallDirect._register_passthroughcCsX|dkr|j�}n|}|jj�r.|j|jj�|jd|t|�|�|dkrT|jd�dS)NT)rr
rIrJrK�_passthroughrSr#)rr.r3r$r%rrrr9^s

zFirewallDirect.add_passthroughcCs@|dkr|j�}n|}|jd|t|�|�|dkr<|jd�dS)NFT)rr_rSr#)rr.r3r$r%rrr�remove_passthroughls
z!FirewallDirect.remove_passthroughcCs||jkot|�|j|kS)N)r�tuple)rr.r3rrrr+ws
z FirewallDirect.query_passthroughcCs>g}x4|jD]*}x$|j|D]}|j|t|�f�qWqW|S)N)rr)rS)rrOr.r3rrrr {s
z#FirewallDirect.get_all_passthroughscCs4g}||jkr0x |j|D]}|jt|��qW|S)N)rr)rS)rr.rOr3rrr�get_passthroughs�s

zFirewallDirect.get_passthroughscCs�g}x�|D]�}d}x�|D]�}y|j|�}Wntk
r>YqXt|�|krd||dkrd}||djd�}x.|D]&}	|dd�}
|	|
|d<|j|
�qxWqW|s
|j|�q
W|S)z5Split values combined with commas for options in optsF�,�TN)�index�
ValueErrorr�splitr))rr,ZoptsZ	out_rulesrYZ	processed�opt�i�items�itemrQrrr�split_value�s$


zFirewallDirect.split_valuec
Cs*|j||�|jjr2|dkr2|jjj||||�|}|jj|�}	|jjrd|	j|||�rdd|}n:|jjr�|dd�dkr�|	j|||dd��r�|dd�}|||f}
||f}|r�|
|jkr�||j|
kr�tt	j
d||||f��nB|
|jk�s||j|
k�rtt	jd||||f��|j|
|}d}d	}
|
|jk�r�t
|j|
j��}d	}x@|t|�k�r�|||k�r�||j|
||7}|d7}�qTWt|�g}|j|d
dg�}|j|dd
g�}x<|D]4}|j|	|	j||||t|���|d7}|
d7}
�q�W|j||
|||
�|j|j||
|||
�dS)Nr;r<z	%s_direct�Z_directz"rule '%s' already is in '%s:%s:%s'zrule '%s' is not in '%s:%s:%s'rdrz-sz--sourcez-dz
--destination)r;r<i����i����i����)r@r
rArD�create_zone_base_by_chainrBZis_chain_builtinrr	r�ALREADY_ENABLED�NOT_ENABLEDr�sortedr?rrSrlr8Z
build_rulerarX�add_fail)rrVr.r/r0r2r3r%rL�backendr1rUrerWZ	positions�jZ	args_list�_argsrrrrQ�sZ




(

zFirewallDirect._rulecCs�|j||�|j|||�||f}|rV||jkr�||j|kr�ttjd|||f��n.||jksn||j|kr�ttjd|||f��|jj|�}|j	||j
|||��|j|||�|j|j|||�dS)Nz chain '%s' already is in '%s:%s'zchain '%s' is not in '%s:%s')
r@rErr	rrorpr
rBZ	add_rulesZbuild_chain_rulesrHrr)rrGr.r/r0r%r-rsrrrrLs$

zFirewallDirect._chainc
Cs�|j|�t|�}|rD||jkrp||j|krpttjd||f��n,||jks\||j|krpttjd||f��|jj|�}|r�|j	|�|dkr�|j
|�\}}|r�|r�|jjj|||�|}	n
|j
|�}	|j||	�|j|||�|j|j|||�dS)Nzpassthrough '%s', '%s'r;r<)r;r<)r=rarr	rrorpr
rBZcheck_passthroughZpassthrough_parse_table_chainrDrnZreverse_passthroughr8r^rr)
rrVr.r3r%Z
tuple_argsrsr/r0rurrrr_'s0




zFirewallDirect._passthrough)N)N)N)N)N)N)N)N))�__name__�
__module__�__qualname__rrrrrrrr!r&r4r5r"r=r@rErHr6rMr'rNrr8rRr*rTrrXr]r^r9r`r+r rbrlrQrLr_rrrrr&sL	

'	

	




jN)�__all__Zfirewall.fw_typesrZ
firewall.corerrZfirewall.core.fw_transactionrZfirewall.core.loggerrZfirewallrZfirewall.errorsr	�objectrrrrr�<module>score/__pycache__/modules.cpython-36.pyc000064400000005500150351351730014005 0ustar003

��g��@sBdZdgZddlmZddlmZddlmZGdd�de�Z	dS)zmodules backend�modules�)�runProg)�log)�COMMANDSc@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dS)rcCstd|_td|_dS)NZmodprobeZrmmod)r�
_load_command�_unload_command)�self�r	�/usr/lib/python3.6/modules.py�__init__s
zmodules.__init__cCs
d|jS)Nz%s)�	__class__)rr	r	r
�__repr__$szmodules.__repr__cCs�g}i}y�tdd��p}xh|D]`}|s&P|j�}|j�}|j|d�|ddkrp|djd�dd	�||d<qg||d<qWWdQRXWntk
r�YnX||fS)
z6 get all loaded kernel modules and their dependencies z
/proc/modules�rr��-�,N����)�open�strip�split�append�FileNotFoundError)r�mods�deps�f�lineZsplitsr	r	r
�loaded_modules's 
 zmodules.loaded_modulescCs"tjd|j|j|�t|j|g�S)Nz	%s: %s %s)r�debug2rrr)r�moduler	r	r
�load_module<szmodules.load_modulecCs"tjd|j|j|�t|j|g�S)Nz	%s: %s %s)rrrrr)rrr	r	r
�
unload_module@szmodules.unload_modulecCsT||krdSx0||D]$}|j|||�||kr|j|�qW||krP|j|�dS)z  get all dependants of a module N)�get_depsr)rrr�ret�modr	r	r
r"Dszmodules.get_depscCs�g}|j�\}}|jd||�x*dD]"}||kr$|j|�|jd|�q$Wx^|D]V}|dks�|jd�s�|jd	�s�|jd
�s�|jd�s�|jd�s�|jd
�rP|j|||�qPW|S)z) get all loaded firewall-related modules Znf_conntrack�nf_conntrack_ipv4�nf_conntrack_ipv6r�	ip_tables�
ip6_tables�ebtablesZiptable_Z	ip6table_Znf_Zxt_Zipt_Zip6t_)r%r&r)r'r(r))rr"�remove�insert�
startswith)rrZmods2rZbad_bad_moduler$r	r	r
�get_firewall_modulesOs


zmodules.get_firewall_modulescCs>x8|j�D],}|j|�\}}|dkr
tjd||f�q
WdS)z% unload all firewall-related modules rz Failed to unload module '%s': %sN)r-r!rZdebug1)rrZstatusr#r	r	r
�unload_firewall_modulesdszmodules.unload_firewall_modulesN)�__name__�
__module__�__qualname__rr
rr r!r"r-r.r	r	r	r
rsN)
�__doc__�__all__Zfirewall.core.progrZfirewall.core.loggerrZfirewall.configr�objectrr	r	r	r
�<module>s
core/__pycache__/fw_service.cpython-36.opt-1.pyc000064400000003201150351351730015424 0ustar003

��gg�@s2dgZddlmZddlmZGdd�de�ZdS)�FirewallService�)�errors)�
FirewallErrorc@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dS)rcCs||_i|_dS)N)Z_fw�	_services)�self�fw�r� /usr/lib/python3.6/fw_service.py�__init__szFirewallService.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r)rrrr	�__repr__ szFirewallService.__repr__cCs|jj�dS)N)r�clear)rrrr	�cleanup#szFirewallService.cleanupcCst|jj��S)N)�sortedr�keys)rrrr	�get_services(szFirewallService.get_servicescCs||jkrttj|��dS)N)rrrZINVALID_SERVICE)r�servicerrr	�
check_service+s
zFirewallService.check_servicecCs|j|�|j|S)N)rr)rrrrr	�get_service/s
zFirewallService.get_servicecCs||j|j<dS)N)r�name)r�objrrr	�add_service3szFirewallService.add_servicecCs|j|�|j|=dS)N)rr)rrrrr	�remove_service6s
zFirewallService.remove_serviceN)�__name__�
__module__�__qualname__r
rrrrrrrrrrr	rsN)�__all__ZfirewallrZfirewall.errorsr�objectrrrrr	�<module>score/__pycache__/fw_policies.cpython-36.opt-1.pyc000064400000004432150351351730015602 0ustar003

��g�
�@sVdgZddlmZddlmZddlmZddlmZddlm	Z	Gdd�de
�ZdS)	�FirewallPolicies�)�config)�log)�LockdownWhitelist)�errors)�
FirewallErrorc@sDeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dS)rcCsd|_ttj�|_dS)NF)�	_lockdownrrZLOCKDOWN_WHITELIST�lockdown_whitelist)�self�r�!/usr/lib/python3.6/fw_policies.py�__init__szFirewallPolicies.__init__cCsd|j|j|jfS)Nz
%s(%r, %r))�	__class__rr	)r
rrr�__repr__#s
zFirewallPolicies.__repr__cCsd|_|jj�dS)NF)rr	�cleanup)r
rrrr'szFirewallPolicies.cleanupcCs�|dkr2tjd|�|jj|�r�tjd�dSn�|dkrdtjd|�|jj|�r�tjd�dSnb|dkr�tjd	|�|jj|�r�tjd
�dSn0|dkr�tjd|�|jj|�r�tjd
�dSdS)N�contextz#Doing access check for context "%s"zcontext matches.TZuidzDoing access check for uid %dzuid matches.�userz Doing access check for user "%s"z
user matches.Zcommandz#Doing access check for command "%s"zcommand matches.F)rZdebug2r	Z
match_contextZdebug3Z	match_uidZ
match_userZ
match_command)r
�key�valuerrr�access_check-s*



zFirewallPolicies.access_checkcCs|jrttjd��d|_dS)Nzenable_lockdown()T)rrrZALREADY_ENABLED)r
rrr�enable_lockdownDsz FirewallPolicies.enable_lockdowncCs|jsttjd��d|_dS)Nzdisable_lockdown()F)rrrZNOT_ENABLED)r
rrr�disable_lockdownIsz!FirewallPolicies.disable_lockdowncCs|jS)N)r)r
rrr�query_lockdownNszFirewallPolicies.query_lockdownN)
�__name__�
__module__�__qualname__r
rrrrrrrrrrrsN)�__all__ZfirewallrZfirewall.core.loggerrZ#firewall.core.io.lockdown_whitelistrrZfirewall.errorsr�objectrrrrr�<module>score/__pycache__/rich.cpython-36.pyc000064400000050640150351351730013267 0ustar003

��g8��@s�dddddddddd	d
ddd
ddddgZddlmZddlmZddlmZddlmZddlm	Z	Gdd�de
�ZGdd�de
�ZGdd�de
�Z
Gdd�de
�ZGdd�de�ZGdd�de
�ZGdd�de
�ZGdd�de
�ZGd d�de
�ZGd!d	�d	e
�ZGd"d
�d
e
�ZGd#d�de
�ZGd$d�de
�ZGd%d
�d
e
�ZGd&d�de�ZGd'd�de
�Zd(d)d/d1d+�ZGd,d�de
�ZGd-d�de
�Zd.S)2�Rich_Source�Rich_Destination�Rich_Service�	Rich_Port�
Rich_Protocol�Rich_Masquerade�Rich_IcmpBlock�
Rich_IcmpType�Rich_SourcePort�Rich_ForwardPort�Rich_Log�
Rich_Audit�Rich_Accept�Rich_Reject�	Rich_Drop�	Rich_Mark�
Rich_Limit�	Rich_Rule�)�	functions)�check_ipset_name)�REJECT_TYPES)�errors)�
FirewallErrorc@seZdZddd�Zdd�ZdS)rFcCs�||_|jdkrd|_||_|jdks0|jdkr8d|_n|jdk	rN|jj�|_||_|jdkrdd|_||_|jdkr�|jdkr�|jdkr�ttjd��dS)N�zno address, mac and ipset)�addr�mac�upper�ipset�invertrr�INVALID_RULE)�selfrrrr�r!�/usr/lib/python3.6/rich.py�__init__$s


zRich_Source.__init__cCsjd|jrdnd}|jdk	r*|d|jS|jdk	rB|d|jS|jdk	rZ|d|jSttjd��dS)Nz	source%s z NOTrzaddress="%s"zmac="%s"z
ipset="%s"zno address, mac and ipset)rrrrrrr)r �retr!r!r"�__str__5s


zRich_Source.__str__N)F)�__name__�
__module__�__qualname__r#r%r!r!r!r"r#s
c@seZdZddd�Zdd�ZdS)rFcCsV||_|jdkrd|_||_|jdkr,d|_||_|jdkrR|jdkrRttjd��dS)Nrzno address and ipset)rrrrrr)r rrrr!r!r"r#Bs

zRich_Destination.__init__cCsRd|jrdnd}|jdk	r*|d|jS|jdk	rB|d|jSttjd��dS)Nzdestination%s z NOTrzaddress="%s"z
ipset="%s"zno address and ipset)rrrrrr)r r$r!r!r"r%Ns

zRich_Destination.__str__N)F)r&r'r(r#r%r!r!r!r"rAs
c@seZdZdd�Zdd�ZdS)rcCs
||_dS)N)�name)r r)r!r!r"r#YszRich_Service.__init__cCs
d|jS)Nzservice name="%s")r))r r!r!r"r%\szRich_Service.__str__N)r&r'r(r#r%r!r!r!r"rXsc@seZdZdd�Zdd�ZdS)rcCs||_||_dS)N)�port�protocol)r r*r+r!r!r"r#`szRich_Port.__init__cCsd|j|jfS)Nzport port="%s" protocol="%s")r*r+)r r!r!r"r%dszRich_Port.__str__N)r&r'r(r#r%r!r!r!r"r_sc@seZdZdd�ZdS)r	cCsd|j|jfS)Nz#source-port port="%s" protocol="%s")r*r+)r r!r!r"r%hszRich_SourcePort.__str__N)r&r'r(r%r!r!r!r"r	gsc@seZdZdd�Zdd�ZdS)rcCs
||_dS)N)�value)r r,r!r!r"r#mszRich_Protocol.__init__cCs
d|jS)Nzprotocol value="%s")r,)r r!r!r"r%pszRich_Protocol.__str__N)r&r'r(r#r%r!r!r!r"rlsc@seZdZdd�Zdd�ZdS)rcCsdS)Nr!)r r!r!r"r#tszRich_Masquerade.__init__cCsdS)N�
masquerader!)r r!r!r"r%wszRich_Masquerade.__str__N)r&r'r(r#r%r!r!r!r"rssc@seZdZdd�Zdd�ZdS)rcCs
||_dS)N)r))r r)r!r!r"r#{szRich_IcmpBlock.__init__cCs
d|jS)Nzicmp-block name="%s")r))r r!r!r"r%~szRich_IcmpBlock.__str__N)r&r'r(r#r%r!r!r!r"rzsc@seZdZdd�Zdd�ZdS)rcCs
||_dS)N)r))r r)r!r!r"r#�szRich_IcmpType.__init__cCs
d|jS)Nzicmp-type name="%s")r))r r!r!r"r%�szRich_IcmpType.__str__N)r&r'r(r#r%r!r!r!r"r�sc@seZdZdd�Zdd�ZdS)r
cCs<||_||_||_||_|jdkr(d|_|jdkr8d|_dS)Nr)r*r+�to_port�
to_address)r r*r+r.r/r!r!r"r#�s

zRich_ForwardPort.__init__cCs<d|j|j|jdkrd|jnd|jdkr4d|jndfS)Nz(forward-port port="%s" protocol="%s"%s%srz
 to-port="%s"z
 to-addr="%s")r*r+r.r/)r r!r!r"r%�szRich_ForwardPort.__str__N)r&r'r(r#r%r!r!r!r"r
�sc@seZdZddd�Zdd�ZdS)rNcCs||_||_||_dS)N)�prefix�level�limit)r r0r1r2r!r!r"r#�szRich_Log.__init__cCs>d|jrd|jnd|jr$d|jnd|jr6d|jndfS)Nz	log%s%s%sz prefix="%s"rz level="%s"z %s)r0r1r2)r r!r!r"r%�szRich_Log.__str__)NNN)r&r'r(r#r%r!r!r!r"r�s
c@seZdZddd�Zdd�ZdS)rNcCs
||_dS)N)r2)r r2r!r!r"r#�szRich_Audit.__init__cCsd|jrd|jndS)Nzaudit%sz %sr)r2)r r!r!r"r%�szRich_Audit.__str__)N)r&r'r(r#r%r!r!r!r"r�s
c@seZdZddd�Zdd�ZdS)r
NcCs
||_dS)N)r2)r r2r!r!r"r#�szRich_Accept.__init__cCsd|jrd|jndS)Nzaccept%sz %sr)r2)r r!r!r"r%�szRich_Accept.__str__)N)r&r'r(r#r%r!r!r!r"r
�s
c@s&eZdZddd�Zdd�Zdd�ZdS)	rNcCs||_||_dS)N)�typer2)r Z_typer2r!r!r"r#�szRich_Reject.__init__cCs,d|jrd|jnd|jr$d|jndfS)Nz
reject%s%sz
 type="%s"rz %s)r3r2)r r!r!r"r%�szRich_Reject.__str__cCsT|jrP|sttjd��|dkrP|jt|krPdjt|�}ttjd|j|f��dS)Nz9When using reject type you must specify also rule family.�ipv4�ipv6z, z%Wrong reject type %s.
Use one of: %s.)r4r5)r3rrrr�join)r �familyZvalid_typesr!r!r"�check�szRich_Reject.check)NN)r&r'r(r#r%r8r!r!r!r"r�s
c@seZdZdd�ZdS)rcCsd|jrd|jndS)Nzdrop%sz %sr)r2)r r!r!r"r%�szRich_Drop.__str__N)r&r'r(r%r!r!r!r"r�sc@s&eZdZddd�Zdd�Zdd�ZdS)	rNcCs||_||_dS)N)�setr2)r Z_setr2r!r!r"r#�szRich_Mark.__init__cCsd|j|jrd|jndfS)Nz
mark set=%s%sz %sr)r9r2)r r!r!r"r%�szRich_Mark.__str__cCs�|jdk	r|j}nttjd��d|krv|jd�}t|�dkrHttj|��tj|d�shtj|d�r�ttj|��ntj|�s�ttj|��dS)Nzno value set�/�r�)r9rrZINVALID_MARK�split�lenrZcheckUINT32)r �x�splitsr!r!r"r8�s


zRich_Mark.check)N)r&r'r(r#r%r8r!r!r!r"r�s
r<�<�)�s�m�h�dc@s�eZdZddd�Zdd�Zedd��Zejdd��Zed	d
��Zejdd
��Ze	dd
��Z
dd�Ze	dd��Zdd�Z
dd�ZdS)rNcCs||_||_dS)N)r,�burst)r r,rGr!r!r"r#�szRich_Limit.__init__cCs|j�|j�dS)N)�value_parse�burst_parse)r r!r!r"r8�szRich_Limit.checkcCs|jS)N)�_value)r r!r!r"r,�szRich_Limit.valuecCsf|dkrd|_dSy|j|�\}}Wntk
r<|}YnX|�d|��}t|dd�|krb||_dS)Nr:rJ)rJ�_value_parser�getattr)r r,�rate�duration�vr!r!r"r,�s
cCs|jS)N)�_burst)r r!r!r"rGszRich_Limit.burstcCs\|dkrd|_dSy|j|�}Wntk
r8|}Yn
Xt|�}t|dd�|krX||_dS)NrP)rP�_burst_parser�strrL)r rG�br!r!r"rGs
cCs�d}d|kr|jd�}|s(t|�dkr4ttj|��|\}}yt|�}Wnttj|��YnX|dkrv|dd�}|dks�|dkr�ttj|��dt||d
kr�ttjd|f��|dkr�|dkr�ttjd|f��||fS)Nr:r;�second�minute�hour�dayr<rCrDrErFi'rz%s too fastz%s too slow)rTrUrVrW)rCrDrErF)r=r>rr�
INVALID_LIMIT�int�DURATION_TO_MULT)r,r@rMrNr!r!r"rKs&
zRich_Limit._value_parsecCs|j|j�S)N)rKrJ)r r!r!r"rH:szRich_Limit.value_parsec	CsR|dkrdSyt|�}Wnttj|��YnX|dksB|dkrNttj|��|S)Nr<i���)rYrrrX)rGrSr!r!r"rQ=szRich_Limit._burst_parsecCs|j|j�S)N)rQrP)r r!r!r"rIKszRich_Limit.burst_parsecCs,d|j�d�}|jdk	r(|d|j��7}|S)Nz
limit value="�"z burst=)rJrP)r rCr!r!r"r%Ns
zRich_Limit.__str__)N)r&r'r(r#r8�propertyr,�setterrG�staticmethodrKrHrQrIr%r!r!r!r"r�s
c@s>eZdZdZdZddd�Zdd�Zd	d
�Zdd�Zd
d�Z	dS)ri�i�NrcCsV|dk	rt|�|_nd|_||_d|_d|_d|_d|_d|_d|_|rR|j	|�dS)N)
rRr7�priority�source�destination�element�log�audit�action�_import_from_string)r r7�rule_strr_r!r!r"r#XszRich_Rule.__init__cCs�g}x|tj|�D]n}d|krp|jd�}t|�dksF|dsF|drVttjd|��|j|d|dd��q|jd|i�qW|jddi�|S)	z Lexical analysis �=r;rr<zinternal error in _lexer(): %s)�	attr_name�
attr_valuerb�EOL)rZ	splitArgsr=r>rrr�append)r rg�tokens�r�attrr!r!r"�_lexeris
 
zRich_Rule._lexercCs�|sttjd��tj|�}d|_d|_d|_d|_d|_	d|_
d|_d|_|j
|�}|rv|djd�dkrvttjd��i}g}d}�x`||jd�dko�|dgk�s�||jd�}||jd�}||jd�}|�r�|dHk�r�ttjd|���n�|dIk�r�|dk�r|j�rttjd+��n�|dk�r<|j�r<ttjd,��n�|dJk�rf|j	�rfttjd-||j	f��nh|d"k�r�|j
�r�ttjd.��nH|d#k�r�|j�r�ttjd/��n(|dKk�r�|j�r�ttjd0||jf��nttjd1|��t|�dk�r�|t|�d2nd3}	|	d3k�r�|�r`|�r`|d	k�r2ttjd4��n,|dk�rJttjd5��nttjd6||f��n*d|k�r�ttjd7||f��n
|jd��nL|	dk�rD|d	k�r�|dLk�r�ttjd:|��||_n||dk�ryt|�|_Wn&tk
�rttjd;|��YnXn:|�r6|dk�rd<}
nd=||f}
ttj|
��n
|j|��n�|	dk�r�|dMk�rb|||<nV|dNk�rvd>|d
<nBt|jd
�|jd�|jd�|jd
d?��|_|j�|j�|d2}�n|	dk�r,|dOk�r�|||<nN|dPk�r�d>|d
<n:t|jd
�|jd�|jd
d?��|_|j�|j�|d2}�n�|	dk�rd|dk�rTt|�|_	|j�nttjd@���nv|	dk�r�|dk�r�t|�|_	|j�nttjdA���n>|	dk�r�|dQk�r�|||<n0t|jd�|jd��|_	|j�|j�|d2}�n�|	dk�r&|dk�rt|�|_	|j�nttjdB���n�|	dk�r^|dk�rNt|�|_	|j�nttjdC���n||	dk�r�t�|_	|j�|j�|d2}�nN|	d k�r�|dRk�r�|||<n@t|jd�|jd�|jd�|jd��|_	|j�|j�|d2}�n�|	d!k�r@|dSk�r|||<n0t|jd�|jd��|_	|j�|j�|d2}�n�|	d"k�r�|dTk�r^|||<nN|d(k�rt|jd(�n8t |jd�|jd�|jd(��|_
|j�|j�|d2}�n*|	d#k�r�|d(k�r�|jd(�n(t!|jd(��|_|j�|j�|d2}�n�|	d$k�rH|d(k�r|jd(�n(t"|jd(��|_|j�|j�|d2}�n�|	d%k�r�|d(k�rh|jd(�n(t#|jd(��|_|j�|j�|d2}�nF|	d&k�r�|dk�r�|||<nF|d(k�r�|jd(�n0t$|jd�|jd(��|_|j�|j�|d2}n�|	d'k�r`|dk�r|||<nF|d(k�r.|jd(�n0t%|jd�|jd(��|_|j�|j�|d2}nz|	d(k�r�|dUk�r�||dD|��<nVdE|k�r�ttjdF��t&|dE|jdG��|d(<|jdEd�|jdGd�|j�|d2}|d2}q�W|j'�dS)VNz
empty rulerrbrk�rulerirjr_r7�addressrrrr,r*r+�to-port�to-addrr)r0r1r3r9rGzbad attribute '%s'r`ra�service�
icmp-block�	icmp-typer-�forward-port�source-portrcrd�accept�drop�reject�markr2�not�NOTzmore than one 'source' elementz#more than one 'destination' elementzFmore than one element. There cannot be both '%s' and '%s' in one rule.zmore than one 'log' elementzmore than one 'audit' elementzOmore than one 'action' element. There cannot be both '%s' and '%s' in one rule.zunknown element %sr<rz0'family' outside of rule. Use 'rule family=...'.z4'priority' outside of rule. Use 'rule priority=...'.z:'%s' outside of any element. Use 'rule <element> %s= ...'.z,'%s' outside of rule. Use 'rule ... %s ...'.r4r5zH'family' attribute cannot have '%s' value. Use 'ipv4' or 'ipv6' instead.z(invalid 'priority' attribute value '%s'.zdwrong 'protocol' usage. Use either 'rule protocol value=...' or  'rule [forward-]port protocol=...'.zDattribute '%s' outside of any element. Use 'rule <element> %s= ...'.TFzinvalid 'protocol' elementzinvalid 'service' elementzinvalid 'icmp-block' elementzinvalid 'icmp-type' elementzlimit.zlimit.valuezinvalid 'limit' elementzlimit.burst)r_r7rrrrrr,r*r+rsrtr)r0r1r3r9rG)rqr`rar+rur*rvrwr-rxryrcrdrzr{r|r}r2r~rrk)r+rur*rvrwr-rxry)rzr{r|r})r4r5)rrrrr)r~r)rrrr)r~r)r*r+)r*r+rsrt)r*r+)r0r1)r,rG)(rrrrZstripNonPrintableCharactersr_r7r`rarbrcrdrerp�getr>rlrY�
ValueError�INVALID_PRIORITYr�pop�clearrrrrrrrr
r	rrr
rrrrr8)r rgrmZattrsZin_elements�indexrbrirjZ
in_elementZerr_msgr!r!r"rfzs�

""













*




"






















(






 




















zRich_Rule._import_from_stringc	Cs`|jdk	r"|jd kr"ttj|j��|jdkrn|jdk	rB|jjdk	sL|jdk	rVttj��t|j	�t
krnttj��|j|jks�|j|j
kr�ttjd|j|j
f��|j	dko�|jdks�|jdk	o�|jdk�r
|jdkr�ttjd��|jdko�|jdko�|jdk�r
ttjd��t|j	�tt
tgk�rP|jdk�rP|jdk�rP|jdk�rPttjd��|jdk	�rj|jjdk	�r�|jdk�r�ttj��|jjdk	�r�ttjd��|jjdk	�r�ttjd	��tj|j|jj��sjttjt|jj���n�|jjdk	�r,|jjdk	�rttjd
��tj|jj��sjttjt|jj���n>|jjdk	�r^t|jj��sjttjt|jj���nttjd��|jdk	�r|jjdk	�r�|jdk�r�ttj��|jjdk	�r�ttjd	��tj|j|jj��sttjt|jj���n>|jjdk	�rt|jj��sttjt|jj���nttjd��t|j	�t k�rd|j	j!dk�sLt"|j	j!�d
k�r`ttj#t|j	j!����n�t|j	�t$k�r�tj%|j	j&��s�ttj'|j	j&��|j	j(d!k�r`ttj)|j	j(���n�t|j	�t*k�r�tj+|j	j,��s`ttj)|j	j,���nvt|j	�tk�r<|jdk	�rttjd��|jdk	�r`|jjdk	�r`ttjd���n$t|j	�tk�r�|j	j!dk�slt"|j	j!�d
k�r�ttj-t|j	j!���|j�r`ttjd���n�t|j	�t.k�r�|j	j!dk�s�t"|j	j!�d
k�r`ttj-t|j	j!����n�t|j	�t
k�r�tj%|j	j&��sttj'|j	j&��|j	j(d"k�r.ttj)|j	j(��|j	j/dk�rZ|j	j0dk�rZttj'|j	j/��|j	j/dk�r�tj%|j	j/��r�ttj'|j	j/��|j	j0dk�r�tj1|j|j	j0��r�ttj|j	j0��|jdk�r�ttj��|jdk	�r`ttjd��nrt|j	�t2k�r>tj%|j	j&��sttj'|j	j&��|j	j(d#k�r`ttj)|j	j(��n"|j	dk	�r`ttjdt|j	���|jdk	�r�|jj3�r�|jj3d$k�r�ttj4|jj3��|jj5dk	�r�|jj5j6�|jdk	�r�t|j�t7t8t9gk�r�ttj:t|j���|jj5dk	�r�|jj5j6�|jdk	�r\t|j�t8k�r(|jj6|j�nt|j�t;k�rB|jj6�|jj5dk	�r\|jj5j6�dS)%Nr4r5z/'priority' attribute must be between %d and %d.rzno element, no actionz%no element, no source, no destinationzno action, no log, no auditzaddress and maczaddress and ipsetz
mac and ipsetzinvalid sourcezinvalid destinationr<�tcp�udp�sctp�dccpzmasquerade and actionzmasquerade and mac sourcezicmp-block and actionrzforward-port and actionzUnknown element %s�emerg�alert�crit�error�warning�notice�info�debug)r4r5)r�r�r�r�)r�r�r�r�)r�r�r�r�)r�r�r�r�r�r�r�r�)<r7rrZINVALID_FAMILYr`rraZMISSING_FAMILYr3rbr
r_�priority_min�priority_maxr�rcrerrrrdrrrZ
check_addressZINVALID_ADDRrRZ	check_macZINVALID_MACrZ
INVALID_IPSETZINVALID_DESTINATIONrr)r>ZINVALID_SERVICErZ
check_portr*ZINVALID_PORTr+ZINVALID_PROTOCOLrZ
checkProtocolr,ZINVALID_ICMPTYPErr.r/Zcheck_single_addressr	r1ZINVALID_LOG_LEVELr2r8r
rrZINVALID_AUDIT_TYPEr)r r!r!r"r8hs�




 
 



   


zRich_Rule.checkcCs�d}|jr|d|j7}|jr,|d|j7}|jr@|d|j7}|jrT|d|j7}|jrh|d|j7}|jr||d|j7}|jr�|d|j7}|jr�|d|j7}tj	r�tj
|�S|S)Nrqz priority="%d"z family="%s"z %s)r_r7r`rarbrcrdrerZPY2Zu2b)r r$r!r!r"r%s$zRich_Rule.__str__i���)NNr)
r&r'r(r�r�r#rprfr8r%r!r!r!r"rTs
o-Nii�i�Q)�__all__ZfirewallrZfirewall.core.ipsetrZfirewall.core.baserrZfirewall.errorsr�objectrrrrr	rrrrr
rrr
rrrrZrrr!r!r!r"�<module>s@
dcore/__pycache__/watcher.cpython-36.opt-1.pyc000064400000005256150351351730014741 0ustar003

��g��@s*dgZddlmZmZGdd�de�ZdS)�Watcher�)�Gio�GLibc@sdeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dS)rcCs"||_||_i|_i|_g|_dS)N)�	_callback�_timeout�	_monitors�	_timeouts�_blocked)�self�callbackZtimeout�r�/usr/lib/python3.6/watcher.py�__init__s
zWatcher.__init__cCs:tjj|�}|jtjjd�|j|<|j|jd|j�dS)N�changed)	r�File�new_for_pathZmonitor_directory�FileMonitorFlags�NONEr�connect�_file_changed_cb)r
Z	directory�gfilerrr
�
add_watch_dir"szWatcher.add_watch_dircCs:tjj|�}|jtjjd�|j|<|j|jd|j�dS)Nr)	rrrZmonitor_filerrrrr)r
�filenamerrrr
�add_watch_file(szWatcher.add_watch_filecCs
|jj�S)N)r�keys)r
rrr
�get_watches.szWatcher.get_watchescCs
||jkS)N)r)r
rrrr
�	has_watch1szWatcher.has_watchcCs|j|=dS)N)r)r
rrrr
�remove_watch4szWatcher.remove_watchcCs||jkr|jj|�dS)N)r	�append)r
rrrr
�block_source7s
zWatcher.block_sourcecCs||jkr|jj|�dS)N)r	�remove)r
rrrr
�unblock_source;s
zWatcher.unblock_sourcecCs4x.t|jj��D]}tj|j|�|j|=qWdS)N)�listrrr�
source_remove)r
rrrr
�clear_timeouts?szWatcher.clear_timeoutscCs ||jkr|j|�|j|=dS)N)r	rr)r
rrrr
�_call_callbackDs

zWatcher._call_callbackcCs�|j�}||jkr8||jkr4tj|j|�|j|=dS|tjjksh|tjjksh|tjj	ksh|tjj
kr�||jkr�tj|j|�|j|=tj|j|j
|�|j|<dS)N)Zget_parse_namer	rrr#rZFileMonitorEventZCHANGEDZCREATEDZDELETEDZATTRIBUTE_CHANGEDZtimeout_add_secondsrr%)r
ZmonitorZgio_fileZgio_other_fileZeventrrrr
rIs


zWatcher._file_changed_cbN)�__name__�
__module__�__qualname__rrrrrrrr!r$r%rrrrr
rsN)�__all__Z
gi.repositoryrr�objectrrrrr
�<module>score/__pycache__/prog.cpython-36.pyc000064400000001266150351351730013311 0ustar003

��g��@sddlZdgZddd�ZdS)�N�runProgc
Cs�|dkrg}|g|}d}|r@t|d��}|j�j�}WdQRXddi}y tj|tjtjtjd|d�}Wntk
r|d
SX|j|�\}}	|j	dd	�}|j
|fS)N�rZLANG�CT)�stdin�stderr�stdoutZ	close_fds�env��zutf-8�replace)r	r
)�open�read�encode�
subprocess�Popen�PIPEZSTDOUT�OSErrorZcommunicate�decode�
returncode)
�prog�argvr�argsZinput_stringZhandlerZprocess�outputZ
err_output�r�/usr/lib/python3.6/prog.pyrs$

)NN)r�__all__rrrrr�<module>score/__pycache__/fw.cpython-36.opt-1.pyc000064400000066115150351351730013721 0ustar003

��g���@s�dgZddlZddlZddlZddlZddlZddlmZddlm	Z	ddl
mZddl
mZddl
m
Z
ddl
mZdd	l
mZdd
lmZddlmZddlmZdd
lmZddlmZddlmZddlmZddlmZddl m!Z!ddl"m#Z#ddl$m%Z%m&Z&ddl'm(Z(ddl)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0ddl1m2Z2m3Z3ddl4m5Z5ddl6m7Z7ddl8m9Z9ddl:m;Z;ddlm<Z<dd l=m>Z>Gd!d�de?�Z@dS)"�Firewall�N)�config)�	functions)�	ipXtables)�ebtables)�nftables)�ipset)�modules)�FirewallIcmpType)�FirewallService)�FirewallZone)�FirewallDirect)�FirewallConfig)�FirewallPolicies)�
FirewallIPSet)�FirewallTransaction)�FirewallHelper)�FirewallPolicy)�nm_get_bus_name�nm_get_interfaces_in_zone)�log)�firewalld_conf)�Direct)�service_reader)�icmptype_reader)�zone_reader�Zone)�ipset_reader)�IPSET_TYPES)�
helper_reader)�
policy_reader)�errors)�
FirewallErrorc@s�eZdZdedd�Zdd�Zdd�Zdd	�Zd
d�Zdfdd
�Zdd�Z	dgdd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zdhd)d*�Zdid+d,�Zd-d.�Zdjd/d0�Zdkd1d2�Zdld3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Zd=d>�Z d?d@�Z!dAdB�Z"dCdD�Z#dEdF�Z$dGdH�Z%dIdJ�Z&dKdL�Z'dMdN�Z(dmdOdP�Z)dQdR�Z*dSdT�Z+dUdV�Z,dWdX�Z-dYdZ�Z.d[d\�Z/d]d^�Z0d_d`�Z1dadb�Z2dcdd�Z3d(S)nrFcCsttj�|_||_|jr>d|_d|_d|_d|_t	|_
d|_nrtj
|�|_d|_g|_tj|�|_d|_g|_tj�|_d|_tj�|_d|_g|_
tj|�|_d|_tj�|_t|�|_t|�|_t|�|_ t!|�|_"t#|�|_t$�|_%t&|�|_t'|�|_(t)|�|_*|j+�dS)NFT),rr�FIREWALLD_CONF�_firewalld_conf�_offline�ip4tables_enabled�ip6tables_enabled�ebtables_enabled�
ipset_enabledr�ipset_supported_types�nftables_enabledr�	ip4tables�ip4tables_backend�ipv4_supported_icmp_types�	ip6tables�ip6tables_backend�ipv6_supported_icmp_typesr�ebtables_backendr�
ipset_backendr�nftables_backendr	�modules_backendr
�icmptyper�servicer�zoner
�directrr�policiesrr�helperr�policy�_Firewall__init_vars)�selfZoffline�r?�/usr/lib/python3.6/fw.py�__init__CsB










zFirewall.__init__cCsDd|j|j|j|j|j|j|j|j|j|j	|j
|j|j|j
|jfS)Nz:%s(%r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r))�	__class__r&r'r(�_state�_panic�
_default_zone�_module_refcount�_marks�cleanup_on_exit�cleanup_modules_on_exit�ipv6_rpfilter_enabledr)�_individual_calls�_log_denied)r>r?r?r@�__repr__kszFirewall.__repr__cCsjd|_d|_d|_i|_g|_tj|_tj|_	tj
|_tj|_
tj|_tj|_tj|_tj|_tj|_dS)NZINITF�)rCrDrErFrGrZFALLBACK_CLEANUP_ON_EXITrHZ FALLBACK_CLEANUP_MODULES_ON_EXITrIZFALLBACK_IPV6_RPFILTERrJZFALLBACK_INDIVIDUAL_CALLSrKZFALLBACK_LOG_DENIEDrLZFALLBACK_FIREWALL_BACKEND�_firewall_backendZFALLBACK_FLUSH_ALL_ON_RELOAD�_flush_all_on_reloadZFALLBACK_RFC3964_IPV4�
_rfc3964_ipv4ZFALLBACK_ALLOW_ZONE_DRIFTING�_allow_zone_drifting)r>r?r?r@Z__init_varstszFirewall.__init_varscCs�|jr$d|jj�kr$tjd�d|_|jrHd|jj�krHtjd�d|_|jrld|jj�krltjd�d|_|jr�|jr�|j	r�tj
d�tjd�dS)N�filterziptables is not usable.Fzip6tables is not usable.zebtables is not usable.zNo IPv4 and IPv6 firewall.�)
r&r-�get_available_tablesr�info1r'r0r(r2r+�fatal�sys�exit)r>r?r?r@�
_check_tables�s 



zFirewall._check_tablescCszy|jj�Wn*tk
r8tjd�d|_g|_YnX|jj�|_|jj	�|jj
s||jjrltjd�ntjd�d|_|j
r�|jjd�|_n|jr�|jj�|_ng|_|jj	�|jj
s�|jjr�tjd�ntjd�d|_|j
r�|jjd�|_n|j�r|jj�|_ng|_|jj	�|jj
�sN|jj�r>tjd	�ntjd
�d|_|j�rv|j�rv|jj�rvtjd�dS)Nz4ipset not usable, disabling ipset usage in firewall.FzFiptables-restore is missing, using individual calls for IPv4 firewall.zCiptables-restore and iptables are missing, disabling IPv4 firewall.�ipv4zGip6tables-restore is missing, using individual calls for IPv6 firewall.zEip6tables-restore and ip6tables are missing, disabling IPv6 firewall.�ipv6zHebtables-restore is missing, using individual calls for bridge firewall.zEebtables-restore and ebtables are missing, disabling bridge firewall.zSebtables-restore is not supporting the --noflush option, will therefore not be used)r3Zset_list�
ValueErrorr�warningr)r*Zset_supported_typesr-Zfill_exists�restore_command_existsZcommand_existsr&r+r4Zsupported_icmp_typesr.r0r'r1r2r(rK�restore_noflush_option�debug1)r>r?r?r@�_start_check�sL








zFirewall._start_checkc>Cs�tj}tjdtj�y|jj�Wn8tk
rZ}ztj|�tjd�WYdd}~X�n"X|jj	d�rt|jj	d�}|jj	d�r�|jj	d�}|dk	r�|j
�dBkr�d|_tjd|j�|jj	d	��r|jj	d	�}|dk	r�|j
�dCkr�d|_|dk	�r|j
�dDk�rd|_tjd
|j�|jj	d��rv|jj	d�}|dk	�rv|j
�dEk�rvtjd�y|j
j�Wntk
�rtYnX|jj	d��r�|jj	d�}|dk	�r�|j
�dFk�r�d|_|j
�dGk�r�d|_|j�r�tjd�n
tjd�|jj	d��r"|jj	d�}|dk	�r"|j
�dHk�r"tjd�d|_|jj	d��rt|jj	d�}|dk�sT|j
�dk�r\d|_n|j
�|_tjd|j�|jj	d��r�|jj	d�|_tjd|j�|jj	d��r�|jj	d�}|j
�dIk�r�d|_nd|_tjd|j�|jj	d��r&|jj	d�}|j
�dJk�rd|_nd|_tjd|j�|jj	d��r||jj	d�}|j
�dKk�rVd|_nd|_|j�sntjd�tjd |j�|jjtj|j��|j|j�|j�s�|j�tjd!�y|j
jj�WnZtk
�r }z<|j
j��r�tjd"|j
jj |�ntjd"|j
jj |�WYdd}~XnX|jj!tj|j
��|j"tj#d#�|j"tj$d#�|j"tj%d$�|j"tj&d$�t'|j(j)��d%k�r�tjd&�|j"tj*d'�|j"tj+d'�|j"tj,d(�|j"tj-d(�t'|j.j/��d%k�r�tjd)�|j"tj0d*�|j"tj1d*�t'|j2j3��d%k�r&tj4d+�t5j6d,�|j"tj7d-�|j"tj8d-�d}x.dLD]&}||j2j3�k�rLtj4d1|�d}�qLW|�r�t5j6d,�||j2j3�k�r�d2|j2j3�k�r�d2}nd3|j2j3�k�r�d3}nd.}tjd4||�|}ntjd5|�t9tj:�}	t;j<j=tj:��rRtjd6tj:�y|	j�Wn4tk
�rP}ztjd7tj:|�WYdd}~XnX|j>j?|	�|jj@tj|	��|jA|�|_B|j�r�dS|jC�tjD�d%k�r�tEjE�}
tF|�}|�s�|jG|d8�|�r�|�s�|jH�r�|jIjJ��r�|jKd�|jL�|�r|�rtjd9�|jMjN�|jO|d8�|jKd�|jL�|jH�rX|jIjJ��rXtjd:�|jIjP�tjd;�|jQ|d8�tjd<�|j2jR|d8�|j2jSd|jB|d8�tjd=�|jTjU|d8�|jKd�|jL�|j>jV��rVtjd>�|j>jW|�y|jKd�|jL�WnXtk
�r>}z$t|jXd?|jY�r&|jYnd@��WYdd}~Xntk
�rT�YnX~tjD�d,k�r�tEjE�}
tjZdA|
|
�dS)MNz"Loading firewalld config file '%s'z0Using fallback firewalld configuration settings.�DefaultZoneZ
CleanupOnExit�no�falseFzCleanupOnExit is set to '%s'ZCleanupModulesOnExit�yes�trueTz#CleanupModulesOnExit is set to '%s'ZLockdownzLockdown is enabledZ
IPv6_rpfilterzIPv6 rpfilter is enabledzIPV6 rpfilter is disabledZIndividualCallszIndividualCalls is enabled�	LogDeniedZoffzLogDenied is set to '%s'ZFirewallBackendzFirewallBackend is set to '%s'ZFlushAllOnReloadzFlushAllOnReload is set to '%s'ZRFC3964_IPv4zRFC3964_IPv4 is set to '%s'ZAllowZoneDriftingz�AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a future release. Please consider disabling it now.z AllowZoneDrifting is set to '%s'zLoading lockdown whitelistz*Failed to load lockdown whitelist '%s': %srr6rzNo icmptypes found.r;r7zNo services found.r8zNo zones found.rTr<�block�drop�trustedzZone '%s' is not available.ZpublicZexternalz+Default zone '%s' is not valid. Using '%s'.zUsing default zone '%s'zLoading direct rules file '%s'z)Failed to load direct rules file '%s': %s)�use_transactionzUnloading firewall moduleszApplying ipsetszApplying default rule setzApplying used zoneszApplying used policiesz2Applying direct chains rules and passthrough rulesz
Direct: %srNz%Flushing and applying took %f seconds)rdre)rfrg)rdre)rfrg)rdre)rfrg)rfrg)rdre)rdre)rdre)rirjrk)[rZ
FALLBACK_ZONErrar#r$�read�	Exceptionr^�get�lowerrHrIr:Zenable_lockdownr"rJrKrLrOrPrQrRr%Zset_firewalld_conf�copy�deepcopy�_select_firewall_backendrbZlockdown_whitelistZquery_lockdown�error�filenameZset_policies�_loaderZFIREWALLD_IPSETSZETC_FIREWALLD_IPSETSZFIREWALLD_ICMPTYPESZETC_FIREWALLD_ICMPTYPES�lenr6�
get_icmptypesZFIREWALLD_HELPERSZETC_FIREWALLD_HELPERSZFIREWALLD_SERVICESZETC_FIREWALLD_SERVICESr7�get_servicesZFIREWALLD_ZONESZETC_FIREWALLD_ZONESr8�	get_zonesrWrXrYZFIREWALLD_POLICIESZETC_FIREWALLD_POLICIESrZFIREWALLD_DIRECT�os�path�existsr9Zset_permanent_configZ
set_direct�
check_zonerErZZgetDebugLogLevel�timer�flushr)rZ
has_ipsets�execute�clearr5�unload_firewall_modules�apply_default_tablesZapply_ipsets�apply_default_rulesZapply_zones�change_default_zoner<Zapply_policiesZhas_configurationZapply_direct�code�msgZdebug2)r>�reload�complete_reloadZdefault_zoner��valuert�zr8�objZtm1�transaction�eZtm2r?r?r@�_start�st







 




















.zFirewall._startcCsHy|j�Wn&tk
r2d|_|jd��YnXd|_|jd�dS)N�FAILED�ACCEPT�RUNNING)r�rnrC�
set_policy)r>r?r?r@�start�s
zFirewall.startcCshtjj|�sdS|rZ|jtj�rV|dkrVt�}tjj|�|_|j	|j�||_d|_
nd}�x|ttj|��D�]h}|j
d�s�|jtj�rl|dkrltjjd||f�rl|jd||f|dd�qld||f}tjd||��y�|dk�r�t||�}|j|jj�k�r8|jj|j�}tjd	||j|j|j�|jj|j�n|jjtj��rNd|_
y|jj|�Wn<tk
�r�}	ztjd
|jt|	�f�WYdd}	~	XnX|jjtj|���n�|dk�rFt||�}|j|jj�k�r|jj |j�}tjd	||j|j|j�|jj!|j�n|jjtj��r$d|_
|jj"|�|jj"tj|���n.|dk�rnt#|||d�}|�r�dtjj|�tjj|�d
d�f|_|j	|j�tj|�}
|j|j$j%�k�r|j$j&|j�}|j$j'|j�|j(�r�tjd||j||�|j)|�ntjd	||j|j|j�n|jjtj��r,d|_
d|
_
|jj*|
�|�r^tjd||j||�|j)|�n|j$j*|��n|dk�rDt+||�}|j|j,j-�k�r�|j,j.|j�}tjd	||j|j|j�|j,j/|j�n|jjtj��r�d|_
y|j,j0|�Wn<tk
�r,}	ztj1d
|jt|	�f�WYdd}	~	XnX|jj0tj|���n0|dk�r�t2||�}|j|j3j4�k�r�|j3j5|j�}tjd	||j|j|j�|j3j6|j�n|jjtj��r�d|_
|j3j7|�|jj7tj|��n�|dk�rht8||�}|j|j9j:�k�r2|j9j;|j�}tjd	||j|j|j�|j9j<|j�n|jjtj��rHd|_
|j9j=|�|jj>tj|��ntj?d|�Wqltk
�r�}ztj@d|||�WYdd}~XqltAk
�r�tj@d||�tjB�YqlXqlW|�rd|j(�rd|j|j$j%�k�rX|j$j&|j�}tjd||j|j|j�y|j$j'|j�WntAk
�rHYnX|jjC|j�|j$j*|�dS)Nr8Fz.xmlz%s/%sT)�combinezLoading %s file '%s'r6z  Overloads %s '%s' ('%s/%s')z%s: %s, ignoring for run-time.r7)Z
no_check_namer�z  Combining %s '%s' ('%s/%s')rr;r<zUnknown reader type %szFailed to load %s file '%s': %szFailed to load %s file '%s':z0  Overloading and deactivating %s '%s' ('%s/%s')���)Dr{r|�isdir�
startswithrZ
ETC_FIREWALLDr�basename�nameZ
check_name�default�sorted�listdir�endswithrvrrarr6rxZget_icmptyperuZremove_icmptypeZadd_icmptyper"rV�strrqrrrr7ryZget_serviceZremove_serviceZadd_servicerr8rzZget_zoneZremove_zone�combinedr�Zadd_zonerr�
get_ipsets�	get_ipsetZremove_ipset�	add_ipsetr^rr;Zget_helpersZ
get_helperZ
remove_helperZ
add_helperr r<�get_policiesZ
get_policyZ
remove_policyZ
add_policyZadd_policy_objectrWrtrnZ	exceptionZforget_zone)r>r|Zreader_typer�Z
combined_zonerur�r�Zorig_objrtZ
config_objr�r?r?r@rvs


$







$




zFirewall._loadercCsp|jj�|jj�|jj�|jj�|jj�|jj�|jj�|jj�|j	j�|j
j�|j�dS)N)r6�cleanupr7r8rr;rr9r:r<r$r=)r>r?r?r@r��s









zFirewall.cleanupcCsN|jsB|jr(|j�|jj�|jd�|jrBtjd�|jj	�|j
�dS)Nr�z!Unloading firewall kernel modules)r%rHr�rr�rIrrar5r�r�)r>r?r?r@�stop�s



z
Firewall.stopc	Cs�d}d}x�t|�D]�\}}|r0|jj|�\}}n$|j|dkrDd}n|jj|�\}}|dkrn|d7}||7}q|r�|jj|d�|j|d7<q||jkr|j|d8<|j|dkr|j|=qW||fS)NrrNrT)�	enumerater5�load_modulerFZ
unload_module�
setdefault)	r>Z_modules�enableZ
num_failedZ
error_msgs�i�moduleZstatusr�r?r?r@�handle_modules�s(
zFirewall.handle_modulescCs|dkrd|_dS)NrF)r+)r>�backendr?r?r@rs�sz!Firewall._select_firewall_backendcCs4x|j�D]}|j|kr
|Sq
Wttjd|��dS)Nz'%s' backend does not exist)�all_backendsr�r"r!Z
UNKNOWN_ERROR)r>r�r�r?r?r@�get_backend_by_name�s

zFirewall.get_backend_by_namecCs\|jr|jS|dkr |jr |jS|dkr4|jr4|jS|dkrH|jrH|jStt	j
d|��dS)Nr[r\�ebz-'%s' is not a valid backend or is unavailable)r+r4r&r-r'r0r(r2r"r!�INVALID_IPV)r>�ipvr?r?r@�get_backend_by_ipv�szFirewall.get_backend_by_ipvcCsP|dkr|jr|jS|dkr(|jr(|jS|dkr<|jr<|jSttjd|��dS)Nr[r\r�z-'%s' is not a valid backend or is unavailable)	r&r-r'r0r(r2r"r!r�)r>r�r?r?r@�get_direct_backend_by_ipv�sz"Firewall.get_direct_backend_by_ipvcCs<|dkr|jS|dkr|jS|dkr*|jS|dkr8|jSdS)Nr,r/rrF)r&r'r(r+)r>r�r?r?r@�is_backend_enabled�szFirewall.is_backend_enabledcCs8|jr
dS|dkr|jS|dkr&|jS|dkr4|jSdS)NTr[r\r�F)r+r&r'r()r>r�r?r?r@�is_ipv_enabledszFirewall.is_ipv_enabledcCsRg}|jr|j|j�n6|jr*|j|j�|jr<|j|j�|jrN|j|j�|S)N)	r+�appendr4r&r-r'r0r(r2)r>�backendsr?r?r@�enabled_backendsszFirewall.enabled_backendscCsPg}|jr|j|j�|jr(|j|j�|jr:|j|j�|jrL|j|j�|S)N)	r&r�r-r'r0r(r2r+r4)r>r�r?r?r@r�szFirewall.all_backendsNcCsN|dkrt|�}n|}x |j�D]}|j||j��q W|dkrJ|jd�dS)NT)rr��	add_rulesZbuild_default_tablesr�)r>rlr�r�r?r?r@r�$s
zFirewall.apply_default_tablescCs�|dkrt|�}n|}x(|j�D]}|j|j�}|j||�q W|jd�r~|jd�}d|j�kr~|jr~|j	|j�}|j||�|jd�r�|j
r�|j�}|j||�|dkr�|jd�dS)Nr\�rawT)
rr�Zbuild_default_rulesrLr�r�r�rUrJZbuild_rpfilter_rulesrQZbuild_rfc3964_ipv4_rulesr�)r>rlr�r��rulesZipv6_backendr?r?r@r�0s"


zFirewall.apply_default_rulescCs|jr|jj�rdSdS)NTF)r+r9Zhas_runtime_configuration)r>r?r?r@�may_skip_flush_direct_backendsHsz'Firewall.may_skip_flush_direct_backendscCs`|dkrt|�}n|}x2|j�D]&}||j�kr2q |j�}|j||�q W|dkr\|jd�dS)NT)rr�r��build_flush_rulesr�r�)r>rlr�r�r�r?r?r@�flush_direct_backendsNs
zFirewall.flush_direct_backendscCsp|dkrt|�}n|}tjd�|j�s4|j|d�x$|j�D]}|j�}|j||�q>W|dkrl|jd�dS)NzFlushing rule set)rlT)	rrrar�r�r�r�r�r�)r>rlr�r�r�r?r?r@r�]s

zFirewall.flushcCs`|dkrt|�}n|}tjd|�x&|j�D]}|j|�}|j||�q,W|dkr\|jd�dS)NzSetting policy to '%s'T)rrrar�Zbuild_set_policy_rulesr�r�)r>r<rlr�r�r�r?r?r@r�os

zFirewall.set_policycCsB|sdS|j|�}|s&ttjd|��|j|�s4dS|j||j�S)NrNz'%s' is not a valid backend)r�r"r!r�r��set_rulerL)r>�backend_name�ruler�r?r?r@r��s


z
Firewall.rulecCs"ttd|��}|j|�}|s,ttjd|��|j|�s:dS|js\|js\|dkoX|j	j
�rx�t|�D]�\}}y|j||j
�Wqftk
�r}zjtjtj��tj|�xFt|d|��D]2}y|j|j|�|j
�Wq�tk
r�Yq�Xq�W|�WYdd}~XqfXqfWn|j||j
�dS)Nz'%s' is not a valid backendr)�listrSr�r"r!r�r�rKr_r2r`r�r�rLrnrra�	traceback�
format_excrt�reversedZreverse_ruleZ	set_rules)r>r�r�Z_rulesr�r�r�r�r?r?r@r��s.




zFirewall.rulescCs|jrttj��dS)N)rDr"r!Z
PANIC_MODE)r>r?r?r@�check_panic�szFirewall.check_paniccCs"|}||jj�krttj|��|S)N)r<r�r"r!ZINVALID_POLICY)r>r<Z_policyr?r?r@�check_policy�szFirewall.check_policycCs8|}|s|dkr|j�}||jj�kr4ttj|��|S)NrN)�get_default_zoner8rzr"r!ZINVALID_ZONE)r>r8�_zoner?r?r@r~�szFirewall.check_zonecCstj|�sttj|��dS)N)rZcheckInterfacer"r!ZINVALID_INTERFACE)r>�	interfacer?r?r@�check_interface�s
zFirewall.check_interfacecCs|jj|�dS)N)r7�
check_service)r>r7r?r?r@r��szFirewall.check_servicecCstj|�sttj|��dS)N)r�
check_portr"r!ZINVALID_PORT)r>Zportr?r?r@r��s
zFirewall.check_portcCs*|sttj��|dkr&ttjd|��dS)N�tcp�udp�sctp�dccpz''%s' not in {'tcp'|'udp'|'sctp'|'dccp'})r�r�r�r�)r"r!ZMISSING_PROTOCOLZINVALID_PROTOCOL)r>Zprotocolr?r?r@�check_tcpudp�s
zFirewall.check_tcpudpcCstj|�sttj|��dS)N)rZcheckIPr"r!�INVALID_ADDR)r>Zipr?r?r@�check_ip�s
zFirewall.check_ipcCsP|dkr tj|�sLttj|��n,|dkr@tj|�sLttj|��nttjd��dS)Nr[r\z'%s' not in {'ipv4'|'ipv6'})rZcheckIPnMaskr"r!r�Z
checkIP6nMaskr�)r>r��sourcer?r?r@�
check_address�s

zFirewall.check_addresscCs|jj|�dS)N)r6�check_icmptype)r>Zicmpr?r?r@r��szFirewall.check_icmptypecCs>t|t�std|t|�f��t|�dkr:ttjd|��dS)Nz%s is %s, expected intrz#timeout '%d' is not positive number)�
isinstance�int�	TypeError�typer"r!�
INVALID_VALUE)r>Ztimeoutr?r?r@�
check_timeout�s

zFirewall.check_timeoutc Cs`|j}|j}|sNi}x&|jj�D]}|jj|�d||<q W|jj�}|j�}g}x$|jj	�D]}	|j
|jj|	��q^W|s�|jd�|j
�|j�d}
y|jd|d�Wn&tk
r�}z
|}
WYdd}~XnX|�r(xL|D]D}|jj|j�s�x0|jj�D]"}
|
jdk�r�q�|
j|j��q�Wq�W|�s�|j�}||k�r�||k�rRi||<xFt||j��D]2\}}|d�rd||||||<|||=�qdWxb|jj�D]T}||k�r�x.||D]"}|jj|||||d��q�W||=ntjd|��q�Wt|�d	k�r6x(t|j��D]}tjd
|�||=�qW~x�|D]�}|jj|j��r�xx|jD]R}y|jj|j|�Wn6tk
�r�}z|jt j!k�r�|�WYdd}~XnX�qZWn|jj"|�|jj#|j��q>W|jj$|�t%�}|�r,x@|jj�dgD],}x$t&|�D]}|jj|||d��q
W�q�W||_|j�sD|jd
�|
�rVd|_'|
�nd|_'dS)N�
interfacesZDROPT)r�r�r�__default__�senderzNew zone '%s'.rz(Lost zone '%s', zone interfaces dropped.rN)r�r�r�r�)(rDrPr8rz�get_settingsr9Zget_runtime_configr�rr�r�r�r�r�r�r�rnZquery_ipsetr�r�Zset_destroyr��items�change_zone_of_interfacerrVrw�keysZentriesZ	add_entryr"r�r!�ALREADY_ENABLEDr�Zapply_ipsetZ
set_configrrrC)r>r�rDZ	flush_allZ_zone_interfacesr8Z_direct_config�_old_dzZ_ipset_objs�_nameZstart_exceptionr�r�r�Z_new_dz�iface�settingsZinterface_id�entryr�Znm_bus_namer�r?r?r@r��s�









zFirewall.reloadcCs|jS)N)rC)r>r?r?r@�	get_stateaszFirewall.get_statecCsZ|jrttjd��y|jd�Wn.tk
rN}zttj|��WYdd}~XnXd|_dS)Nzpanic mode already enabledZPANICT)rDr"r!r�r�rn�COMMAND_FAILED)r>r�r?r?r@�enable_panic_modefszFirewall.enable_panic_modecCsZ|jsttjd��y|jd�Wn.tk
rN}zttj|��WYdd}~XnXd|_dS)Nzpanic mode is not enabledr�F)rDr"r!ZNOT_ENABLEDr�rnr�)r>r�r?r?r@�disable_panic_modeqszFirewall.disable_panic_modecCs|jS)N)rD)r>r?r?r@�query_panic_mode|szFirewall.query_panic_modecCs|jS)N)rL)r>r?r?r@�get_log_denied�szFirewall.get_log_deniedcCsb|tjkr&ttjd|djtj�f��||j�krR||_|jj	d|�|jj
�nttj|��dS)Nz'%s', choose from '%s'z','rh)rZLOG_DENIED_VALUESr"r!r��joinr�rLr$�set�writeZALREADY_SET)r>r�r?r?r@�set_log_denied�s
zFirewall.set_log_deniedcCs|jS)N)rE)r>r?r?r@r��szFirewall.get_default_zonecCs�|j|�}||jkr�|j}||_|jjd|�|jj�|jj||�|jj|�}x@t|dj	��D]\}}|drd|jj
d|�qdWnttj
|��dS)Nrcr�r�rN)r~rEr$r�r�r8r�r�r�r�r�r"r!ZZONE_ALREADY_SET)r>r8r�r�Z_old_dz_settingsr�r�r?r?r@�set_default_zone�s


zFirewall.set_default_zonecCsH|j�}x:|j�D].\}}|s(t|t�r2|||<q||kr||=qW|S)N)rqr�r��bool)r>Z	permanentZruntimer��keyr�r?r?r@�'combine_runtime_with_permanent_settings�s

z0Firewall.combine_runtime_with_permanent_settingscCsi}i}x�t|j��t|j��BD]�}||kr"t||t�r�t||krN||ng�}tt||�|�||<t|t||�A|@�||<q"t||t�s�t||t�r�||r�||r�d||<q�||r�||r�d||<q"ttjdj	t
||�|���q"W||fS)NTFz Unhandled setting type {} key {})r�r�r�r�r�r�r"r!ZINVALID_SETTING�formatr�)r>Zold_settingsZnew_settingsZadd_settingsZremove_settingsr��oldr?r?r@�get_added_and_removed_settings�s

 z'Firewall.get_added_and_removed_settings)F)FF)F)N)N)N)N)N)F)4�__name__�
__module__�__qualname__rArMr=rZrbr�r�rvr�r�r�rsr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r~r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r?r?r?r@rBsh
(	;
 








 	
s)A�__all__Zos.pathr{rXrqrr�ZfirewallrrZ
firewall.corerrrrr	Zfirewall.core.fw_icmptyper
Zfirewall.core.fw_servicerZfirewall.core.fw_zonerZfirewall.core.fw_directr
Zfirewall.core.fw_configrZfirewall.core.fw_policiesrZfirewall.core.fw_ipsetrZfirewall.core.fw_transactionrZfirewall.core.fw_helperrZfirewall.core.fw_policyrZfirewall.core.fw_nmrrZfirewall.core.loggerrZfirewall.core.io.firewalld_confrZfirewall.core.io.directrZfirewall.core.io.servicerZfirewall.core.io.icmptyperZfirewall.core.io.zonerrZfirewall.core.io.ipsetrZfirewall.core.ipsetrZfirewall.core.io.helperrZfirewall.core.io.policyr r!Zfirewall.errorsr"�objectrr?r?r?r@�<module>sHcore/__pycache__/base.cpython-36.pyc000064400000002172150351351730013251 0ustar003

��g6�@s�dZdZdZd0ZdddedgZddddgZd	d
ddd
dd�Zddddddddddddddddgd d!d"d#d$d%d&ddg	d'�Zd(d)d*d+d,d-d.gZd/S)1zBase firewall settingsz{chain}_{zone}ZCONTINUE�ZACCEPTz
%%REJECT%%ZDROP�defaultZREJECTZPREZPOST�INZFWDIZFWDOZOUT)Z
PREROUTINGZPOSTROUTINGZINPUTZ
FORWARD_INZFORWARD_OUTZOUTPUTzicmp-host-prohibitedzhost-prohibzicmp-net-unreachableznet-unreachzicmp-host-unreachablezhost-unreachzicmp-port-unreachablezport-unreachzicmp-proto-unreachablez
proto-unreachzicmp-net-prohibitedz
net-prohibz	tcp-resetztcp-rstzicmp-admin-prohibitedzadmin-prohibzicmp6-adm-prohibitedzadm-prohibitedzicmp6-no-routezno-routezicmp6-addr-unreachablezaddr-unreachzicmp6-port-unreachable)Zipv4Zipv6zhash:ipzhash:ip,portzhash:ip,markzhash:netz
hash:net,portzhash:net,ifacezhash:macN���)	�__doc__ZDEFAULT_ZONE_TARGETZDEFAULT_POLICY_TARGETZDEFAULT_POLICY_PRIORITYZZONE_TARGETSZPOLICY_TARGETSZ	SHORTCUTSZREJECT_TYPESZSOURCE_IPSET_TYPES�rr�/usr/lib/python3.6/base.py�<module>s.core/__pycache__/nftables.cpython-36.opt-1.pyc000064400000130376150351351730015104 0ustar003

��g��%@slddlmZddlZddlZddlZddlmZddlmZm	Z	m
Z
mZmZddl
mZmZmZmZmZmZmZddlmZmZmZmZmZmZmZddlmZdZed	d
Z dZ!dZ"id
ddCe"fiddDe"fdde"fd�dde"fdde"fdde"fdde"fd�d�Z#dEdd�Z$e$ddd�e$dd�e$dd�e$dd�e$ddd�e$ddd �e$ddd�e$dd!d"�e$ddd#�e$ddd"�e$dd$d"�e$ddd%�e$dd!d�e$ddd&�e$ddd�e$dd$�e$ddd'�e$ddd(�e$ddd)�e$dd!�e$dd$d"�e$dd*�e$dd+�e$dd,�e$ddd-�e$dd.�e$dd/�e$dd0�e$dd!d'�e$ddd1�e$dd!d)�e$ddd2�e$dd.d"�e$dd.d�d3�"e$d4dd'�e$d4d$d�e$d4dd)�e$d4dd"�e$d4d�e$d4d�e$d4d�e$d4dd-�e$d4d5�e$d4d6�e$d4d7�e$d4d8�e$d4d9�e$d4d:�e$d4dd�e$d4d;�e$d4d$�e$d4dd�e$d4d<�e$d4dd&�e$d4d=�e$d4d>�e$d4d.�e$d4d.d"�e$d4d.d�e$d4d$d"�e$d4d$d)�d?�d@�Z%GdAdB�dBe&�Z'dS)F�)�absolute_importN)�log)�	check_mac�getPortRange�normalizeIP6�check_single_address�
check_address)�
FirewallError�
UNKNOWN_ERROR�INVALID_RULE�INVALID_ICMPTYPE�INVALID_TYPE�
INVALID_ENTRY�INVALID_PORT)�Rich_Accept�Rich_Reject�	Rich_Drop�	Rich_Mark�Rich_Masquerade�Rich_ForwardPort�Rich_IcmpBlock)�NftablesZ	firewalld�_Zpolicy_dropZpolicy_�
�
PREROUTING�
prerouting��dZpostrouting)r�POSTROUTING�input�forward�output)r�INPUT�FORWARD�OUTPUT)�raw�mangle�nat�filtercCsHdd|dd�id|d�ig}|dk	rD|jdd|dd�id|d�i�|S)N�match�payload�type)�protocol�fieldz==)�left�op�right�code)�append)r,r+r1�	fragments�r4�/usr/lib/python3.6/nftables.py�_icmp_types_fragmentsSsr6�icmpzdestination-unreachable�
z
echo-replyzecho-request���redirect��zparameter-problem�����zrouter-advertisementzrouter-solicitationz
source-quench�z
time-exceededztimestamp-replyztimestamp-request��)"zcommunication-prohibitedzdestination-unreachablez
echo-replyzecho-requestzfragmentation-neededzhost-precedence-violationzhost-prohibitedz
host-redirectzhost-unknownzhost-unreachablez
ip-header-badznetwork-prohibitedznetwork-redirectznetwork-unknownznetwork-unreachablezparameter-problemzport-unreachablezprecedence-cutoffzprotocol-unreachabler;zrequired-option-missingzrouter-advertisementzrouter-solicitationz
source-quenchzsource-route-failedz
time-exceededztimestamp-replyztimestamp-requestztos-host-redirectztos-host-unreachableztos-network-redirectztos-network-unreachablezttl-zero-during-reassemblyzttl-zero-during-transit�icmpv6zmld-listener-donezmld-listener-queryzmld-listener-reportzmld2-listener-reportznd-neighbor-advertznd-neighbor-solicitzpacket-too-bigznd-redirectznd-router-advertznd-router-solicit)zaddress-unreachablez
bad-headerzbeyond-scopezcommunication-prohibitedzdestination-unreachablez
echo-replyzecho-requestz
failed-policyzmld-listener-donezmld-listener-queryzmld-listener-reportzmld2-listener-reportzneighbour-advertisementzneighbour-solicitationzno-routezpacket-too-bigzparameter-problemzport-unreachabler;zreject-routezrouter-advertisementzrouter-solicitationz
time-exceededzttl-zero-during-reassemblyzttl-zero-during-transitzunknown-header-typezunknown-option)�ipv4�ipv6c@s`eZdZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Z	dd
�Z
dd�Zd�dd�Zdd�Z
dd�Zdd�Zdd�Zd�dd�Zdd�Zd�d d!�Zd"d#�Zd�d%d&�Zd�d(d)�Zd�d*d+�Zd�d,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�Zd<d=�Z d>d?�Z!d@dA�Z"dBdC�Z#dDdE�Z$dFdG�Z%dHdI�Z&d�dJdK�Z'dLdM�Z(dNdO�Z)dPdQ�Z*dRdS�Z+d�dTdU�Z,d�dVdW�Z-d�dXdY�Z.dZd[�Z/d�d\d]�Z0d�d^d_�Z1d�d`da�Z2d�dbdc�Z3d�ddde�Z4dfdg�Z5d�dhdi�Z6djdk�Z7d�dldm�Z8dndo�Z9dpdq�Z:drds�Z;dtdu�Z<d�dvdw�Z=d�dxdy�Z>dzd{�Z?d�d|d}�Z@d~d�ZAd�d��ZBd�d��ZCd�d��ZDd�d��ZEd�d��ZFd�d��ZGd�d�d��ZHdS)��nftablesTcCsb||_d|_g|_i|_i|_i|_i|_i|_gggd�|_t	�|_
|j
jd�|j
jd�dS)NT)�inet�ip�ip6)
�_fwZrestore_command_existsZavailable_tables�rule_to_handle�rule_ref_count�rich_rule_priority_counts�policy_priority_counts�zone_source_index_cache�created_tablesrrIZset_echo_outputZset_handle_output)�self�fwr4r4r5�__init__�sznftables.__init__cCs�xdD]}||krPqWd||dkr`||ddd||dddf}||dd=n(d||dkr�d}||dd=ndS||dd	}|r�|dkr�||kr�|||kr�||j|�n�|dk�r�||kr�g||<|�r(|||k�r||j|�||jd
d�d�||j|�}n|jj�r8d
}nt||�}||}||=|d
k�rf||d<n |d8}||d<||ddd<dS)N�add�insert�deletez%%ZONE_SOURCE%%�rule�zone�addressz%%ZONE_INTERFACE%%�familycSs|dS)Nrr4)�xr4r4r5�<lambda>�sz3nftables._run_replace_zone_source.<locals>.<lambda>)�keyrr<�index)rWrXrY)�remover2�sortrarM�_allow_zone_drifting�len)rTrZrR�verbZzone_sourcer]ra�
_verb_snippetr4r4r5�_run_replace_zone_source�sD




z!nftables._run_replace_zone_sourcecCsBd|krdtj|d�iSd|kr4dtj|d�iSttd��dS)NrXrYrWzFailed to reverse rule)�copy�deepcopyr	r
)rT�dictr4r4r5�reverse_rule�s
znftables.reverse_rulec
Cs�xdD]}||krPqW|||dk�r�||d|}||d|=t|�tkr^ttd��||dd||ddf}|dkr�||ks�|||ks�|||dkr�ttd	��|||d
8<n�||kr�i||<|||kr�d|||<d}xVt||j��D]B}||k�r"|dk�r"P||||7}||k�r|dk�rP�qW|||d
7<||}	||=|dk�r�|	|d<n |d
8}|	|d<||ddd<dS)
NrWrXrYrZz%priority must be followed by a numberr]�chainrz*nonexistent or underflow of priority countr<ra)rWrXrY)r+�intr	rr
�sorted�keys)
rTrZZpriority_counts�tokenrf�priorityrmra�prgr4r4r5�_set_rule_replace_priority�sD

 


z#nftables._set_rule_replace_prioritycCsfx`d
D]X}||krd||krtj||d�}xdD]}||kr6||=q6Wtj|dd	�}|SqWdS)NrWrXrYrZra�handle�positionT)Z	sort_keys)rWrXrY)rarurv)rirj�json�dumps)rTrZrf�rule_keyZnon_keyr4r4r5�
_get_rule_keys


znftables._get_rule_keycCsLdddddg}dddg}g}g}tj|j�}tj|j�}tj|j�}	|jj�}
�x�|D�]�}t|�tkrvtt	d|��x|D]}||kr|Pq|W||kr�tt
d|��|j|�}
|
|
k�rDtj
d|j|
|
|
�|dkr�|
|
d	7<qVnX|
|
d	k�r|
|
d	8<qVn6|
|
d	k�r,|
|
d	8<ntt	d
|
|
|
f��n|
�r\|dk�r\d	|
|
<|j|�tj|�}|
�rttd||dd��||dd<|j||d
�|j||d�|j||	�|dk�rdd|ddd|ddd|ddd|j|
d�ii}|j|�qVWdddd	iig|i}tj�dk�rVtjd|jtj|��|jj|�\}}}|dk�r�tdd|tj|�f��||_||_|	|_|
|_d}x�|D]�}|d	7}|j|�}
|
�s̐q�d|k�r�|j|
=|j|
=�q�x"|D]}||d|k�r�P�q�W||d|k�r$�q�|d||dd|j|
<�q�WdS)NrWrXrY�flush�replacez#rule must be a dictionary, rule: %szno valid verb found, rule: %sz%s: prev rule ref cnt %d, %sr<z)rule ref count bug: rule_key '%s', cnt %drZ�exprz%%RICH_RULE_PRIORITY%%z%%POLICY_PRIORITY%%r]�tablerm)r]r~rmrurIZmetainfoZjson_schema_versionr@z.%s: calling python-nftables with JSON blob: %srz'%s' failed: %s
JSON blob:
%szpython-nftablesru)rirjrPrQrRrOr+rkr	r
rrzrZdebug2�	__class__r2�listr(rtrhrNZgetDebugLogLevelZdebug3rwrxrIZjson_cmd�
ValueError)rT�rules�
log_deniedZ_valid_verbsZ_valid_add_verbsZ_deduplicated_rulesZ_executed_rulesrPrQrRrOrZrfryZ_ruleZ	json_blobZrcr!�errorrar4r4r5�	set_rules+s�







&






znftables.set_rulescCs|j|g|�dS)N�)r�)rTrZr�r4r4r5�set_rule�sznftables.set_ruleNcCs|r
|gStj�S)N)�IPTABLES_TO_NFT_HOOKrp)rTr~r4r4r5�get_available_tables�sznftables.get_available_tablescCsFg}x<dD]4}|jdd||d�ii�|jdd||d�ii�q
W|S)	NrJrKrLrWr~)r]�namerY)rJrKrL)r2)rTr~r�r]r4r4r5�_build_delete_table_rules�s


z"nftables._build_delete_table_rulescCs�i}i}xB|jd�D]4}|j|�}||jkr|j|||<|j|||<qW||_||_i|_i|_i|_x*dD]"}t|j|krp|j|j	t�qpW|j
t�S)NTrJrKrL)rJrKrL)� _build_set_policy_rules_ct_rulesrzrNrOrPrQrR�
TABLE_NAMErSrbr�)rTZsaved_rule_to_handleZsaved_rule_ref_countrZ�
policy_keyr]r4r4r5�build_flush_rules�s 


znftables.build_flush_rulesc
Cslddd�|}g}xTdD]L}|j|ddtd	d
|fddd
diiddddgid�iddigd�ii�qW|S)NrWrY)TFrr r!rZrJz%s_%sr(r)�ctr`�state�in�set�established�related)r.r/r0�accept)r]r~rmr})rr r!)r2�TABLE_NAME_POLICY)rT�enable�add_delr��hookr4r4r5r��s


z)nftables._build_set_policy_rules_ct_rulescCstg}|dkrt|jdddtd�ii�|jdjt�x>dD]6}|jdddtd	d
|fd|dtd
dd�ii�q:W|dk�r�|jdddtd�ii�|jdjt�x>dD]6}|jdddtd	d|fd|dtd
dd�ii�q�W||jd�7}nz|dk�rfx4|jd�D]&}|j|�}||jk�r|j|��qW||jt�7}t|jdk�rp|jdjt�n
t	t
d�|S)NZPANICrWr~rJ)r]r�rr!rmz%s_%sr%r(i,r<�drop)r]r~r�r+r��prio�policy�DROPrr rT�ACCEPTFznot implemented)rr!i���)rr r!)r2r�rS�NFT_HOOK_OFFSETr�rzrNr�rbr	r
)rTr�r�r�rZr�r4r4r5�build_set_policy_rules�sH













znftables.build_set_policy_rulescCs<t�}x,|r|gntj�D]}|jt|j��qWt|�S)N)r��ICMP_TYPES_FRAGMENTSrp�updater�)rT�ipvZ	supportedZ_ipvr4r4r5�supported_icmp_types�sznftables.supported_icmp_typescCs>g}x4dD],}|jdd|td�ii�|j|jt�q
W|S)NrJrKrLrWr~)r]r�)rJrKrL)r2r�rS)rTZdefault_tablesr]r4r4r5�build_default_tabless

znftables.build_default_tables�offcCs�g}x�tdj�D]�}|jdddtd|ddtd|dtd|d	d
�ii�xz|jjrlddd
dgndd
dgD]X}|jdddtd||fd�ii�|jdddtd|ddd||fiigd�ii�qvWqWx�d?D]�}x�tdj�D]�}|jdd|td|ddtd|dtd|d	d
�ii�x~|jj�rJddd
dgndd
dgD]Z}|jdd|td||fd�ii�|jdd|td|ddd||fiigd�ii��qTWq�Wq�WxVtdj�D]F}|jdddtd|ddtd|dtd|d	d
�ii��q�W|jdddtddddddiid d!d"d#gid$�id%digd�ii�|jdddtdddddd&iid d'd$�id%digd�ii�|jdddtdddd(dd)iid*d+d$�id%digd�ii�x~|jj�r�ddd
dgndd
dgD]Z}|jdddtd,d|fd�ii�|jdddtddddd,d|fiigd�ii��q�W|d-k�r�|jdddtddddddiid d!d.gid$�i|j|�d/d0d1iigd�ii�|jdddtddddddiid d!d.gid$�id2digd�ii�|d-k�r$|jdddtdd|j|�d/d0d3iigd�ii�|jdddtddd4d5d6d7�igd�ii�|jdddtdd8ddddiid d!d"d#gid$�id%digd�ii�|jdddtdd8dddd&iid d'd$�id%digd�ii�|jdddtdd8dd(dd)iid*d+d$�id%digd�ii�xbd@D]Z}|jdddtd,d8|fd�ii�|jdddtdd8ddd,d8|fiigd�ii��qWx�dAD]�}xz|jj�r�dd
gnd
gD]^}|jdddtd;d8||fd�ii�|jdddtdd8ddd;d8||fiigd�ii��q�W�qvWxbdBD]Z}|jdddtd,d8|fd�ii�|jdddtdd8ddd,d8|fiigd�ii��qW|d-k�r�|jdddtdd8ddddiid d!d.gid$�i|j|�d/d0d1iigd�ii�|jdddtdd8ddddiid d!d.gid$�id2digd�ii�|d-k�r6|jdddtdd8|j|�d/d0d3iigd�ii�|jdddtdd8d4d5d6d7�igd�ii�|jdddtdd<ddddiid d!d"d#gid$�id%digd�ii�|jdddtd=dd(dd>iid*d+d$�id%digd�ii�xbdCD]Z}|jdddtd,d<|fd�ii�|jdddtdd<ddd,d<|fiigd�ii��q�WxbdDD]Z}|jdddtd,d<|fd�ii�|jdddtdd<ddd,d<|fiigd�ii��qHW|S)ENr&rWrmrJz	mangle_%sr(z%srr<)r]r~r�r+r�r��POLICIES_preZZONES_SOURCEZZONES�
POLICIES_postzmangle_%s_%s)r]r~r�rZ�jump�target)r]r~rmr}rKrLr'znat_%sz	nat_%s_%sz	filter_%sr"r)r�r`r�r�r�r�r�)r.r/r0r�Zstatus�dnat�meta�iifnamez==�lozfilter_%s_%sr�Zinvalidr�prefixzSTATE_INVALID_DROP: r�zFINAL_REJECT: �reject�icmpxzadmin-prohibited)r+r}r#�IN�OUTzfilter_%s_%s_%sr$�
filter_OUTPUT�oifname)rKrL)r�)r�r�)r�)r�)r�)r�rpr2r�rMrd�_pkttype_match_fragment)rTr�Z
default_rulesrmZdispatch_suffixr]�	directionr4r4r5�build_default_ruless�
$

(

&

.
 


&

&











&


.


&










&


&znftables.build_default_rulescCs4|dkrdddgS|dkr dgS|dkr0ddgSgS)	Nr(r"�
FORWARD_IN�FORWARD_OUTr&rr'rr4)rTr~r4r4r5�get_zone_table_chains�s
znftables.get_zone_table_chainsrJc
s��dkr\�dkr\g}
|
j�j�|��||||dd�	�|
j�j�|��||||dd�	�|
S�jjj|���jdkrxdnd��dkr��d	kr�d
nd}�jjj|�t|��g}g}
|r�|jdd
ddiiddt	|�id�i�|�r|
jdd
ddiiddt	|�id�i�ddd�}|�rlxT|D]L}�dk�rT�jj
j|�}||k�rT�||k�rT�q|j�jd|���qW|�r�xT|D]L}�dk�r��jj
j|�}||k�r��||k�r��qx|
j�jd|���qxW��������fdd�}g}
|�rHx�|D]P}|
�rxB|
D]}|
j|||���qWn"�dk�r0|�r0n|
j||d���q�Wn\�dk�rZ|�rZnJ|
�r�xB|
D]}|
j|d|���qfWn"�dk�r�|�r�n|
j|dd��|
S)Nr'rJrK)r]rLr�pre�postrTFr)r�r`r�z==r�)r.r/r0r�)rGrH�saddr�daddrcs�g}|r|j|�|r |j|�|jddd��fii��td���f|d�}|j�j����rrdd|iiSdd|iiSdS)	Nr�r�z%s_%sz%s_%s_POLICIES_%s)r]r~rmr}rWrZrY)r2r�r��_policy_priority_fragment)�ingress_fragment�egress_fragment�expr_fragmentsrZ)�_policyrm�chain_suffixr�r]�p_objrTr~r4r5�_generate_policy_dispatch_rules

zRnftables.build_policy_ingress_egress_rules.<locals>._generate_policy_dispatch_rule)
�extend�!build_policy_ingress_egress_rulesrMr�Z
get_policyrr�policy_base_chain_name�POLICY_CHAIN_PREFIXr2r�r[Zcheck_source�_rule_addr_fragment)rTr�r�r~rmZingress_interfacesZegress_interfacesZingress_sourcesZegress_sourcesr]r��isSNATZingress_fragmentsZegress_fragmentsZ
ipv_to_family�srcr��dstr�r�r�r4)r�rmr�r�r]r�rTr~r5r��sv









z*nftables.build_policy_ingress_egress_rulesFc	
Cs�|dkrT|dkrTg}	|	j|j|||||||d��|	j|j|||||||d��|	S|dkrh|dkrhdnd}
|jjj||t|
d�}d	d
d	d	d
d
d�|}|t|�dd
kr�|dt|�d�d}d}
|dkr�|
dd||fiig}n,ddd|iid|d�i|
dd||fiig}|�rL|�rLd}|td||f|d�}|j|j	��nP|�rnd}|td||f|d�}n.d}|td||f|d�}|�s�|j|j	��|d|iigS)Nr'rJrKrLrTF)r�r�r�)rrr"r�r�r$r<�+�*�gotor�z%s_%sr)r�r`z==)r.r/r0rXz%s_%s_ZONES)r]r~rmr}rWrYrZ)
r��!build_zone_source_interface_rulesrMr�r�r�rer�r��_zone_interface_fragment)rTr�r[r��	interfacer~rmr2r]r�r�r��opt�actionr�rfrZr4r4r5r�Qs\



z*nftables.build_zone_source_interface_rulesc	Csn|dkr�|dkr�g}|jd�r6|j|td�d��}	nd}	td|�sTt|�sT|	dkrp|j|j||||||d��td|�s�t|�s�|	dkr�|j|j||||||d��|S|dkr�|dkr�d	nd
}
|jjj	||t
|
d�}dd
d�|}ddddddd�|}
|jj�rd||f}nd||f}d}|t||j
|
|�|dd||fiigd�}|j|j||��|d|iigS)Nr'rJzipset:rGrKrHrLrTF)r�rXrY)TFr�r�)rrr"r�r�r$z%s_%s_ZONES_SOURCEz%s_%s_ZONESr�r�z%s_%s)r]r~rmr}rZ)�
startswith�_set_get_familyrerrr��build_zone_source_address_rulesrMr�r�r�rdr�r�r��_zone_source_fragment)rTr�r[r�r\r~rmr]r�Zipset_familyr�r�r�r�Zzone_dispatch_chainr�rZr4r4r5r��sB


z(nftables.build_zone_source_address_rulesc
Cs|dkrH|dkrHg}|j|j||||d��|j|j||||d��|Sddd�|}|dkrj|dkrjd	nd
}|jjj||t|d�}	g}|j|d|td
||	fd�ii�x0d!D](}
|j|d|td||	|
fd�ii�q�WxDd"D]<}
|j|d|td
||	fddd||	|
fiigd�ii�q�W|jjj|j	}|jj
�dk�r�|dk�r�|d#k�r�|}|dk�rhd}|j|d|td
||	f|j|jj
��ddd|	|fiigd�ii�|dk�r|d$k�r|d%k�r�|j�}
n|j
�di}
|j|d|td
||	f|
gd�ii�|�s|j�|S)&Nr'rJrKrLrWrY)TFrTF)r�rmz%s_%s)r]r~r�r�r�deny�allowr�z%s_%s_%srZr�r�)r]r~rmr}r�r(�REJECT�
%%REJECT%%r�r�z"filter_%s_%s: "r�)r�rr�r�r�)r�rr�r�r�)r�r�r�)r�r�r�r�)r�r�)r��build_policy_chain_rulesrMr�r�r�r2r�Z	_policiesr��get_log_deniedr��_reject_fragment�lower�reverse)rTr�r�r~rmr]r�r�r�r�r�r�Z
log_suffix�target_fragmentr4r4r5r��sZ





&




 





z!nftables.build_policy_chain_rulescCs<|dkriS|dkr,ddddiid	|d
�iSttd|��dS)
N�all�unicast�	broadcast�	multicastr)r�r`�pkttypez==)r.r/r0zInvalid pkttype "%s")r�r�r�)r	r)rTr�r4r4r5r��s
z nftables._pkttype_match_fragmentcCsdddd�idddd�idddd�idddd�idddd�idddd�idddd�idddd�idddd�idddd�iddd	d�iddd	d�iddd
d�iddd
d�iddd
d�idddd�idddd�iddd
d�iddd
d�idddd�idddd�idddiidddiid�}||S)Nr�r7zhost-prohibited)r+r}znet-prohibitedzadmin-prohibitedrFznet-unreachablezhost-unreachablezport-unreachabler�zprot-unreachablezaddr-unreachablezno-router+z	tcp reset)zicmp-host-prohibitedzhost-prohibzicmp-net-prohibitedz
net-prohibzicmp-admin-prohibitedzadmin-prohibzicmp6-adm-prohibitedzadm-prohibitedzicmp-net-unreachableznet-unreachzicmp-host-unreachablezhost-unreachzicmp-port-unreachablezicmp6-port-unreachablezport-unreachzicmp-proto-unreachablez
proto-unreachzicmp6-addr-unreachablezaddr-unreachzicmp6-no-routezno-routez	tcp-resetztcp-rstr4)rTZreject_typeZfragsr4r4r5�_reject_types_fragment�s0
znftables._reject_types_fragmentcCsdddd�iS)Nr�r�zadmin-prohibited)r+r}r4)rTr4r4r5r�sznftables._reject_fragmentcCs ddddiiddddgid	�iS)
Nr)r�r`�l4protoz==r�r7rF)r.r/r0r4)rTr4r4r5�_icmp_match_fragment"sznftables._icmp_match_fragmentcCsP|siSddddd�}|j�\}}|||d�}|j�}|dk	rH||d<d|iS)	N�secondZminuteZhourZday)�s�m�h�d)�rateZper�burst�limit)Zvalue_parseZburst_parse)rTr�Zrich_to_nftr�Zdurationr�r�r4r4r5�_rich_rule_limit_fragment'sz"nftables._rich_rule_limit_fragmentcCs�t|j�tttgkrn<|jrHt|j�tttt	gkrRt
tdt|j���n
t
td��|jdkr�t|j�ttgks�t|j�tt	gkr�dSt|j�tgks�t|j�ttgkr�dSn|jdkr�dSdSdS)NzUnknown action %szNo rule action specified.rr�r�r�r�)
r+�elementrrrr�rrrrr	rrr)rT�	rich_ruler4r4r5�_rich_rule_chain_suffix?s 


z nftables._rich_rule_chain_suffixcCs>|jr|jrttd��|jdkr(dS|jdkr6dSdSdS)NzNot log or auditrrr�r�)r�auditr	rrr)rTr�r4r4r5� _rich_rule_chain_suffix_from_logUs


z)nftables._rich_rule_chain_suffix_from_logcCsddiS)Nz%%ZONE_INTERFACE%%r4)rTr4r4r5r�`sz!nftables._zone_interface_fragmentcCsNtd|�rt|�}n,td|�r@|jd�}t|d�d|d}d||d�iS)NrH�/rr<z%%ZONE_SOURCE%%)r[r\)rrr�split)rTr[r\Z
addr_splitr4r4r5r�cs



znftables._zone_source_fragmentcCs
d|jiS)Nz%%POLICY_PRIORITY%%)rr)rTr�r4r4r5r�ksz"nftables._policy_priority_fragmentcCs|s|jdkriSd|jiS)Nrz%%RICH_RULE_PRIORITY%%)rr)rTr�r4r4r5�_rich_rule_priority_fragmentnsz%nftables._rich_rule_priority_fragmentcCs�|js
iS|jjj||t�}ddd�|}|j|�}i}	|jjrPd|jj|	d<|jjr|d|jjkrhdn|jj}
d|
|	d<d	td
|||f||j	|jj
�d|	igd�}|j|j|��|d
|iiS)NrWrY)TFz%sr�Zwarning�warn�levelrJz%s_%s_%sr)r]r~rmr}rZ)
rrMr�r�r�r�r�rr�r�r�r�r�)rTr�r�r�r~r�r�r�r�Zlog_optionsrrZr4r4r5�_rich_rule_logss&
znftables._rich_rule_logc
Cs�|js
iS|jjj||t�}ddd�|}|j|�}dtd|||f||j|jj�dddiigd	�}	|	j	|j
|��|d
|	iiS)NrWrY)TFrJz%s_%s_%srrr�)r]r~rmr}rZ)r�rMr�r�r�r�r�r�r�r�r�)
rTr�r�r�r~r�r�r�r�rZr4r4r5�_rich_rule_audit�s
znftables._rich_rule_auditc
Cs�|js
iS|jjj||t�}ddd�|}|j|�}d|||f}	t|j�tkr\ddi}
�nt|j�tkr�|jjr�|j	|jj�}
nddi}
n�t|j�t
kr�ddi}
n�t|j�tk�rHd}|jjj||t�}d|||f}	|jjj
d	�}t|�d
k�r,dddd
iiddddd
ii|d
gi|dgid�i}
ndddd
ii|dd�i}
nttdt|j���dt|	||j|jj�|
gd�}|j|j|��|d|iiS)NrWrY)TFz%s_%s_%sr�r�r�r&r�r<r�r`�mark�^�&r)r`�valuezUnknown action %srJ)r]r~rmr}rZ)r�rMr�r�r�r�r+rrr�rrr�r�rer	rr�r�r�r�r�)
rTr�r�r�r~r�r�r�r�rmZrule_actionrrZr4r4r5�_rich_rule_action�sB


,znftables._rich_rule_actioncCs�|jd�r0|j|td�d�d|kr(dnd|�St|�r>d}n�td|�rNd}nvtd|�r�d}tj|dd�}d	|jj	|j
d
�i}nDtd|�r�d}t|�}n,d}|jd
�}d	t|d�t
|d�d
�i}dd||d�i|r�dnd|d�iSdS)Nzipset:r�TF�etherrGrK)�strictr�)�addrrerHrLr�rr<r)r*)r,r-z!=z==)r.r/r0)r��_set_match_fragmentrerrr�	ipaddressZIPv4NetworkZnetwork_addressZ
compressedZ	prefixlenrr�rn)rTZ
addr_fieldr\�invertr]Znormalized_addressZaddr_lenr4r4r5r��s(
&





znftables._rule_addr_fragmentcCs6|siS|d
krttd|��ddddiid|d	�iS)NrGrHzInvalid familyr)r�r`�nfprotoz==)r.r/r0)rGrH)r	r)rTZrich_familyr4r4r5�_rich_rule_family_fragment�s
z#nftables._rich_rule_family_fragmentcCs8|siS|jr|j}n|jr&d|j}|jd||jd�S)Nzipset:r�)r)r�ipsetr�r)rTZ	rich_destr\r4r4r5�_rich_rule_destination_fragment�s
z(nftables._rich_rule_destination_fragmentcCsZ|siS|jr|j}n2t|d�r.|jr.|j}nt|d�rH|jrHd|j}|jd||jd�S)N�macrzipset:r�)r)r�hasattrrrr�r)rTZrich_sourcer\r4r4r5�_rich_rule_source_fragment�s
z#nftables._rich_rule_source_fragmentcCsPt|�}t|t�r$|dkr$tt��n(t|�dkr8|dSd|d|dgiSdS)Nrr<�range)r�
isinstancernr	rre)rT�portrr4r4r5�_port_fragments
znftables._port_fragmentc	Csbddd�|}d}|jjj||t�}	g}
|r>|
j|j|j��|rT|
j|jd|��|r||
j|j|j	��|
j|j
|j��|
jdd|dd	�id
|j|�d�i�|s�t
|j�tkr�|
jddd
diiddddgid�i�g}|�r0|j|j|||||
��|j|j|||||
��|j|j|||||
��n.|j|ddtd||	f|
ddigd�ii�|S)NrWrY)TFr(r�r)r*�dport)r,r-z==)r.r/r0r�r`r�r�r��new�	untrackedrZrJz%s_%s_allowr�)r]r~rmr})rMr�r�r�r2rr]r�r�destinationr�sourcerr+r�rrrrr�)rTr�r��protorrr�r�r~r�r�r�r4r4r5�build_policy_ports_ruless:


z!nftables.build_policy_ports_rulesc	CsZddd�|}d}|jjj||t�}g}	|r>|	j|j|j��|rT|	j|jd|��|r||	j|j|j	��|	j|j
|j��|	jdddd	iid
|d�i�|s�t|j
�tkr�|	jdddd
iiddddgid�i�g}
|�r(|
j|j|||||	��|
j|j|||||	��|
j|j|||||	��n.|
j|ddtd||f|	ddigd�ii�|
S)NrWrY)TFr(r�r)r�r`r�z==)r.r/r0r�r�r�r�rrrZrJz%s_%s_allowr�)r]r~rmr})rMr�r�r�r2rr]r�rrrrr+r�rrrrr�)rTr�r�r,rr�r�r~r�r�r�r4r4r5�build_policy_protocol_rules2s8

z$nftables.build_policy_protocol_rulesc	Csbddd�|}d}|jjj||t�}	g}
|r>|
j|j|j��|rT|
j|jd|��|r||
j|j|j	��|
j|j
|j��|
jdd|dd	�id
|j|�d�i�|s�t
|j�tkr�|
jddd
diiddddgid�i�g}|�r0|j|j|||||
��|j|j|||||
��|j|j|||||
��n.|j|ddtd||	f|
ddigd�ii�|S)NrWrY)TFr(r�r)r*�sport)r,r-z==)r.r/r0r�r`r�r�r�rrrZrJz%s_%s_allowr�)r]r~rmr})rMr�r�r�r2rr]r�rrrrrr+r�rrrrr�)rTr�r�rrrr�r�r~r�r�r�r4r4r5�build_policy_source_ports_rulesUs:


z(nftables.build_policy_source_ports_rulesc
	Cs�d}|jjj||t�}	ddd�|}
g}|rR|jdddtd||f||d�ii�g}|rl|j|jd	|��|jd
d|dd
�id|j|�d�i�|jdd||fi�|j|
ddtd|	|d�ii�|S)Nr(rWrY)TFz	ct helperrJzhelper-%s-%s)r]r~r�r+r,r�r)r*r)r,r-z==)r.r/r0rZzfilter_%s_allow)r]r~rmr})rMr�r�r�r2r�r�r)
rTr�r�rrrZhelper_nameZmodule_short_namer~r�r�r�r�r4r4r5�build_policy_helper_ports_ruleszs.



z(nftables.build_policy_helper_ports_rulescCs�ddd�|}|jjj||t�}g}	|rv|t|�ddkrT|dt|�d�d}ddd	d
iid|d�id
dig}
n|jd|�d
dig}
dtd||
d�}|	j|d|ii�|	S)NrWrY)TFr<r�r�r)r�r`r�z==)r.r/r0r�r�rJzfilter_%s_allow)r]r~rmr}rZ)rMr�r�r�rer�r�r2)rTr�r[r�r~r�rr�r�r�r}rZr4r4r5�build_zone_forward_rules�s"z!nftables.build_zone_forward_rulesc	Cs�d}|jjj||tdd�}ddd�|}g}|r`|j|j|j��|j|j|j��|j	|�}	nd}	|t
d||	f|d	d
ddiid
dd�iddigd�}
|
j|j|��|d|
iigS)Nr'T)r�rWrY)TFr�z	nat_%s_%sr)r�r`r�z!=r�)r.r/r0Z
masquerade)r]r~rmr}rZ)
rMr�r�r�r2rrrrr�r�r�r�)rTr�r�r]r�r~r�r�r�r�rZr4r4r5�"_build_policy_masquerade_nat_rules�s&
z+nftables._build_policy_masquerade_nat_rulesc
Cs^g}|rD|jr|jdks,|jrDtd|jj�rD|j|j||d|��nV|r�|jrX|jdksl|jr�td|jj�r�|j|j||d|��n|j|j||d|��d}|jjj||t	�}ddd�|}g}|r�|j
|j|j��|j
|j
|j��|j|�}	nd	}	d
td||	f|dd
ddiiddddgid�iddigd�}
|
j|j|��|j
|d|
ii�|S)NrHrLrGrKr(rWrY)TFr�rJzfilter_%s_%sr)r�r`r�r�r�rr)r.r/r0r�)r]r~rmr}rZ)r]rrrr�r&rMr�r�r�r2rrrr�r�r�r�)rTr�r�r�r�r~r�r�r�r�rZr4r4r5�build_policy_masquerade_rules�s8
z&nftables.build_policy_masquerade_rulesc	Cs$d}	|jjj||	t�}
ddd�|}g}|r\|j|j|j��|j|j|j��|j	|�}
nd}
|jdd|dd	�id
|j
|�d�i�|r�td|�r�t|�}|r�|d
kr�|jd||j
|�d�i�q�|jdd|ii�n|jdd|j
|�ii�|t
d|
|
f|d�}|j|j|��|d|iigS)Nr'rWrY)TFr�r)r*r)r,r-z==)r.r/r0rHr�r�)rrrr;rz	nat_%s_%s)r]r~rmr}rZ)rMr�r�r�r2rrrrr�rrrr�r�r�)rTr�r�rr,�toaddr�toportr]r�r~r�r�r�r�rZr4r4r5�$_build_policy_forward_port_nat_rules�s4


z-nftables._build_policy_forward_port_nat_rulesc	
Cs�g}|rF|jr|jdks&|rFtd|�rF|j|j||||||d|��n�|r�|jrZ|jdksh|r�td|�r�|j|j||||||d|��nL|r�td|�r�|j|j||||||d|��n|j|j||||||d|��|S)NrHrLrGrK)r]rr�r*)	rTr�r�rr,r)r(r�r�r4r4r5�build_policy_forward_port_rulessz(nftables.build_policy_forward_port_rulescCs2|t|krt||Sttd||j|f��dS)Nz)ICMP type '%s' not supported by %s for %s)r�r	rr�)rTr�Z	icmp_typer4r4r5�_icmp_types_to_nft_fragments(sz%nftables._icmp_types_to_nft_fragmentscCsBd}|jjj||t�}ddd�|}|r6|jr6|j}n<|jrjg}d|jkrT|jd�d|jkrr|jd�nddg}g}	�x�|D�]�}
|jjj|�r�d||f}ddi}nd	||f}|j�}g}
|r�|
j|j	|j
��|
j|j|j��|
j|j|j
��|
j|j|
|j��|�r�|	j|j|||||
��|	j|j|||||
��|j�rf|	j|j|||||
��nN|j|�}d
td|||f|
|j�gd�}|j|j|��|	j|d
|ii�q~|jj�dk�r|jjj|��r|	j|d
d
t||
|j|jj��ddd||fiigd�ii�|	j|d
d
t||
|gd�ii�q~W|	S)Nr(rWrY)TFrGrHz%s_%s_allowr�z
%s_%s_denyrJz%s_%s_%s)r]r~rmr}rZr�rr�z"%s_%s_ICMP_BLOCK: ")rMr�r�r��ipvsrr2�query_icmp_block_inversionr�rr]rrrr�r,r�rrr�rr�r�r�r�r�r�)rTr�r�Zictr�r~r�r�r-r�r�Zfinal_chainr�r�r�rZr4r4r5�build_policy_icmp_block_rules/sb





"
"
z&nftables.build_policy_icmp_block_rulescCs�d}|jjj||t�}g}ddd�|}|jjj|�r@|j�}nddi}|j|ddtd||fd	|j�|gd
�ii�|jj	�dkr�|jjj|�r�|j|ddtd||fd	|j�|j
|jj	��dd
d||fiigd
�ii�|S)Nr(rWrY)TFr�rZrJz%s_%sr9)r]r~rmrar}r�rr�z%s_%s_ICMP_BLOCK: )rMr�r�r�r.r�r2r�r�r�r�)rTr�r�r~r�r�r�r�r4r4r5�'build_policy_icmp_block_inversion_rulesks,




 z0nftables.build_policy_icmp_block_inversion_rulescCs�g}ddddiiddd�iddd	d
dgdd
�iddd�ig}|dkrV|jdddii�|jddi�|jdddtd|d�ii�|jdddtdddddd�iddddgid�id digd�ii�|S)!Nr)r�r`rz==rH)r.r/r0Zfibr�ZiifrZoif)�flags�resultFr�rr�zrpfilter_DROP: r�rXrZrJZfilter_PREROUTING)r]r~rmr}r*rFr+)r,r-r�znd-router-advertznd-neighbor-solicitr�)r2r�)rTr�r�r�r4r4r5�build_rpfilter_rules�s0

znftables.build_rpfilter_rulesc	Cs�ddddddddd	g	}d
d�|D�}dd
ddd�idd|id�ig}|jjd"krb|jdddii�|j|jd��g}|jdddtdd|d�ii�|jdddtd d!|d�ii�|S)#Nz::0.0.0.0/96z::ffff:0.0.0.0/96z2002:0000::/24z2002:0a00::/24z2002:7f00::/24z2002:ac10::/28z2002:c0a8::/32z2002:a9fe::/32z2002:e000::/19cSs2g|]*}d|jd�dt|jd�d�d�i�qS)r�r�rr<)rre)r�rn)�.0r^r4r4r5�
<listcomp>�sz5nftables.build_rfc3964_ipv4_rules.<locals>.<listcomp>r)r*rLr�)r,r-z==r�)r.r/r0r�r�rr�zRFC3964_IPv4_REJECT: zaddr-unreachrWrZrJr�r<)r]r~rmrar}Zfilter_FORWARDrB)r�r�)rMZ_log_deniedr2r�r�)rTZ	daddr_setr�r�r4r4r5�build_rfc3964_ipv4_rules�s:

z!nftables.build_rfc3964_ipv4_rulescCs�d}g}|j|j|j��|j|j|j��|j|j|j��g}|j|j|||||��|j|j|||||��|j|j	|||||��|S)Nr()
r2rr]rrrrrrr)rTr�r�r�r~r�r�r4r4r5�*build_policy_rich_source_destination_rules�sz3nftables.build_policy_rich_source_destination_rulescCs|dkrdSdS)NrGrH�ebTF)rGrHr8r4)rTr�r4r4r5�is_ipv_supported�sznftables.is_ipv_supportedc
Cs�ddd�}||||ddg||dd||g||dd||g||dg||||||g||ddg||dd||g||dgdd	�}||kr�||Sttd
|��dS)NZ	ipv4_addrZ	ipv6_addr)rGrHZ
inet_protoZinet_servicerZifnameZ
ether_addr)zhash:ipzhash:ip,portzhash:ip,port,ipzhash:ip,port,netzhash:ip,markzhash:netzhash:net,netz
hash:net,portzhash:net,port,netzhash:net,ifacezhash:macz!ipset type name '%s' is not valid)r	r
)rTr�r+Zipv_addr�typesr4r4r5�_set_type_list�s"

znftables._set_type_listc
Cs�|rd|kr|ddkrd}nd}t||j||�d�}x0|jd�djd�D]}|dkrLdg|d
<PqLW|r�d|kr�|d|d<d|kr�|d|d<g}x0dD](}d|i}	|	j|�|jdd|	ii�q�W|S)Nr]�inet6rHrG)r~r�r+�:r<�,rK�netrZintervalr1ZtimeoutZmaxelem�sizerJrLrWr�)rKr?r)rJrKrL)r�r;r�r�r2)
rTr�r+�optionsr�Zset_dict�tr�r]Z	rule_dictr4r4r5�build_set_create_rules�s*


znftables.build_set_create_rulescCs$|j|||�}|j||jj��dS)N)rCr�rMr�)rTr�r+rAr�r4r4r5�
set_createsznftables.set_createcCs8x2dD]*}dd|t|d�ii}|j||jj��qWdS)NrJrKrLrYr�)r]r~r�)rJrKrL)r�r�rMr�)rTr�r]rZr4r4r5�set_destroys

znftables.set_destroycCs6|jjj|�jjd�djd�}g}x�tt|��D]�}||dkrr|jdddii�|jdd	|rdd
ndd�i�q2||dkr�|jd|j|�|r�dndd�i�q2||dkr�|jdd|r�dndii�q2||dkr�|jdddii�q2t	d||��q2Wdt|�dk�rd|in|d|�r&dndd|d�iS)Nr=r<r>rr�r`r�r*Zthrr")r,r-rKr?rr�r�Zifacer�r�rz-Unsupported ipset type for match fragment: %sr)�concatrz!=z==�@)r.r/r0)rKr?r)
rMr�	get_ipsetr+r�rrer2r�r	)rTr�Z
match_destr�type_formatr3�ir4r4r5r s$ znftables._set_match_fragmentcCsN|jjj|�}|jjd�djd�}|jd�}t|�t|�krHttd��g}�x�tt|��D�]�}||dk�r,y||j	d�}Wn&t
k
r�|jd�||}	Yn,X|j||d|��|||dd�}	y|	j	d�}Wn t
k
�r|j|	�Yn(X|jd|	d|�|	|dd�gi�q\||dk�r d||k�rb|jd||jd�i�n�y||j	d�}WnLt
k
�r�||}
d|jk�r�|jdd
k�r�t
|
�}
|j|
�Yn^X||d|�}
d|jk�r�|jdd
k�r�t
|
�}
|jd|
t|||dd��d�i�q\|j||�q\Wt|�dk�rJd|igS|S)Nr=r<r>z+Number of values does not match ipset type.rZtcp�-rrKr?r�r]r<r�)rrerF)rKr?)rMrrHr+r�rer	rrrar�r2rArrn)rTr��entry�objrIZentry_tokensZfragmentrJraZport_strrr4r4r5�_set_entry_fragment7sL

("znftables._set_entry_fragmentc	Cs>g}|j||�}x(dD] }|jdd|t||d�ii�qW|S)NrJrKrLrWr�)r]r~r��elem)rJrKrL)rNr2r�)rTr�rLr�r�r]r4r4r5�build_set_add_rulesks

znftables.build_set_add_rulescCs"|j||�}|j||jj��dS)N)rPr�rMr�)rTr�rLr�r4r4r5�set_addusznftables.set_addcCsF|j||�}x4dD],}dd|t||d�ii}|j||jj��qWdS)NrJrKrLrYr�)r]r~r�rO)rJrKrL)rNr�r�rMr�)rTr�rLr�r]rZr4r4r5�
set_deleteys
znftables.set_deletecCs4g}x*dD]"}dd|t|d�ii}|j|�q
W|S)NrJrKrLr{r�)r]r~r�)rJrKrL)r�r2)rTr�r�r]rZr4r4r5�build_set_flush_rules�s
znftables.build_set_flush_rulescCs |j|�}|j||jj��dS)N)rSr�rMr�)rTr�r�r4r4r5�	set_flush�s
znftables.set_flushcCsJ|jjj|�}|jdkrd}n(|jrBd|jkrB|jddkrBd}nd}|S)Nzhash:macr	r]r<rLrK)rMrrHr+rA)rTr�rr]r4r4r5r��s
znftables._set_get_familyc	Cs�g}|j|j|||��|j|j|��d}x^|D]D}|j|j||��|d7}|dkr2|j||jj��|j�d}q2W|j||jj��dS)Nrr<i�)r�rCrSrPr�rMr��clear)	rTZset_nameZ	type_nameZentriesZcreate_optionsZ
entry_optionsr��chunkrLr4r4r5�set_restore�s
znftables.set_restore)N)N)r�)rJ)FrJ)rJ)rJ)F)NN)NN)NN)NN)N)N)N)N)N)F)N)N)F)NN)I�__name__�
__module__�__qualname__r�Zpolicies_supportedrVrhrlrtrzr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrr�rrrrr r!r#r$r%r&r'r*r+r,r/r0r3r6r7r9r;rCrDrErrNrPrQrRrSrTr�rWr4r4r4r5rI�s�/.`

4


R
i
;
-
9
 +


	
$
$
$


'
$

<
#


4
		rIij���i����)N)(Z
__future__rrirwr
Zfirewall.core.loggerrZfirewall.functionsrrrrrZfirewall.errorsr	r
rrr
rrZfirewall.core.richrrrrrrrZnftables.nftablesrr�r�r�r�r�r6r��objectrIr4r4r4r5�<module>s�$$





































core/__pycache__/fw_ifcfg.cpython-36.opt-1.pyc000064400000002613150351351730015050 0ustar003

��g
�@sTdZddgZddlZddlZddlmZddlmZddlm	Z	dd�Z
d	d�ZdS)
z.Functions to search for and change ifcfg files�search_ifcfg_of_interface�ifcfg_set_zone_of_interface�N)�config)�log)�ifcfgcCs�tjjtj�sdSxtttjtj��D]`}|jd�s4q$xd
D]}|j|�r:q:q:Wd	|krXq$t	d
tj|f�}|j
�|jd�|kr$|Sq$Wdtj|f}tjj|�r�t	|�}|j
�|SdS)z6search ifcfg file for the interface in config.IFCFGDIRNzifcfg-�.bak�.orig�.rpmnew�.rpmorig�.rpmsave�-range�.z%s/%sZDEVICEz%s/ifcfg-%s)rrr	r
rr)�os�path�existsrZIFCFGDIR�sorted�listdir�
startswith�endswithr�read�get)�	interface�filenameZignored�
ifcfg_file�r�/usr/lib/python3.6/fw_ifcfg.pyr!s*

cCsn|dkrd}t|�}|dk	rj|jd�|krj|jd�dko>|dkrjtjd||jf�|jd|�|j�dS)zYSet zone (ZONE=<zone>) in the ifcfg file that uses the interface
    (DEVICE=<interface>)N�ZZONEzSetting ZONE=%s in '%s')rrrZdebug1r�set�write)Zzonerrrrrr?s)�__doc__�__all__rZos.pathZfirewallrZfirewall.core.loggerrZfirewall.core.io.ifcfgrrrrrrr�<module>score/__pycache__/base.cpython-36.opt-1.pyc000064400000002172150351351730014210 0ustar003

��g6�@s�dZdZdZd0ZdddedgZddddgZd	d
ddd
dd�Zddddddddddddddddgd d!d"d#d$d%d&ddg	d'�Zd(d)d*d+d,d-d.gZd/S)1zBase firewall settingsz{chain}_{zone}ZCONTINUE�ZACCEPTz
%%REJECT%%ZDROP�defaultZREJECTZPREZPOST�INZFWDIZFWDOZOUT)Z
PREROUTINGZPOSTROUTINGZINPUTZ
FORWARD_INZFORWARD_OUTZOUTPUTzicmp-host-prohibitedzhost-prohibzicmp-net-unreachableznet-unreachzicmp-host-unreachablezhost-unreachzicmp-port-unreachablezport-unreachzicmp-proto-unreachablez
proto-unreachzicmp-net-prohibitedz
net-prohibz	tcp-resetztcp-rstzicmp-admin-prohibitedzadmin-prohibzicmp6-adm-prohibitedzadm-prohibitedzicmp6-no-routezno-routezicmp6-addr-unreachablezaddr-unreachzicmp6-port-unreachable)Zipv4Zipv6zhash:ipzhash:ip,portzhash:ip,markzhash:netz
hash:net,portzhash:net,ifacezhash:macN���)	�__doc__ZDEFAULT_ZONE_TARGETZDEFAULT_POLICY_TARGETZDEFAULT_POLICY_PRIORITYZZONE_TARGETSZPOLICY_TARGETSZ	SHORTCUTSZREJECT_TYPESZSOURCE_IPSET_TYPES�rr�/usr/lib/python3.6/base.py�<module>s.core/__pycache__/ebtables.cpython-36.opt-1.pyc000064400000016336150351351730015066 0ustar003

��g�$�@s&dgZddlZddlmZddlmZddlmZm	Z	m
Z
ddlmZddl
mZddlmZmZddlZd	gd
ddgd
ddgd�ZiZiZiZx�ej�D]tZgee<e�ee<x\eeD]PZeejde�eejdeef�eejde�eejde�q�Wq�WGdd�de�ZdS)�ebtables�N)�runProg)�log)�tempFile�readfile�	splitArgs)�COMMANDS)�	ipXtables)�
FirewallError�INVALID_IPVZBROUTINGZ
PREROUTINGZPOSTROUTINGZOUTPUTZINPUTZFORWARD)ZbrouteZnat�filterz-N %s_directz-I %s 1 -j %s_directz-I %s_direct 1 -j RETURNz	%s_directc@s�eZdZdZdZdZdd�Zdd�Zdd�Zd	d
�Z	dd�Z
d
d�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zd/d d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd0d+d,�Zd-d.�ZdS)1rZebFcCsBt|j|_td|j|_|j�|_|j�|_|j�g|_	dS)Nz
%s-restore)
r�ipv�_command�_restore_command�_detect_restore_noflush_optionZrestore_noflush_option�_detect_concurrent_option�concurrent_option�fill_exists�available_tables)�self�r�/usr/lib/python3.6/ebtables.py�__init__9s

zebtables.__init__cCs$tjj|j�|_tjj|j�|_dS)N)�os�path�existsrZcommand_existsrZrestore_command_exists)rrrrrAszebtables.fill_existscCs(d}t|jddg�}|ddkr$d}|S)N�z--concurrentz-Lr)rr)rr�retrrrrEs
z"ebtables._detect_concurrent_optioncCs.g}y|j|d�Wntk
r(dSXdS)N�offFT)�	set_rules�
ValueError)r�rulesrrrrOsz'ebtables._detect_restore_noflush_optioncCs�g}|jr |j|kr |j|j�|dd�|D�7}tjd|j|jdj|��t|j|�\}}|dkr~td|jdj|�|f��|S)NcSsg|]}d|�qS)z%sr)�.0�itemrrr�
<listcomp>^sz"ebtables.__run.<locals>.<listcomp>z	%s: %s %s� rz'%s %s' failed: %s)	r�appendr�debug2�	__class__r�joinrr )r�argsZ_args�statusrrrrZ__runYszebtables.__runcCs(x"dD]}||krttd|��qWdS)N�
%%REJECT%%�%%ICMP%%�%%LOGTYPE%%z'%s' invalid for ebtables)r,r-r.)r
r)r�rule�strrrr�_rule_validatefs
zebtables._rule_validatecCs|tko|t|kS)N)�BUILT_IN_CHAINS)rr
�table�chainrrr�is_chain_builtinlszebtables.is_chain_builtincCsJg}|r4|jd|d|g�|jd|d|dddg�n|jd|d|g�|S)Nz-tz-Nz-I�1z-jZRETURNz-X)r&)r�addr3r4r!rrr�build_chain_rulespszebtables.build_chain_rulescCs8d|g}|r |d|t|�g7}n|d|g7}||7}|S)Nz-tz-Iz-D)r0)rr7r3r4�indexr*r/rrr�
build_rule{szebtables.build_rulecCs
tj|�S)N)r	Zcommon_reverse_rule)rr*rrr�reverse_rule�szebtables.reverse_rulecCstj|�dS)N)r	Zcommon_check_passthrough)rr*rrr�check_passthrough�szebtables.check_passthroughcCs
tj|�S)N)r	Zcommon_reverse_passthrough)rr*rrr�reverse_passthrough�szebtables.reverse_passthroughc
Cs<t�}d}i}x�|D]�}|dd�}|j|�xTdD]L}y|j|�}	Wntk
rZYq4Xt|�|	dkr4|j|	�|j|	�}q4Wx^tt|��D]N}	xHtjD]>}
|
||	kr�||	j	d�o�||	j
d�r�d||	||	<q�Wq�W|j|g�j|�qWxD|D]<}|j
d|�x&||D]}|j
dj|�d	��qW�qW|j�tj|j�}tjd
|j|jd|j|jf�g}|jd�t|j||jd
�\}
}tj�dk�rt|j�}|dk	�rd}	xH|D]@}tjd|	|fddd�|j
d	��s�tjddd�|	d7}	�q�Wtj|j�|
dk�r8td|jdj|�|f��dS)Nr�-t�--table��"z"%s"z*%s
r%�
z	%s: %s %sz%s: %dz	--noflush)�stdin�z%8d: %sr)�nofmt�nlr)rEz'%s %s' failed: %s)r>r?)rr1r9r �len�pop�range�stringZ
whitespace�
startswith�endswith�
setdefaultr&�writer)�closer�stat�namerr'r(r�st_sizerZgetDebugLogLevelrZdebug3�unlink)rr!�
log_deniedZ	temp_filer3Ztable_rulesZ_ruler/�opt�i�crPr*r+r�lines�linerrrr�sZ




 




zebtables.set_rulescCs|j|�|j|�S)N)r1�_ebtables__run)rr/rTrrr�set_rule�s
zebtables.set_ruleNcCs�g}|r|gntj�}xp|D]h}||jkr6|j|�qy*|jd|dg�|jj|�|j|�Wqtk
r�tjd|�YqXqW|S)Nz-tz-Lz#ebtables table '%s' does not exist.)r2�keysrr&rZr rZdebug1)rr3rZtablesrrr�get_available_tables�s

zebtables.get_available_tablescCsiS)Nr)rr3rrr�get_zone_table_chains�szebtables.get_zone_table_chainscCsFg}x<tj�D]0}||j�kr qxdD]}|jd||g�q&WqW|S)N�-F�-X�-Zz-t)r_r`ra)r2r\r]r&)rr!r3�flagrrr�build_flush_rules�s
zebtables.build_flush_rulescCs^g}|dkrdn|}xDtj�D]8}||j�kr0qx$t|D]}|jd|d||g�q:WqW|S)NZPANICZDROPz-tz-P)r2r\r]r&)rZpolicyr!Z_policyr3r4rrr�build_set_policy_rules�szebtables.build_set_policy_rulescCsgS)Nr)rrrr�build_default_tables�szebtables.build_default_tablesrcCs�g}x�tD]�}||j�krq
t|dd�}|dkrJ|tkrJ|jt|�d|g}x:|D]2}t|�tkrx|j||�qX|j|t|��qXWq
W|S)Nrz-t)�
DEFAULT_RULESr]�	LOG_RULES�extend�type�listr&r)rrTZ
default_rulesr3Z_default_rules�prefixr/rrr�build_default_rules�s

zebtables.build_default_rulescCs
||jkS)N)r
)rr
rrr�is_ipv_supportedszebtables.is_ipv_supported)N)r)�__name__�
__module__�__qualname__r
rQZpolicies_supportedrrrrrZr1r5r8r:r;r<r=rr[r]r^rcrdrerlrmrrrrr4s0


	@


)�__all__Zos.pathrZfirewall.core.progrZfirewall.core.loggerrZfirewall.functionsrrrZfirewall.configrZ
firewall.corer	Zfirewall.errorsr
rrJr2rfrgZ
OUR_CHAINSr\r3�setr4r&r7�objectrrrrr�<module>s.
core/__pycache__/fw_transaction.cpython-36.opt-1.pyc000064400000011650150351351730016320 0ustar003

��g��@sJdZdgZddlZddlmZddlmZddlmZGdd�de	�Z
dS)z!Transaction classes for firewalld�FirewallTransaction�N)�log)�errors)�
FirewallErrorc@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#S)$rcCs(||_i|_g|_g|_g|_g|_dS)N)�fw�rules�	pre_funcs�
post_funcs�
fail_funcs�modules)�selfr�r
�$/usr/lib/python3.6/fw_transaction.py�__init__!szFirewallTransaction.__init__cCs2|jj�|jdd�=|jdd�=|jdd�=dS)N)r�clearrr	r
)rr
r
rr)s
zFirewallTransaction.clearcCs|jj|jg�j|�dS)N)r�
setdefault�name�append)r�backend�ruler
r
r�add_rule/szFirewallTransaction.add_rulecCsx|D]}|j||�qWdS)N)r)rrrrr
r
r�	add_rules2s
zFirewallTransaction.add_rulescCs|j|jko||j|jkS)N)rr)rrrr
r
r�
query_rule6szFirewallTransaction.query_rulecCs2|j|jkr.||j|jkr.|j|jj|�dS)N)rr�remove)rrrr
r
r�remove_rule9szFirewallTransaction.remove_rulecGs|jj||f�dS)N)rr)r�func�argsr
r
r�add_pre=szFirewallTransaction.add_precGs|jj||f�dS)N)r	r)rrrr
r
r�add_post@szFirewallTransaction.add_postcGs|jj||f�dS)N)r
r)rrrr
r
r�add_failCszFirewallTransaction.add_failcCs||jkr|jj|�dS)N)rr)r�moduler
r
r�
add_moduleFs
zFirewallTransaction.add_modulecCs||jkr|jj|�dS)N)rr)rr r
r
r�
remove_moduleJs
z!FirewallTransaction.remove_modulecCsx|D]}|j|�qWdS)N)r!)rrr r
r
r�add_modulesNs
zFirewallTransaction.add_modulescCsx|D]}|j|�qWdS)N)r")rrr r
r
r�remove_modulesRs
z"FirewallTransaction.remove_modulescCs�tjdt|�|df�i}|sjxp|jD]<}x6t|j|�D]$}|j|g�j|jj|�j	|��q<Wq(Wn(x&|jD]}|j|g�j
|j|�qrW||jfS)Nz%s.prepare(%s, %s)z...)r�debug4�typer�reversedrrr�get_backend_by_name�reverse_rule�extendr)r�enabler�backend_namerr
r
r�prepareVszFirewallTransaction.preparecCstjdt|�|f�|j|�\}}|j�d}d}g}xp|D]h}y|jj|||�WnBtk
r�}z&d}|}tjt	j
��tj|�WYdd}~Xq>X|j|�q>W|s�|jj
||�}	|	r�|	\}
}|
r�tj|�|�ri}xH|D]@}g||<x2t||�D]"}||j|jj|�j|���qWq�Wxb|D]Z}y|jj|||�Wn<tk
�r�}ztjt	j
��tj|�WYdd}~XnX�q0Wxh|jD]^\}
}y|
|�WnFtk
�r�}z(tjt	j
��tjd|
||f�WYdd}~XnX�q�Wttj|��|j�dS)Nz%s.execute(%s)F�Tz#Calling fail func %s(%s) failed: %s)rr%r&r-�prerr�	Exception�debug1�	traceback�
format_exc�errorrZhandle_modulesr'r(r)r
rrZCOMMAND_FAILED�post)rr+rrr4ZerrorMsg�doner,�msgZ
module_returnZstatusZ
undo_rulesrrrr
r
r�executefsV



"&zFirewallTransaction.executecCs|tjdt|��xd|jD]Z\}}y||�Wqtk
rr}z(tjtj��tjd|||f�WYdd}~XqXqWdS)Nz%s.pre()z"Calling pre func %s(%s) failed: %s)	rr%r&rr0r1r2r3r4)rrrr7r
r
rr/�szFirewallTransaction.precCs|tjdt|��xd|jD]Z\}}y||�Wqtk
rr}z(tjtj��tjd|||f�WYdd}~XqXqWdS)Nz	%s.post()z#Calling post func %s(%s) failed: %s)	rr%r&r	r0r1r2r3r4)rrrr7r
r
rr5�szFirewallTransaction.postN)�__name__�
__module__�__qualname__rrrrrrrrrr!r"r#r$r-r8r/r5r
r
r
rr s"@)�__doc__�__all__r2Zfirewall.core.loggerrZfirewallrZfirewall.errorsr�objectrr
r
r
r�<module>score/__pycache__/__init__.cpython-36.pyc000064400000000161150351351730014072 0ustar003

��g�@sdS)N�rrr�/usr/lib/python3.6/__init__.py�<module>score/__pycache__/__init__.cpython-36.opt-1.pyc000064400000000161150351351730015031 0ustar003

��g�@sdS)N�rrr�/usr/lib/python3.6/__init__.py�<module>score/__pycache__/ipset.cpython-36.opt-1.pyc000064400000021161150351351730014421 0ustar003

��gq2�@s�dZdddgZddlZddlZddlmZddlmZddl	m
Z
dd	lmZdd
l
mZmZddlmZdZd
ddddddddddgZddddd�Zdddd�ZGd d�de�Zd!d�Zd"d�Zd#d$�Zd%d&�Zd'd(�ZdS))zThe ipset command wrapper�ipset�check_ipset_name�remove_default_create_options�N)�errors)�
FirewallError)�runProg)�log)�tempFile�readfile)�COMMANDS� zhash:ipzhash:ip,portzhash:ip,port,ipzhash:ip,port,netzhash:ip,markzhash:netzhash:net,netz
hash:net,portzhash:net,port,netzhash:net,ifacezhash:macz
inet|inet6�valuez
value in secs)�family�hashsize�maxelem�timeoutZinetZ1024Z65536)rrrc@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zd'd
d�Z	dd�Z
dd�Zdd�Zd(dd�Z
d)dd�Zdd�Zd*dd�Zd+dd�Zdd �Zd!d"�Zd#d$�Zd%d&�ZdS),rzipset command wrapper classcCstd|_d|_dS)Nr)r�_command�name)�self�r�/usr/lib/python3.6/ipset.py�__init__Ks
zipset.__init__cCs^dd�|D�}tjd|j|jdj|��t|j|�\}}|dkrZtd|jdj|�|f��|S)zCall ipset with argscSsg|]}d|�qS)z%sr)�.0�itemrrr�
<listcomp>Rszipset.__run.<locals>.<listcomp>z	%s: %s %s� rz'%s %s' failed: %s)r�debug2�	__class__r�joinr�
ValueError)r�argsZ_args�status�retrrrZ__runOszipset.__runcCs t|�tkrttjd|��dS)zCheck ipset namezipset name '%s' is not validN)�len�IPSET_MAXNAMELENrrZINVALID_NAME)rrrrr�
check_nameZszipset.check_namecCs�g}d}y|jdg�}Wn0tk
rH}ztjd|�WYdd}~XnX|j�}d}xT|D]L}|r�|j�jdd�}|d|kr�|dtkr�|j|d�|j	d�r\d	}q\W|S)
z?Return types that are supported by the ipset command and kernel�z--helpzipset error: %sNF�rzSupported set types:T)
�_ipset__runrrZdebug1�
splitlines�strip�split�IPSET_TYPES�append�
startswith)rr"�outputZex�linesZin_types�line�splitsrrr�set_supported_types`s  

zipset.set_supported_typescCs(t|�tks|tkr$ttjd|��dS)zCheck ipset typez!ipset type name '%s' is not validN)r#r$r,rrZINVALID_TYPE)r�	type_namerrr�
check_typeuszipset.check_typeNcCsd|j|�|j|�d||g}t|t�rZx0|j�D]$\}}|j|�|dkr2|j|�q2W|j|�S)z+Create an ipset with name, type and options�creater&)r%r5�
isinstance�dict�itemsr-r()r�set_namer4�optionsr �key�valrrr�
set_create{s




zipset.set_createcCs|j|�|jd|g�S)NZdestroy)r%r()rr:rrr�set_destroy�s
zipset.set_destroycCsd||g}|j|�S)N�add)r()rr:�entryr rrr�set_add�s
z
ipset.set_addcCsd||g}|j|�S)N�del)r()rr:rAr rrr�
set_delete�s
zipset.set_deletecCs,d||g}|r"|jddj|��|j|�S)N�testz%sr)r-rr()rr:rAr;r rrrrE�s
z
ipset.testcCs2dg}|r|j|�|r"|j|�|j|�jd�S)N�list�
)r-�extendr(r+)rr:r;r rrr�set_list�s

zipset.set_listcCs<|jdgd�}i}d}}i}�x|D�]}t|�dkr:q&dd�|jdd�D�}t|�dkr`q&q&|d	d
krv|d}q&|d	dkr�|d}q&|d	dkr&|dj�}d	}	x^|	t|�k�r||	}
|
dk�r�t|�|	kr�|	d7}	||	||
<ntjd|�iS|	d7}	q�W|�r$|�r$|t|�f||<d}}|j�q&W|S)z" Get active ipsets (only headers) z-terse)r;N�cSsg|]}|j��qSr)r*)r�xrrrr�sz.ipset.set_get_active_terse.<locals>.<listcomp>�:r'r�NameZTypeZHeaderrrrr�netmaskz&Malformed ipset list -terse output: %s)rrrrrN)rIr#r+r�errorr�clear)rr0r"�_nameZ_type�_optionsr1Zpairr2�i�optrrr�set_get_active_terse�sD

zipset.set_get_active_tersecCsdg}|r|j|�|j|�S)N�save)r-r()rr:r rrrrV�s
z
ipset.savecCs�|j|�|j|�t�}d|kr*d|}d||dg}|rlx0|j�D]$\}}	|j|�|	dkrD|j|	�qDW|jddj|��|jd|�xN|D]F}
d|
kr�d|
}
|r�|jd||
dj|�f�q�|jd	||
f�q�W|j�tj	|j
�}tjd
|j
|jd|j
|jf�dg}t|j||j
d
�\}}
tj�dk�r�yt|j
�Wntk
�r`YnVXd}xNt|j
�D]@}tjd||fddd�|jd��s�tjddd�|d7}�qrWtj|j
�|dk�r�td|jdj|�|
f��|
S)Nrz'%s'r6z-existr&z%s
z	flush %s
z
add %s %s %s
z
add %s %s
z%s: %s restore %sz%s: %dZrestore)�stdinr'rJz%8d: %sr)�nofmt�nlrG)rXz'%s %s' failed: %s)r%r5r	r9r-�writer�close�os�statrrrrr�st_sizerZgetDebugLogLevelr
�	ExceptionZdebug3�endswith�unlinkr)rr:r4�entriesZcreate_optionsZ
entry_optionsZ	temp_filer r<r=rAr]r!r"rSr1rrr�set_restore�sV




zipset.set_restorecCsdg}|r|j|�|j|�S)N�flush)r-r()rr:r rrr�	set_flushs
zipset.set_flushcCs|jd||g�S)N�rename)r()rZold_set_nameZnew_set_namerrrrf
szipset.renamecCs|jd||g�S)N�swap)r()rZ
set_name_1Z
set_name_2rrrrgsz
ipset.swapcCs|jdg�S)N�version)r()rrrrrhsz
ipset.version)N)N)NN)N)NN)�__name__�
__module__�__qualname__�__doc__rr(r%r3r5r>r?rBrDrErIrUrVrcrerfrgrhrrrrrHs&



'

7cCst|�tkrdSdS)z"Return true if ipset name is validFT)r#r$)rrrrrscCs8|j�}x*tD]"}||krt|||kr||=qW|S)z( Return only non default create options )�copy�IPSET_DEFAULT_CREATE_OPTIONS)r;rRrTrrrrs

c
Cshg}xX|jd�D]J}y&|jd�|jttj|dd���Wqtk
rX|j|�YqXqWdj|�S)z! Normalize IP addresses in entry �,�/F)�strict)r+�indexr-�str�	ipaddress�
ip_networkrr)rAZ_entryZ_partrrr�normalize_ipset_entry&s
rvcCsxt|jd��dkrdSytj|dd�}Wntk
r<dSXx4|D],}|jtj|dd��rDttjdj	||���qDWdS)z: Check if entry overlaps any entry in the list of entries rorJNF)rqz,Entry '{}' overlaps with existing entry '{}')
r#r+rtrur�overlapsrr�
INVALID_ENTRY�format)rArbZ
entry_networkZitrrrr�check_entry_overlaps_existing2s
rzcCs~ydd�|D�}Wntk
r&dSXt|�dkr8dS|j�|jd�}x.|D]&}|j|�rrttjdj||���|}qPWdS)z> Check if any entry overlaps any entry in the list of entries cSsg|]}tj|dd��qS)F)rq)rtru)rrKrrrrEsz1check_for_overlapping_entries.<locals>.<listcomp>NrzEntry '{}' overlaps entry '{}')	rr#�sort�poprwrrrxry)rbZprev_networkZcurrent_networkrrr�check_for_overlapping_entriesBs2


r})rl�__all__Zos.pathr\rtZfirewallrZfirewall.errorsrZfirewall.core.progrZfirewall.core.loggerrZfirewall.functionsr	r
Zfirewall.configrr$r,ZIPSET_CREATE_OPTIONSrn�objectrrrrvrzr}rrrr�<module>sF
P	core/__pycache__/logger.cpython-36.opt-1.pyc000064400000055135150351351730014564 0ustar003

��g>y�@s�ddddgZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z
ddl
Z
Gdd�de�ZGdd�de�Z
Gd	d
�d
e
�ZGdd�de�ZGd
d�de�ZGdd�de�Ze�ZdS)�	LogTarget�FileLog�Logger�log�Nc@s2eZdZdZdd�Zddd�Zdd�Zd	d
�ZdS)
rz% Abstract class for logging targets. cCs
d|_dS)N)�fd)�self�r�/usr/lib/python3.6/logger.py�__init__(szLogTarget.__init__rcCstd��dS)Nz%LogTarget.write is an abstract method)�NotImplementedError)r�data�level�logger�is_debugrrr	�write+szLogTarget.writecCstd��dS)Nz%LogTarget.flush is an abstract method)r)rrrr	�flush.szLogTarget.flushcCstd��dS)Nz%LogTarget.close is an abstract method)r)rrrr	�close1szLogTarget.closeN)r)�__name__�
__module__�__qualname__�__doc__r
rrrrrrr	r&s

c@s.eZdZdd�Zddd�Zdd�Zdd	�Zd
S)�
_StdoutLogcCstj|�tj|_dS)N)rr
�sys�stdoutr)rrrr	r
8s
z_StdoutLog.__init__rcCs|jj|�|j�dS)N)rrr)rrr
rrrrr	r<sz_StdoutLog.writecCs|j�dS)N)r)rrrr	rAsz_StdoutLog.closecCs|jj�dS)N)rr)rrrr	rDsz_StdoutLog.flushN)r)rrrr
rrrrrrr	r7s
rc@seZdZdd�ZdS)�
_StderrLogcCstj|�tj|_dS)N)rr
r�stderrr)rrrr	r
Ks
z_StderrLog.__init__N)rrrr
rrrr	rJsrc@s.eZdZdd�Zddd�Zdd�Zdd	�Zd
S)�
_SyslogLogcCs.tj|�tjtjjtjd�tj	tj
�dS)Nr)rr
�syslogZopenlog�os�path�basenamer�argvZLOG_PIDZ
LOG_DAEMON)rrrr	r
Ss
	z_SyslogLog.__init__rcCs�d}|rtj}nF||jkr"tj}n4||jkr4tj}n"||jkrFtj}n||jkrVtj	}|j
d�rt|dt|�d�}t|�dkr�|dkr�tj|�ntj||�dS)N�
�r)rZ	LOG_DEBUG�INFO1ZLOG_INFO�WARNINGZLOG_WARNING�ERRORZLOG_ERR�FATALZLOG_CRIT�endswith�len)rrr
rrZpriorityrrr	ras"




z_SyslogLog.writecCstj�dS)N)rZcloselog)rrrr	rwsz_SyslogLog.closecCsdS)Nr)rrrr	rzsz_SyslogLog.flushN)r)rrrr
rrrrrrr	rRs
rc@s<eZdZdZddd�Zdd�Zddd	�Zd
d�Zdd
�ZdS)rz< FileLog class.
    File will be opened on the first write. �wcCstj|�||_||_dS)N)rr
�filename�mode)rr+r,rrr	r
�s
zFileLog.__init__cCsv|jr
dStjtjB}|jjd�r,|tjO}tj|j|d�|_tj	|jd�tj
|j|j�|_tj|jtjtj
�dS)N�ai�)rr�O_CREAT�O_WRONLYr,�
startswith�O_APPEND�openr+�fchmod�fdopen�fcntlZF_SETFDZ
FD_CLOEXEC)r�flagsrrr	r2�s
zFileLog.openrcCs(|js|j�|jj|�|jj�dS)N)rr2rr)rrr
rrrrr	r�sz
FileLog.writecCs|js
dS|jj�d|_dS)N)rr)rrrr	r�s
z
FileLog.closecCs|js
dS|jj�dS)N)rr)rrrr	r�sz
FileLog.flushN)r*)r)	rrrrr
r2rrrrrrr	rs

c@s�eZdZdZd[Zd\Zd]Zd^Zd_ZdZ	e
�Ze�Z
e�Zd`d	d
�Zdd�Zdadd�Zdbdd�Zdcdd�Zdddd�Zdd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zed"fd#d$�Zed"fd%d&�Zed"fd'd(�Zed"fd)d*�Zed"fd+d,�Z ed"fd-d.�Z!d/d0�Z"d1d2�Z#d3d4�Z$d5d6�Z%d7d8�Z&d9d:�Z'd;d<�Z(d=d>�Z)d?d@�Z*dAdB�Z+dCdD�Z,dedEdF�Z-dGdH�Z.dfdIdJ�Z/ed"dfdKdL�Z0ed"dfdMdN�Z1ed"dfdOdP�Z2dgdQdR�Z3dSdT�Z4dUdV�Z5dWdX�Z6dhdYdZ�Z7d"S)iraL	
    Format string:

    %(class)s      Calling class the function belongs to, else empty
    %(date)s       Date using Logger.date_format, see time module
    %(domain)s     Full Domain: %(module)s.%(class)s.%(function)s
    %(file)s       Filename of the module
    %(function)s   Function name, empty in __main__
    %(label)s      Label according to log function call from Logger.label
    %(level)d      Internal logging level
    %(line)d       Line number in module
    %(module)s     Module name
    %(message)s    Log message

    Standard levels:

    FATAL                 Fatal error messages
    ERROR                 Error messages
    WARNING               Warning messages
    INFOx, x in [1..5]    Information
    DEBUGy, y in [1..10]  Debug messages
    NO_INFO               No info output
    NO_DEBUG              No debug output
    INFO_MAX              Maximum info level
    DEBUG_MAX             Maximum debug level

    x and y depend on info_max and debug_max from Logger class
    initialization. See __init__ function.

    Default logging targets:

    stdout        Logs to stdout
    stderr        Logs to stderr
    syslog        Logs to syslog

    Additional arguments for logging functions (fatal, error, warning, info
    and debug):

    nl       Disable newline at the end with nl=0, default is nl=1.
    fmt      Format string for this logging entry, overloads global format
             string. Example: fmt="%(file)s:%(line)d %(message)s"
    nofmt    Only output message with nofmt=1. The nofmt argument wins over
             the fmt argument.

    Example:

    from logger import log
    log.setInfoLogLevel(log.INFO1)
    log.setDebugLogLevel(log.DEBUG1)
    for i in range(1, log.INFO_MAX+1):
        log.setInfoLogLabel(i, "INFO%d: " % i)
    log.setFormat("%(date)s %(module)s:%(line)d [%(domain)s] %(label)s: "
                  "%(level)d %(message)s")
    log.setDateFormat("%Y-%m-%d %H:%M:%S")

    fl = FileLog("/tmp/log", "a")
    log.addInfoLogging("*", fl)
    log.addDebugLogging("*", fl)
    log.addInfoLogging("*", log.syslog, fmt="%(label)s%(message)s")

    log.debug3("debug3")
    log.debug2("debug2")
    log.debug1("debug1")
    log.info2("info2")
    log.info1("info1")
    log.warning("warning\n", nl=0)
    log.error("error\n", nl=0)
    log.fatal("fatal")
    log.info(log.INFO1, "nofmt info", nofmt=1)

    ����r#r�
cCs�i|_i|_d|_d|_i|_i|_i|_i|_i|_i|_	|dkrPt
d|��|dkrdt
d|��|j|_||_
d|_||_|j|jd�|j|jd�|j|jd�|j|jd�xNtd|j
d�D]:}t|d	||�|j|d�t|d
|dd�||��q�WxTtd|jd�D]@}t|d
||�|j|d|�t|d|dd�||���qW|j|j�|j|j�|jd�|jd�|jd|j|j|j|jg�|jd|jdd�t|j|j
d�D��|jd|jdd�td|jd�D��dS)z Logger class initialization �r#zLogger: info_max %d is too lowrzLogger: debug_max %d is too lowz
FATAL ERROR: zERROR: z	WARNING: zINFO%dzinfo%dcs��fdd�S)Ncs�j�|f|�|�S)N)�info)�message�args�kwargs)r�xrr	�<lambda> sz3Logger.__init__.<locals>.<lambda>.<locals>.<lambda>r)rrAr)rrAr	rBsz!Logger.__init__.<locals>.<lambda>zDEBUG%dz	DEBUG%d: zdebug%dcs��fdd�S)Ncs�j�|f|�|�S)N)�debug)r>r?r@)rrArr	rB)sz3Logger.__init__.<locals>.<lambda>.<locals>.<lambda>r)rrAr)rrAr	rB(sz%(label)s%(message)sz%d %b %Y %H:%M:%S�*cSsg|]}|�qSrr)�.0�irrr	�
<listcomp>4sz#Logger.__init__.<locals>.<listcomp>cSsg|]}|�qSrr)rErFrrr	rG6sN) �_level�_debug_level�_format�_date_format�_label�_debug_label�_logging�_debug_logging�_domains�_debug_domains�
ValueErrorr%�NO_INFO�INFO_MAX�NO_DEBUG�	DEBUG_MAX�setInfoLogLabelr'�	TRACEBACKr&�range�setattr�setDebugLogLabel�setInfoLogLevelr$�setDebugLogLevel�	setFormat�
setDateFormat�setInfoLoggingrr�setDebugLogging)rZinfo_maxZ	debug_maxrHrrr	r
�sX






zLogger.__init__cCsNxHt|j|jd�D]2}||jkr$qx |j|D]\}}}|j�q0WqWdS)z Close all logging targets r#N)rYr'rVrNr)rr
�dummy�targetrrr	r8s

zLogger.closerDcCs$|j|�||jkr|j|S|jS)z Get info log level. )�_checkDomainrH�NOTHING)r�domainrrr	�getInfoLogLevel@s


zLogger.getInfoLogLevelcCs8|j|�||jkr|j}||jkr*|j}||j|<dS)z% Set log level [NOTHING .. INFO_MAX] N)rdrerTrH)rr
rfrrr	r\Gs


zLogger.setInfoLogLevelcCs*|j|�||jkr$|j||jS|jS)z Get debug log level. )rdrIrU)rrfrrr	�getDebugLogLevelPs

zLogger.getDebugLogLevelcCs:|j|�|dkrd}||jkr&|j}||j|j|<dS)z- Set debug log level [NO_DEBUG .. DEBUG_MAX] rN)rdrVrUrI)rr
rfrrr	r]Ws

zLogger.setDebugLogLevelcCs|jS)N)rJ)rrrr	�	getFormat`szLogger.getFormatcCs
||_dS)N)rJ)rrJrrr	r^cszLogger.setFormatcCs|jS)N)rK)rrrr	�
getDateFormatfszLogger.getDateFormatcCs
||_dS)N)rK)rrJrrr	r_iszLogger.setDateFormatcCs:|j|�}x*|D]"}|j||j|jd�||j|<qWdS)zU Set log label for level. Level can be a single level or an array
        of levels. )�	min_level�	max_levelN)�
_getLevels�_checkLogLevelr'rTrL)rr
�label�levelsrrr	rWls




zLogger.setInfoLogLabelcCs>|j|dd�}x*|D]"}|j||j|jd�||j|<qWdS)zU Set log label for level. Level can be a single level or an array
        of levels. r#)r)rkrlN)rmrnr$rVrM)rr
rorprrr	r[us



zLogger.setDebugLogLabelNcCs|j||||dd�dS)z� Set info log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r)rN)�_setLogging)rrfrcr
�fmtrrr	r`~szLogger.setInfoLoggingcCs|j||||dd�dS)z� Set debug log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r#)rN)rq)rrfrcr
rrrrr	ra�szLogger.setDebugLoggingcCs|j||||dd�dS)z� Add info log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r)rN)�_addLogging)rrfrcr
rrrrr	�addInfoLogging�szLogger.addInfoLoggingcCs|j||||dd�dS)z� Add debg log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r#)rN)rs)rrfrcr
rrrrr	�addDebugLogging�szLogger.addDebugLoggingcCs|j||||dd�dS)z� Delete info log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r)rN)�_delLogging)rrfrcr
rrrrr	�delInfoLogging�szLogger.delInfoLoggingcCs|j||||dd�dS)z� Delete debug log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. r#)rN)rv)rrfrcr
rrrrr	�delDebugLogging�szLogger.delDebugLoggingcCs|j|dd�S)zN Is there currently any info logging for this log level (and
        domain)? r)r)�_isLoggingHere)rr
rrr	�isInfoLoggingHere�szLogger.isInfoLoggingHerecCs|j|dd�S)zO Is there currently any debug logging for this log level (and
        domain)? r#)r)ry)rr
rrr	�isDebugLoggingHere�szLogger.isDebugLoggingHerecOs,|j|�d|d<|j|j|f|�|�dS)z Fatal error log. rrN)�_checkKWargs�_logr')rrJr?r@rrr	�fatal�s
zLogger.fatalcOs,|j|�d|d<|j|j|f|�|�dS)z Error log. rrN)r|r}r&)rrJr?r@rrr	�error�s
zLogger.errorcOs,|j|�d|d<|j|j|f|�|�dS)z Warning log. rrN)r|r}r%)rrJr?r@rrr	�warning�s
zLogger.warningcOsB|j|d|jd�|j|�d|d<|j||j|f|�|�dS)z� Information log using info level [1..info_max].
        There are additional infox functions according to info_max from
        __init__r#)rkrlrrN)rnrTr|r}rS)rr
rJr?r@rrr	r=�s
zLogger.infocOs<|j|d|jd�|j|�d|d<|j||f|�|�dS)z� Debug log using debug level [1..debug_max].
        There are additional debugx functions according to debug_max
        from __init__r#)rkrlrN)rnrVr|r})rr
rJr?r@rrr	rC�s
zLogger.debugcCs|j|jtj�gid�dS)N)r?r@)r}rX�	traceback�
format_exc)rrrr	�	exception�szLogger.exceptioncCs&||ks||kr"td|||f��dS)Nz*Level %d out of range, should be [%d..%d].)rR)rr
rkrlrrr	rn�szLogger._checkLogLevelcCs2|sdSx$|j�D]}|dkrtd|��qWdS)N�nlrr�nofmtz0Key '%s' is not allowed as argument for logging.)r�rrr�)�keysrR)rr@�keyrrr	r|�s
zLogger._checkKWargscCs|s|dkrtd|��dS)Nr<zDomain '%s' is not valid.)rR)rrfrrr	rd�szLogger._checkDomaincCs�||jkrft|t�st|t�r$|}n|g}xp|D]0}|rL|j|d|jd�q0|j||j|jd�q0Wn6|r�dd�t|j	|j�D�}ndd�t|j|j�D�}|S)z Generate log level array. r#)rkrlcSsg|]}|�qSrr)rErFrrr	rG�sz%Logger._getLevels.<locals>.<listcomp>cSsg|]}|�qSrr)rErFrrr	rG�s)
�ALL�
isinstance�list�tuplernrVr'rTrYZDEBUG1)rr
rrprrr	rm�s


zLogger._getLevelscCsNt|t�st|t�r|}n|g}x(|D] }t|jt�s&td|jj��q&W|S)z Generate target array. z '%s' is no valid logging target.)r�r�r��
issubclass�	__class__rrRr)rrc�targetsZ_targetrrr	�_getTargets�s
zLogger._getTargetscCs�|r |j}|j}d|jdf}n|j}|j}|j|jdf}t|�dkrP|j�xVt	|d|d�D]@}||krrqdx0||D]$\}}}||kr||j
|g�j|�q|WqdWdS)z% Generate dict with domain by level. r#rN)rQrOrVrPrNr'rTr)�clearrY�
setdefault�append)rrrPrNZ_ranger
rfrbrrr	�_genDomainsszLogger._genDomainsc	Csl|j|�|j||�}|j|�}|r,|j}n|j}x*|D]"}x|D]}|||fg||<qBWq8W|j|�dS)N)rdrmr�rOrNr�)	rrfrcr
rrrrpr�rNrrr	rqs



zLogger._setLoggingc	Cst|j|�|j||�}|j|�}|r,|j}n|j}x2|D]*}x$|D]}|j|g�j|||f�qBWq8W|j|�dS)N)rdrmr�rOrNr�r�r�)	rrfrcr
rrrrpr�rNrrr	rs-s



 zLogger._addLoggingc
Cs�|j|�|j||�}|j|�}|r,|j}n|j}x�|D]|}	xv|D]n}|	|krPqB|||f||	kr�||	j|||f�t||	�dkr�||	=qB||jkrBtd|	||j	j
|f��qBWq8W|j|�dS)NrzDNo mathing logging for level %d, domain %s, target %s and format %s.)rdrmr�rOrN�remover)r�rRr�rr�)
rrfrcr
rrrrpr�rNrHrrr	rv<s&




zLogger._delLoggingcCst|j||�}|sdS|dd}|r,|j}n|j}x<||D]0\}}}|dksh|j|�shtj|d|�r<dSq<WdS)NFrf�.rDT)�_genDictrOrNr0�fnmatch�fnmatchcase)rr
r�_dict�point_domainrNrfrbrrr	ryUs
zLogger._isLoggingHerec	Cs�|jjdkrD|jjd}||jkrD|j|}|j|j|j�}|rD|Stj|j�}|j}|j|j	kr�t
|j	|jd�r�|j	|jj|kr�dSxT|j	j�D]F\}}t
|tj�r�t
||j�r�t||j�}t
|tj�r�|j|kr�|Sq�WdS)z7 Function to get calling class. Returns class or None. rZ	func_codeN)�f_code�co_argcount�co_varnames�f_locals�
_getClass2r��inspectZ	getmodule�co_name�__dict__�hasattr�__code__�itemsr��typesZ	ClassType�getattr�FunctionType)	r�frameZselfname�_self�obj�module�coderb�valuerrr	�	_getClassis*


zLogger._getClasscCsVx,|jj�D]}t|tj�r|j|kr|SqWx"|jD]}|j||�}|r6|Sq6WdS)z@ Internal function to get calling class. Returns class or None. N)r��valuesr�r�r�r��	__bases__r�)rr�r�r��baseZ_objrrr	r��s
zLogger._getClass2cOsld}d|kr|d}d}d|kr(|d}d}d|kr<|d}|j||�}|sPdSt|�dkrj|||d<n&t|�dkr�||d|d<n||d<|dd}	|r�|j}
n|j}
g}x�|
|D]�\}}
}|
|kr�q�|d	ks�|	j|d�s�tj|d|�r�|�s|j}d
|k�r|d
}|�r0|
j|d|||�n|
j|||||�|�rZ|
jd|||�|j	|
�q�WdS)Nrrr#r�r�r>rfr�rDrrr")
r�r)rOrNr0r�r�rJrr�)rr
rJr?r@rr�r�r�r�rNZused_targetsrfrcrrr	r}�sL
zLogger._logcCsg}d}|r |j}|j}|j}n|j}|j}|j}xN|D]F}|dkrh|||kr~d}t|�dkrdg}Pq8|||kr8|j|�q8W|r�t|�dkr�dS||kr�dStj	�}	x$|	r�|	j
r�|	jd|jkr�|	j
}	q�W|	s�t
d��|	jd}
|
d	}x|D]}|j|�r�g}Pq�W|	j}t|
�}
xx||D]l}|jd�}|dk�rD�q&n|dk�r\|d|�}n|}|
t|�k�r�|
j|��s�dSn|j|
��s&dS�q&Wd
}||k�r�||}|j|	j|
d
|jd
||tj|jtj��d�	}|dd
k�r�d
|d<d}x&||D]}|dk�r�q�d}P�q�W|jjd�dk�sR|jjd�dk�sR|�sRt|�dk�rl|j|	�}|�rl|j|d<d
|d|d<|dd
k�r�|dd	|d7<|dd
k�r�|dd	|d7<t|�dk�r�|S|dd	}x0|D](}|j|��stj|d|��r�|S�q�WdS)z Internal function. FrDTrr#Nrz Frame information not available.r�r<)	�file�liner��class�functionrfror
Zdater��?z	%(domain)z%(class)r�r�rf)rIrQrMrHrPrLr)r�r�Zcurrentframe�f_back�	f_globalsrrRr0r��find�co_filename�f_linenor��timeZstrftimerKZ	localtimerJr�rr�r�)rr
rZ
check_domainsZsimple_matchr�rPrLrf�fZmodule_nameZpoint_module�co�_lenrF�dZ	level_strZ
domain_neededr�r�rrr	r��s�














zLogger._genDict���������������)r7r;)rD)rD)rD)rD)r)r)r)r)8rrrrr�rer'rXr&r%rrrrrrr
rrgr\rhr]rir^rjr_rWr[r`rartrurwrxrzr{r~rr�r=rCr�rnr|rdrmr�r�rqrsrvryr�r�r}r�rrrr	r�sdG
;

	

					


 4)�__all__rr�r�r�r�rr�r5Zos.pathr�objectrrrrrrrrrrr	�<module>s.-(*4core/__pycache__/fw_direct.cpython-36.opt-1.pyc000064400000031230150351351730015241 0ustar003

��g�W�@sndgZddlmZddlmZddlmZddlmZddlm	Z	ddl
mZddlm
Z
Gd	d�de�Zd
S)�FirewallDirect�)�LastUpdatedOrderedDict)�	ipXtables)�ebtables)�FirewallTransaction)�log)�errors)�
FirewallErrorc@sLeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dNdd�Zdd�Zdd�Z
dOdd�Zdd�Zdd�Zdd�Zd d!�ZdPd"d#�ZdQd$d%�Zd&d'�Zd(d)�Zd*d+�ZdRd,d-�ZdSd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�ZdTd<d=�Z dUd>d?�Z!d@dA�Z"dBdC�Z#dDdE�Z$dFdG�Z%dHdI�Z&dJdK�Z'dLdM�Z(dS)VrcCs||_|j�dS)N)�_fw�_FirewallDirect__init_vars)�self�fw�r�/usr/lib/python3.6/fw_direct.py�__init__'szFirewallDirect.__init__cCsd|j|j|j|jfS)Nz%s(%r, %r, %r))�	__class__�_chains�_rules�_rule_priority_positions)rrrr�__repr__+szFirewallDirect.__repr__cCs"i|_i|_i|_i|_d|_dS)N)rrr�
_passthroughs�_obj)rrrrZ__init_vars/s
zFirewallDirect.__init_varscCs|j�dS)N)r)rrrr�cleanup6szFirewallDirect.cleanupcCs
t|j�S)N)rr
)rrrr�new_transaction;szFirewallDirect.new_transactioncCs
||_dS)N)r)r�objrrr�set_permanent_config@sz#FirewallDirect.set_permanent_configcCs*t|j�t|j�t|j�dkr&dSdS)NrTF)�lenrrr)rrrr�has_runtime_configurationCs"z(FirewallDirect.has_runtime_configurationcCsB|j�rdSt|jj��t|jj��t|jj��dkr>dSdS)NTrF)rrr�get_all_chains�
get_all_rules�get_all_passthroughs)rrrr�has_configurationHsz FirewallDirect.has_configurationNcCsP|dkr|j�}n|}|j|jj�|jj�|jj�f|�|dkrL|jd�dS)NT)r�
set_configrrrr �execute)r�use_transaction�transactionrrr�apply_directQs

zFirewallDirect.apply_directcCsi}i}i}xL|jD]B}|\}}x4|j|D]&}|jj|||�s,|j|g�j|�q,WqWxf|jD]\}|\}}}xL|j|D]>\}	}
|jj||||	|
�s|||kr�t�||<|	|||	|
f<q|WqbWxP|jD]F}x@|j|D]2}
|jj	||
�s�||k�r�g||<||j|
�q�Wq�W|||fS)N)
rr�query_chain�
setdefault�appendr�
query_rulerr�query_passthrough)rZchains�rulesZpassthroughs�table_id�ipv�table�chain�chain_id�priority�argsrrr�get_runtime_configbs,


z!FirewallDirect.get_runtime_configcCs|j|j|jfS)N)rrr)rrrr�
get_config�szFirewallDirect.get_configcCs�|dkr|j�}n|}|\}}}x||D]t}|\}}	xf||D]Z}
|j||	|
�s<y|j||	|
|d�Wq<tk
r�}ztjt|��WYdd}~Xq<Xq<Wq&Wx�|D]�}|\}}	}
xt||D]h\}
}|j||	|
|
|�s�y|j||	|
|
||d�Wq�tk
�r"}ztjt|��WYdd}~Xq�Xq�Wq�Wxx|D]p}xh||D]\}|j	||��s@y|j
|||d�Wn2tk
�r�}ztjt|��WYdd}~XnX�q@W�q2W|dk�r�|jd�dS)N)r$T)rr'�	add_chainr	rZwarning�strr*�add_ruler+�add_passthroughr#)rZconfr$r%rrrr-r.r/r0�errorr1r2r3rrrr"�s@



(

(
,
zFirewallDirect.set_configcCs*dddg}||kr&ttjd||f��dS)N�ipv4�ipv6Zebz'%s' not in '%s')r	rZINVALID_IPV)rr.Zipvsrrr�
_check_ipv�s
zFirewallDirect._check_ipvcCsF|j|�|dkrtjj�ntjj�}||krBttjd||f��dS)Nr;r<z'%s' not in '%s')r;r<)r=r�BUILT_IN_CHAINS�keysrr	rZ
INVALID_TABLE)rr.r/Ztablesrrr�_check_ipv_table�s

zFirewallDirect._check_ipv_tablecCs�|dkr4tj|}|jjr i}qH|jj|�j|}ntj|}tj|}||kr`tt	j
d|��||krxtt	j
d|��|dkr�|jjj|�dk	r�tt	j
d|��dS)Nr;r<zchain '%s' is built-in chainzchain '%s' is reservedzChain '%s' is reserved)r;r<)r;r<)rr>r
�nftables_enabled�get_direct_backend_by_ipv�
our_chainsrZ
OUR_CHAINSr	rZ
BUILTIN_CHAIN�zoneZzone_from_chainZ
INVALID_CHAIN)rr.r/r0Zbuilt_in_chainsrCrrr�_check_builtin_chain�s"




z#FirewallDirect._check_builtin_chaincCsH|r|jj|g�j|�n*|j|j|�t|j|�dkrD|j|=dS)Nr)rr(r)�remover)rr-r0�addrrr�_register_chain�s
zFirewallDirect._register_chaincCsV|dkr|j�}n|}|jj�r.|j|jj�|jd||||�|dkrR|jd�dS)NT)rr
�may_skip_flush_direct_backends�add_pre�flush_direct_backends�_chainr#)rr.r/r0r$r%rrrr6�s

zFirewallDirect.add_chaincCs>|dkr|j�}n|}|jd||||�|dkr:|jd�dS)NFT)rrLr#)rr.r/r0r$r%rrr�remove_chain�s
zFirewallDirect.remove_chaincCs:|j||�|j|||�||f}||jko8||j|kS)N)r@rEr)rr.r/r0r-rrrr'�s

zFirewallDirect.query_chaincCs,|j||�||f}||jkr(|j|SgS)N)r@r)rr.r/r-rrr�
get_chains�s


zFirewallDirect.get_chainscCsDg}x:|jD]0}|\}}x"|j|D]}|j|||f�q$WqW|S)N)rr))r�r�keyr.r/r0rrrrszFirewallDirect.get_all_chainscCsZ|dkr|j�}n|}|jj�r.|j|jj�|jd||||||�|dkrV|jd�dS)NT)rr
rIrJrK�_ruler#)rr.r/r0r2r3r$r%rrrr8	s

zFirewallDirect.add_rulecCsB|dkr|j�}n|}|jd||||||�|dkr>|jd�dS)NFT)rrQr#)rr.r/r0r2r3r$r%rrr�remove_rules
zFirewallDirect.remove_rulecCs2|j||�|||f}||jko0||f|j|kS)N)r@r)rr.r/r0r2r3r1rrrr*#s

zFirewallDirect.query_rulecCs6|j||�|||f}||jkr2t|j|j��SgS)N)r@r�listr?)rr.r/r0r1rrr�	get_rules)s


zFirewallDirect.get_rulesc	CsRg}xH|jD]>}|\}}}x.|j|D] \}}|j||||t|�f�q&WqW|S)N)rr)rS)rrOrPr.r/r0r2r3rrrr0s
 zFirewallDirect.get_all_rulescCs�|rr||jkrt�|j|<||j||<||jkr<i|j|<||j|krb|j|||7<q�||j||<n<|j||=t|j|�dkr�|j|=|j|||8<dS)Nr)rrrr)r�rule_idr1r2�enable�countrrr�_register_rule8s


zFirewallDirect._register_rulecCsVy|jj|jj|�j|�Stk
rP}ztj|�ttj	|��WYdd}~XnXdS)N)
r
�rulerB�name�	ExceptionrZdebug2r	rZCOMMAND_FAILED)rr.r3�msgrrr�passthroughLs

zFirewallDirect.passthroughcCsX|r*||jkrg|j|<|j|j|�n*|j|j|�t|j|�dkrT|j|=dS)Nr)rr)rFr)rr.r3rVrrr�_register_passthroughTs

z$FirewallDirect._register_passthroughcCsX|dkr|j�}n|}|jj�r.|j|jj�|jd|t|�|�|dkrT|jd�dS)NT)rr
rIrJrK�_passthroughrSr#)rr.r3r$r%rrrr9^s

zFirewallDirect.add_passthroughcCs@|dkr|j�}n|}|jd|t|�|�|dkr<|jd�dS)NFT)rr_rSr#)rr.r3r$r%rrr�remove_passthroughls
z!FirewallDirect.remove_passthroughcCs||jkot|�|j|kS)N)r�tuple)rr.r3rrrr+ws
z FirewallDirect.query_passthroughcCs>g}x4|jD]*}x$|j|D]}|j|t|�f�qWqW|S)N)rr)rS)rrOr.r3rrrr {s
z#FirewallDirect.get_all_passthroughscCs4g}||jkr0x |j|D]}|jt|��qW|S)N)rr)rS)rr.rOr3rrr�get_passthroughs�s

zFirewallDirect.get_passthroughscCs�g}x�|D]�}d}x�|D]�}y|j|�}Wntk
r>YqXt|�|krd||dkrd}||djd�}x.|D]&}	|dd�}
|	|
|d<|j|
�qxWqW|s
|j|�q
W|S)z5Split values combined with commas for options in optsF�,�TN)�index�
ValueErrorr�splitr))rr,ZoptsZ	out_rulesrYZ	processed�opt�i�items�itemrQrrr�split_value�s$


zFirewallDirect.split_valuec
Cs*|j||�|jjr2|dkr2|jjj||||�|}|jj|�}	|jjrd|	j|||�rdd|}n:|jjr�|dd�dkr�|	j|||dd��r�|dd�}|||f}
||f}|r�|
|jkr�||j|
kr�tt	j
d||||f��nB|
|jk�s||j|
k�rtt	jd||||f��|j|
|}d}d	}
|
|jk�r�t
|j|
j��}d	}x@|t|�k�r�|||k�r�||j|
||7}|d7}�qTWt|�g}|j|d
dg�}|j|dd
g�}x<|D]4}|j|	|	j||||t|���|d7}|
d7}
�q�W|j||
|||
�|j|j||
|||
�dS)Nr;r<z	%s_direct�Z_directz"rule '%s' already is in '%s:%s:%s'zrule '%s' is not in '%s:%s:%s'rdrz-sz--sourcez-dz
--destination)r;r<i����i����i����)r@r
rArD�create_zone_base_by_chainrBZis_chain_builtinrr	r�ALREADY_ENABLED�NOT_ENABLEDr�sortedr?rrSrlr8Z
build_rulerarX�add_fail)rrVr.r/r0r2r3r%rL�backendr1rUrerWZ	positions�jZ	args_list�_argsrrrrQ�sZ




(

zFirewallDirect._rulecCs�|j||�|j|||�||f}|rV||jkr�||j|kr�ttjd|||f��n.||jksn||j|kr�ttjd|||f��|jj|�}|j	||j
|||��|j|||�|j|j|||�dS)Nz chain '%s' already is in '%s:%s'zchain '%s' is not in '%s:%s')
r@rErr	rrorpr
rBZ	add_rulesZbuild_chain_rulesrHrr)rrGr.r/r0r%r-rsrrrrLs$

zFirewallDirect._chainc
Cs�|j|�t|�}|rD||jkrp||j|krpttjd||f��n,||jks\||j|krpttjd||f��|jj|�}|r�|j	|�|dkr�|j
|�\}}|r�|r�|jjj|||�|}	n
|j
|�}	|j||	�|j|||�|j|j|||�dS)Nzpassthrough '%s', '%s'r;r<)r;r<)r=rarr	rrorpr
rBZcheck_passthroughZpassthrough_parse_table_chainrDrnZreverse_passthroughr8r^rr)
rrVr.r3r%Z
tuple_argsrsr/r0rurrrr_'s0




zFirewallDirect._passthrough)N)N)N)N)N)N)N)N))�__name__�
__module__�__qualname__rrrrrrrr!r&r4r5r"r=r@rErHr6rMr'rNrr8rRr*rTrrXr]r^r9r`r+r rbrlrQrLr_rrrrr&sL	

'	

	




jN)�__all__Zfirewall.fw_typesrZ
firewall.corerrZfirewall.core.fw_transactionrZfirewall.core.loggerrZfirewallrZfirewall.errorsr	�objectrrrrr�<module>score/__pycache__/fw_helper.cpython-36.pyc000064400000003705150351351730014315 0ustar003

��g)�@s6dZdgZddlmZddlmZGdd�de�ZdS)zhelper backend�FirewallHelper�)�errors)�
FirewallErrorc@s\eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�ZdS)rcCs||_i|_dS)N)Z_fw�_helpers)�self�fw�r�/usr/lib/python3.6/fw_helper.py�__init__szFirewallHelper.__init__cCsd|j|jfS)Nz%s(%r))�	__class__r)rrrr	�__repr__"szFirewallHelper.__repr__cCs|jj�dS)N)r�clear)rrrr	�cleanup'szFirewallHelper.cleanupcCs||j�krttj|��dS)N)�get_helpersrr�INVALID_HELPER)r�namerrr	�check_helper*szFirewallHelper.check_helpercCs||j�kS)N)r)rrrrr	�query_helper.szFirewallHelper.query_helpercCst|jj��S)N)�sortedr�keys)rrrr	r1szFirewallHelper.get_helperscCst|j�dkS)Nr)�lenr)rrrr	�has_helpers4szFirewallHelper.has_helperscCs|j|�|j|S)N)rr)rrrrr	�
get_helper7s
zFirewallHelper.get_helpercCs||j|j<dS)N)rr)r�objrrr	�
add_helper;szFirewallHelper.add_helpercCs"||jkrttj|��|j|=dS)N)rrrr)rrrrr	�
remove_helper>s
zFirewallHelper.remove_helperN)
�__name__�
__module__�__qualname__r
rrrrrrrrrrrrr	rsN)�__doc__�__all__ZfirewallrZfirewall.errorsr�objectrrrrr	�<module>score/ebtables.py000064400000022256150351351730007641 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "ebtables" ]

import os.path
from firewall.core.prog import runProg
from firewall.core.logger import log
from firewall.functions import tempFile, readfile, splitArgs
from firewall.config import COMMANDS
from firewall.core import ipXtables # some common stuff lives there
from firewall.errors import FirewallError, INVALID_IPV
import string

BUILT_IN_CHAINS = {
    "broute": [ "BROUTING" ],
    "nat": [ "PREROUTING", "POSTROUTING", "OUTPUT" ],
    "filter": [ "INPUT", "OUTPUT", "FORWARD" ],
}

DEFAULT_RULES = { }
LOG_RULES = { }
OUR_CHAINS = {}  # chains created by firewalld

for table in BUILT_IN_CHAINS.keys():
    DEFAULT_RULES[table] = [ ]
    OUR_CHAINS[table] = set()
    for chain in BUILT_IN_CHAINS[table]:
        DEFAULT_RULES[table].append("-N %s_direct" % chain)
        DEFAULT_RULES[table].append("-I %s 1 -j %s_direct" % (chain, chain))
        DEFAULT_RULES[table].append("-I %s_direct 1 -j RETURN" % chain)
        OUR_CHAINS[table].add("%s_direct" % chain)

class ebtables(object):
    ipv = "eb"
    name = "ebtables"
    policies_supported = False # ebtables only supported with direct interface

    def __init__(self):
        self._command = COMMANDS[self.ipv]
        self._restore_command = COMMANDS["%s-restore" % self.ipv]
        self.restore_noflush_option = self._detect_restore_noflush_option()
        self.concurrent_option = self._detect_concurrent_option()
        self.fill_exists()
        self.available_tables = []

    def fill_exists(self):
        self.command_exists = os.path.exists(self._command)
        self.restore_command_exists = os.path.exists(self._restore_command)

    def _detect_concurrent_option(self):
        # Do not change any rules, just try to use the --concurrent option
        # with -L
        concurrent_option = ""
        ret = runProg(self._command, ["--concurrent", "-L"])
        if ret[0] == 0:
            concurrent_option = "--concurrent"  # concurrent for ebtables lock

        return concurrent_option

    def _detect_restore_noflush_option(self):
        # Do not change any rules, just try to use the restore command
        # with --noflush
        rules = [ ]
        try:
            self.set_rules(rules, "off")
        except ValueError:
            return False
        return True

    def __run(self, args):
        # convert to string list
        _args = [ ]
        if self.concurrent_option and self.concurrent_option not in args:
            _args.append(self.concurrent_option)
        _args += ["%s" % item for item in args]
        log.debug2("%s: %s %s", self.__class__, self._command, " ".join(_args))
        (status, ret) = runProg(self._command, _args)
        if status != 0:
            raise ValueError("'%s %s' failed: %s" % (self._command,
                                                     " ".join(args), ret))
        return ret

    def _rule_validate(self, rule):
        for str in ["%%REJECT%%", "%%ICMP%%", "%%LOGTYPE%%"]:
            if str in rule:
                raise FirewallError(INVALID_IPV,
                        "'%s' invalid for ebtables" % str)

    def is_chain_builtin(self, ipv, table, chain):
        return table in BUILT_IN_CHAINS and \
               chain in BUILT_IN_CHAINS[table]

    def build_chain_rules(self, add, table, chain):
        rules = []

        if add:
            rules.append([ "-t", table, "-N", chain ])
            rules.append([ "-t", table, "-I", chain, "1", "-j", "RETURN" ])
        else:
            rules.append([ "-t", table, "-X", chain ])

        return rules

    def build_rule(self, add, table, chain, index, args):
        rule = [ "-t", table ]
        if add:
            rule += [ "-I", chain, str(index) ]
        else:
            rule += [ "-D", chain ]
        rule += args
        return rule

    def reverse_rule(self, args):
        return ipXtables.common_reverse_rule(args)

    def check_passthrough(self, args):
        ipXtables.common_check_passthrough(args)

    def reverse_passthrough(self, args):
        return ipXtables.common_reverse_passthrough(args)

    def set_rules(self, rules, log_denied):
        temp_file = tempFile()

        table = "filter"
        table_rules = { }
        for _rule in rules:
            rule = _rule[:]

            self._rule_validate(rule)

            # get table form rule
            for opt in [ "-t", "--table" ]:
                try:
                    i = rule.index(opt)
                except ValueError:
                    pass
                else:
                    if len(rule) >= i+1:
                        rule.pop(i)
                        table = rule.pop(i)

            # we can not use joinArgs here, because it would use "'" instead
            # of '"' for the start and end of the string, this breaks
            # iptables-restore
            for i in range(len(rule)):
                for c in string.whitespace:
                    if c in rule[i] and not (rule[i].startswith('"') and
                                             rule[i].endswith('"')):
                        rule[i] = '"%s"' % rule[i]

            table_rules.setdefault(table, []).append(rule)

        for table in table_rules:
            temp_file.write("*%s\n" % table)
            for rule in table_rules[table]:
                temp_file.write(" ".join(rule) + "\n")

        temp_file.close()

        stat = os.stat(temp_file.name)
        log.debug2("%s: %s %s", self.__class__, self._restore_command,
                   "%s: %d" % (temp_file.name, stat.st_size))
        args = [ ]
        args.append("--noflush")

        (status, ret) = runProg(self._restore_command, args,
                                stdin=temp_file.name)

        if log.getDebugLogLevel() > 2:
            lines = readfile(temp_file.name)
            if lines is not None:
                i = 1
                for line in lines:
                    log.debug3("%8d: %s" % (i, line), nofmt=1, nl=0)
                    if not line.endswith("\n"):
                        log.debug3("", nofmt=1)
                    i += 1

        os.unlink(temp_file.name)

        if status != 0:
            raise ValueError("'%s %s' failed: %s" % (self._restore_command,
                                                     " ".join(args), ret))

    def set_rule(self, rule, log_denied):
        self._rule_validate(rule)
        return self.__run(rule)

    def get_available_tables(self, table=None):
        ret = []
        tables = [ table ] if table else BUILT_IN_CHAINS.keys()
        for table in tables:
            if table in self.available_tables:
                ret.append(table)
            else:
                try:
                    self.__run(["-t", table, "-L"])
                    self.available_tables.append(table)
                    ret.append(table)
                except ValueError:
                    log.debug1("ebtables table '%s' does not exist." % table)

        return ret

    def get_zone_table_chains(self, table):
        return {}

    def build_flush_rules(self):
        rules = []
        for table in BUILT_IN_CHAINS.keys():
            if table not in self.get_available_tables():
                continue
            # Flush firewall rules: -F
            # Delete firewall chains: -X
            # Set counter to zero: -Z
            for flag in [ "-F", "-X", "-Z" ]:
                rules.append(["-t", table, flag])
        return rules

    def build_set_policy_rules(self, policy):
        rules = []
        _policy = "DROP" if policy == "PANIC" else policy
        for table in BUILT_IN_CHAINS.keys():
            if table not in self.get_available_tables():
                continue
            for chain in BUILT_IN_CHAINS[table]:
                rules.append(["-t", table, "-P", chain, _policy])
        return rules

    def build_default_tables(self):
        # nothing to do, they always exist
        return []

    def build_default_rules(self, log_denied="off"):
        default_rules = []
        for table in DEFAULT_RULES:
            if table not in self.get_available_tables():
                continue
            _default_rules = DEFAULT_RULES[table][:]
            if log_denied != "off" and table in LOG_RULES:
                _default_rules.extend(LOG_RULES[table])
            prefix = [ "-t", table ]
            for rule in _default_rules:
                if type(rule) == list:
                    default_rules.append(prefix + rule)
                else:
                    default_rules.append(prefix + splitArgs(rule))
        return default_rules

    def is_ipv_supported(self, ipv):
        return ipv == self.ipv
core/rich.py000064400000102070150351351730006776 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2013-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "Rich_Source", "Rich_Destination", "Rich_Service", "Rich_Port",
            "Rich_Protocol", "Rich_Masquerade", "Rich_IcmpBlock",
            "Rich_IcmpType",
            "Rich_SourcePort", "Rich_ForwardPort", "Rich_Log", "Rich_Audit",
            "Rich_Accept", "Rich_Reject", "Rich_Drop", "Rich_Mark",
            "Rich_Limit", "Rich_Rule" ]

from firewall import functions
from firewall.core.ipset import check_ipset_name
from firewall.core.base import REJECT_TYPES
from firewall import errors
from firewall.errors import FirewallError

class Rich_Source(object):
    def __init__(self, addr, mac, ipset, invert=False):
        self.addr = addr
        if self.addr == "":
            self.addr = None
        self.mac = mac
        if self.mac == "" or self.mac is None:
            self.mac = None
        elif self.mac is not None:
            self.mac = self.mac.upper()
        self.ipset = ipset
        if self.ipset == "":
            self.ipset = None
        self.invert = invert
        if self.addr is None and self.mac is None and self.ipset is None:
            raise FirewallError(errors.INVALID_RULE,
                                "no address, mac and ipset")

    def __str__(self):
        ret = 'source%s ' % (" NOT" if self.invert else "")
        if self.addr is not None:
            return ret + 'address="%s"' % self.addr
        elif self.mac is not None:
            return ret + 'mac="%s"' % self.mac
        elif self.ipset is not None:
            return ret + 'ipset="%s"' % self.ipset
        else:
            raise FirewallError(errors.INVALID_RULE,
                                "no address, mac and ipset")

class Rich_Destination(object):
    def __init__(self, addr, ipset, invert=False):
        self.addr = addr
        if self.addr == "":
            self.addr = None
        self.ipset = ipset
        if self.ipset == "":
            self.ipset = None
        self.invert = invert
        if self.addr is None and self.ipset is None:
            raise FirewallError(errors.INVALID_RULE,
                                "no address and ipset")

    def __str__(self):
        ret = 'destination%s ' % (" NOT" if self.invert else "")
        if self.addr is not None:
            return ret + 'address="%s"' % self.addr
        elif self.ipset is not None:
            return ret + 'ipset="%s"' % self.ipset
        else:
            raise FirewallError(errors.INVALID_RULE,
                                "no address and ipset")

class Rich_Service(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return 'service name="%s"' % (self.name)

class Rich_Port(object):
    def __init__(self, port, protocol):
        self.port = port
        self.protocol = protocol

    def __str__(self):
        return 'port port="%s" protocol="%s"' % (self.port, self.protocol)

class Rich_SourcePort(Rich_Port):
    def __str__(self):
        return 'source-port port="%s" protocol="%s"' % (self.port,
                                                        self.protocol)

class Rich_Protocol(object):
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return 'protocol value="%s"' % (self.value)

class Rich_Masquerade(object):
    def __init__(self):
        pass

    def __str__(self):
        return 'masquerade'

class Rich_IcmpBlock(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return 'icmp-block name="%s"' % (self.name)

class Rich_IcmpType(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return 'icmp-type name="%s"' % (self.name)

class Rich_ForwardPort(object):
    def __init__(self, port, protocol, to_port, to_address):
        self.port = port
        self.protocol = protocol
        self.to_port = to_port
        self.to_address = to_address
        # replace None with "" in to_port and/or to_address
        if self.to_port is None:
            self.to_port = ""
        if self.to_address is None:
            self.to_address = ""

    def __str__(self):
        return 'forward-port port="%s" protocol="%s"%s%s' % \
            (self.port, self.protocol,
             ' to-port="%s"' % self.to_port if self.to_port != "" else '',
             ' to-addr="%s"' % self.to_address if self.to_address != "" else '')

class Rich_Log(object):
    def __init__(self, prefix=None, level=None, limit=None):
        #TODO check default level in iptables
        self.prefix = prefix
        self.level = level
        self.limit = limit

    def __str__(self):
        return 'log%s%s%s' % \
            (' prefix="%s"' % (self.prefix) if self.prefix else "",
             ' level="%s"' % (self.level) if self.level else "",
             " %s" % self.limit if self.limit else "")

class Rich_Audit(object):
    def __init__(self, limit=None):
        #TODO check default level in iptables
        self.limit = limit

    def __str__(self):
        return 'audit%s' % (" %s" % self.limit if self.limit else "")

class Rich_Accept(object):
    def __init__(self, limit=None):
        self.limit = limit

    def __str__(self):
        return "accept%s" % (" %s" % self.limit if self.limit else "")

class Rich_Reject(object):
    def __init__(self, _type=None, limit=None):
        self.type = _type
        self.limit = limit

    def __str__(self):
        return "reject%s%s" % (' type="%s"' % self.type if self.type else "",
                               " %s" % self.limit if self.limit else "")

    def check(self, family):
        if self.type:
            if not family:
                raise FirewallError(errors.INVALID_RULE, "When using reject type you must specify also rule family.")
            if family in ['ipv4', 'ipv6'] and \
               self.type not in REJECT_TYPES[family]:
                valid_types = ", ".join(REJECT_TYPES[family])
                raise FirewallError(errors.INVALID_RULE, "Wrong reject type %s.\nUse one of: %s." % (self.type, valid_types))

class Rich_Drop(Rich_Accept):
    def __str__(self):
        return "drop%s" % (" %s" % self.limit if self.limit else "")


class Rich_Mark(object):
    def __init__(self, _set, limit=None):
        self.set = _set
        self.limit = limit

    def __str__(self):
        return "mark set=%s%s" % (self.set,
                                  " %s" % self.limit if self.limit else "")

    def check(self):
        if self.set is not None:
            x = self.set
        else:
            raise FirewallError(errors.INVALID_MARK, "no value set")

        if "/" in x:
            splits = x.split("/")
            if len(splits) != 2:
                raise FirewallError(errors.INVALID_MARK, x)
            if not functions.checkUINT32(splits[0]) or \
               not functions.checkUINT32(splits[1]):
                # value and mask are uint32
                raise FirewallError(errors.INVALID_MARK, x)
        else:
            if not functions.checkUINT32(x):
                # value is uint32
                raise FirewallError(errors.INVALID_MARK, x)

DURATION_TO_MULT = {
    "s": 1,
    "m": 60,
    "h": 60 * 60,
    "d": 24 * 60 * 60,
}

class Rich_Limit(object):
    def __init__(self, value, burst=None):
        self.value = value
        self.burst = burst

    def check(self):
        self.value_parse()
        self.burst_parse()

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, value):
        if value is None:
            self._value = None
            return
        try:
            rate, duration = self._value_parse(value)
        except FirewallError:
            # The value is invalid. We cannot normalize it.
            v = value
        else:
            v = f"{rate}/{duration}"
        if getattr(self, "_value", None) != v:
            self._value = v

    @property
    def burst(self):
        return self._burst

    @burst.setter
    def burst(self, burst):
        if burst is None:
            self._burst = None
            return
        try:
            b = self._burst_parse(burst)
        except FirewallError:
            b = burst
        else:
            b = str(burst)
        if getattr(self, "_burst", None) != b:
            self._burst = b

    @staticmethod
    def _value_parse(value):
        splits = None
        if "/" in value:
            splits = value.split("/")
        if not splits or len(splits) != 2:
            raise FirewallError(errors.INVALID_LIMIT, value)
        (rate, duration) = splits
        try:
            rate = int(rate)
        except:
            raise FirewallError(errors.INVALID_LIMIT, value)

        if duration in ["second", "minute", "hour", "day"]:
            duration = duration[:1]

        if rate < 1 or duration not in ["s", "m", "h", "d"]:
            raise FirewallError(errors.INVALID_LIMIT, value)

        if 10000 * DURATION_TO_MULT[duration] // rate == 0:
            raise FirewallError(errors.INVALID_LIMIT, "%s too fast" % (value,))

        if rate == 1 and duration == "d":
            # iptables (v1.4.21) doesn't accept 1/d
            raise FirewallError(errors.INVALID_LIMIT, "%s too slow" % (value,))

        return rate, duration

    def value_parse(self):
        return self._value_parse(self._value)

    @staticmethod
    def _burst_parse(burst):
        if burst is None:
            return None
        try:
            b = int(burst)
        except:
            raise FirewallError(errors.INVALID_LIMIT, burst)

        if b < 1 or b > 10_000_000:
            raise FirewallError(errors.INVALID_LIMIT, burst)

        return b

    def burst_parse(self):
        return self._burst_parse(self._burst)

    def __str__(self):
        s = f'limit value="{self._value}"'
        if self._burst is not None:
            s += f" burst={self._burst}"
        return s

class Rich_Rule(object):
    priority_min = -32768
    priority_max =  32767

    def __init__(self, family=None, rule_str=None, priority=0):
        if family is not None:
            self.family = str(family)
        else:
            self.family = None

        self.priority = priority
        self.source = None
        self.destination = None
        self.element = None
        self.log = None
        self.audit = None
        self.action = None

        if rule_str:
            self._import_from_string(rule_str)

    def _lexer(self, rule_str):
        """ Lexical analysis """
        tokens = []

        for r in functions.splitArgs(rule_str):
            if "=" in r:
                attr = r.split('=')
                if len(attr) != 2 or not attr[0] or not attr[1]:
                    raise FirewallError(errors.INVALID_RULE,
                                        'internal error in _lexer(): %s' % r)
                tokens.append({'attr_name':attr[0], 'attr_value':attr[1]})
            else:
                tokens.append({'element':r})
        tokens.append({'element':'EOL'})

        return tokens

    def _import_from_string(self, rule_str):
        if not rule_str:
            raise FirewallError(errors.INVALID_RULE, 'empty rule')

        rule_str = functions.stripNonPrintableCharacters(rule_str)

        self.priority = 0
        self.family = None
        self.source = None
        self.destination = None
        self.element = None
        self.log = None
        self.audit = None
        self.action = None

        tokens = self._lexer(rule_str)
        if tokens and tokens[0].get('element')  == 'EOL':
            raise FirewallError(errors.INVALID_RULE, 'empty rule')

        attrs = {}       # attributes of elements
        in_elements = [] # stack with elements we are in
        index = 0        # index into tokens
        while not (tokens[index].get('element')  == 'EOL' and in_elements == ['rule']):
            element = tokens[index].get('element')
            attr_name = tokens[index].get('attr_name')
            attr_value = tokens[index].get('attr_value')
            #print ("in_elements: ", in_elements)
            #print ("index: %s, element: %s, attribute: %s=%s" % (index, element, attr_name, attr_value))
            if attr_name:     # attribute
                if attr_name not in ['priority', 'family', 'address', 'mac', 'ipset',
                                     'invert', 'value',
                                     'port', 'protocol', 'to-port', 'to-addr',
                                     'name', 'prefix', 'level', 'type',
                                     'set', 'burst']:
                    raise FirewallError(errors.INVALID_RULE, "bad attribute '%s'" % attr_name)
            else:             # element
                if element in ['rule', 'source', 'destination', 'protocol',
                               'service', 'port', 'icmp-block', 'icmp-type', 'masquerade',
                               'forward-port', 'source-port', 'log', 'audit',
                               'accept', 'drop', 'reject', 'mark', 'limit', 'not', 'NOT', 'EOL']:
                    if element == 'source' and self.source:
                        raise FirewallError(errors.INVALID_RULE, "more than one 'source' element")
                    elif element == 'destination' and self.destination:
                        raise FirewallError(errors.INVALID_RULE, "more than one 'destination' element")
                    elif element in ['protocol', 'service', 'port',
                                     'icmp-block', 'icmp-type',
                                     'masquerade', 'forward-port',
                                     'source-port'] and self.element:
                        raise FirewallError(errors.INVALID_RULE, "more than one element. There cannot be both '%s' and '%s' in one rule." % (element, self.element))
                    elif element == 'log' and self.log:
                        raise FirewallError(errors.INVALID_RULE, "more than one 'log' element")
                    elif element == 'audit' and self.audit:
                        raise FirewallError(errors.INVALID_RULE, "more than one 'audit' element")
                    elif element in ['accept', 'drop', 'reject', 'mark'] and self.action:
                        raise FirewallError(errors.INVALID_RULE, "more than one 'action' element. There cannot be both '%s' and '%s' in one rule." % (element, self.action))
                else:
                    raise FirewallError(errors.INVALID_RULE, "unknown element %s" % element)

            in_element = in_elements[len(in_elements)-1] if len(in_elements) > 0 else ''

            if in_element == '':
                if not element and attr_name:
                    if attr_name == 'family':
                        raise FirewallError(errors.INVALID_RULE, "'family' outside of rule. Use 'rule family=...'.")
                    elif attr_name == 'priority':
                        raise FirewallError(errors.INVALID_RULE, "'priority' outside of rule. Use 'rule priority=...'.")
                    else:
                        raise FirewallError(errors.INVALID_RULE, "'%s' outside of any element. Use 'rule <element> %s= ...'." % (attr_name, attr_name))
                elif 'rule' not in element:
                    raise FirewallError(errors.INVALID_RULE, "'%s' outside of rule. Use 'rule ... %s ...'." % (element, element))
                else:
                    in_elements.append('rule') # push into stack
            elif in_element == 'rule':
                if attr_name == 'family':
                    if attr_value not in ['ipv4', 'ipv6']:
                        raise FirewallError(errors.INVALID_RULE, "'family' attribute cannot have '%s' value. Use 'ipv4' or 'ipv6' instead." % attr_value)
                    self.family = attr_value
                elif attr_name == 'priority':
                    try:
                        self.priority = int(attr_value)
                    except ValueError:
                        raise FirewallError(errors.INVALID_PRIORITY, "invalid 'priority' attribute value '%s'." % attr_value)
                elif attr_name:
                    if attr_name == 'protocol':
                        err_msg = "wrong 'protocol' usage. Use either 'rule protocol value=...' or  'rule [forward-]port protocol=...'."
                    else:
                        err_msg = "attribute '%s' outside of any element. Use 'rule <element> %s= ...'." % (attr_name, attr_name)
                    raise FirewallError(errors.INVALID_RULE, err_msg)
                else:
                    in_elements.append(element) # push into stack
            elif in_element == 'source':
                if attr_name in ['address', 'mac', 'ipset', 'invert']:
                    attrs[attr_name] = attr_value
                elif element in ['not', 'NOT']:
                    attrs['invert'] = True
                else:
                    self.source = Rich_Source(attrs.get('address'), attrs.get('mac'), attrs.get('ipset'), attrs.get('invert', False))
                    in_elements.pop() # source
                    attrs.clear()
                    index = index -1 # return token to input
            elif in_element == 'destination':
                if attr_name in ['address', 'ipset', 'invert']:
                    attrs[attr_name] = attr_value
                elif element in ['not', 'NOT']:
                    attrs['invert'] = True
                else:
                    self.destination = Rich_Destination(attrs.get('address'), attrs.get('ipset'), attrs.get('invert', False))
                    in_elements.pop() # destination
                    attrs.clear()
                    index = index -1 # return token to input
            elif in_element == 'protocol':
                if attr_name == 'value':
                    self.element = Rich_Protocol(attr_value)
                    in_elements.pop() # protocol
                else:
                    raise FirewallError(errors.INVALID_RULE, "invalid 'protocol' element")
            elif in_element == 'service':
                if attr_name == 'name':
                    self.element = Rich_Service(attr_value)
                    in_elements.pop() # service
                else:
                    raise FirewallError(errors.INVALID_RULE, "invalid 'service' element")
            elif in_element == 'port':
                if attr_name in ['port', 'protocol']:
                    attrs[attr_name] = attr_value
                else:
                    self.element = Rich_Port(attrs.get('port'), attrs.get('protocol'))
                    in_elements.pop() # port
                    attrs.clear()
                    index = index -1 # return token to input
            elif in_element == 'icmp-block':
                if attr_name == 'name':
                    self.element = Rich_IcmpBlock(attr_value)
                    in_elements.pop() # icmp-block
                else:
                    raise FirewallError(errors.INVALID_RULE, "invalid 'icmp-block' element")
            elif in_element == 'icmp-type':
                if attr_name == 'name':
                    self.element = Rich_IcmpType(attr_value)
                    in_elements.pop() # icmp-type
                else:
                    raise FirewallError(errors.INVALID_RULE, "invalid 'icmp-type' element")
            elif in_element == 'masquerade':
                self.element = Rich_Masquerade()
                in_elements.pop()
                attrs.clear()
                index = index -1 # return token to input
            elif in_element == 'forward-port':
                if attr_name in ['port', 'protocol', 'to-port', 'to-addr']:
                    attrs[attr_name] = attr_value
                else:
                    self.element = Rich_ForwardPort(attrs.get('port'), attrs.get('protocol'), attrs.get('to-port'), attrs.get('to-addr'))
                    in_elements.pop() # forward-port
                    attrs.clear()
                    index = index -1 # return token to input
            elif in_element == 'source-port':
                if attr_name in ['port', 'protocol']:
                    attrs[attr_name] = attr_value
                else:
                    self.element = Rich_SourcePort(attrs.get('port'), attrs.get('protocol'))
                    in_elements.pop() # source-port
                    attrs.clear()
                    index = index -1 # return token to input
            elif in_element == 'log':
                if attr_name in ['prefix', 'level']:
                    attrs[attr_name] = attr_value
                elif element == 'limit':
                    in_elements.append('limit')
                else:
                    self.log = Rich_Log(attrs.get('prefix'), attrs.get('level'), attrs.get('limit'))
                    in_elements.pop() # log
                    attrs.clear()
                    index = index -1 # return token to input
            elif in_element == 'audit':
                if element == 'limit':
                    in_elements.append('limit')
                else:
                    self.audit = Rich_Audit(attrs.get('limit'))
                    in_elements.pop() # audit
                    attrs.clear()
                    index = index -1 # return token to input
            elif in_element == 'accept':
                if element == 'limit':
                    in_elements.append('limit')
                else:
                    self.action = Rich_Accept(attrs.get('limit'))
                    in_elements.pop() # accept
                    attrs.clear()
                    index = index -1 # return token to input
            elif in_element == 'drop':
                if element == 'limit':
                    in_elements.append('limit')
                else:
                    self.action = Rich_Drop(attrs.get('limit'))
                    in_elements.pop() # drop
                    attrs.clear()
                    index = index -1 # return token to input
            elif in_element == 'reject':
                if attr_name == 'type':
                    attrs[attr_name] = attr_value
                elif element == 'limit':
                    in_elements.append('limit')
                else:
                    self.action = Rich_Reject(attrs.get('type'), attrs.get('limit'))
                    in_elements.pop() # accept
                    attrs.clear()
                    index = index -1 # return token to input
            elif in_element == 'mark':
                if attr_name == 'set':
                    attrs[attr_name] = attr_value
                elif element == 'limit':
                    in_elements.append('limit')
                else:
                    self.action = Rich_Mark(attrs.get('set'),
                                            attrs.get('limit'))
                    in_elements.pop() # accept
                    attrs.clear()
                    index = index -1 # return token to input
            elif in_element == 'limit':
                if attr_name in ["value", "burst"]:
                    attrs[f"limit.{attr_name}"] = attr_value
                else:
                    if "limit.value" not in attrs:
                        raise FirewallError(
                            errors.INVALID_RULE, "invalid 'limit' element"
                        )
                    attrs["limit"] = Rich_Limit(
                        attrs["limit.value"], attrs.get("limit.burst")
                    )
                    attrs.pop("limit.value", None)
                    attrs.pop("limit.burst", None)
                    in_elements.pop()  # limit
                    index = index - 1  # return token to input

            index = index + 1

        self.check()

    def check(self):
        if self.family is not None and self.family not in [ "ipv4", "ipv6" ]:
            raise FirewallError(errors.INVALID_FAMILY, self.family)
        if self.family is None:
            if (self.source is not None and self.source.addr is not None) or \
               self.destination is not None:
                raise FirewallError(errors.MISSING_FAMILY)
            if type(self.element) == Rich_ForwardPort:
                raise FirewallError(errors.MISSING_FAMILY)

        if self.priority < self.priority_min or self.priority > self.priority_max:
            raise FirewallError(errors.INVALID_PRIORITY, "'priority' attribute must be between %d and %d." \
                                                         % (self.priority_min, self.priority_max))

        if self.element is None and \
           (self.log is None or (self.log is not None and self.priority == 0)):
            if self.action is None:
                raise FirewallError(errors.INVALID_RULE, "no element, no action")
            if self.source is None and self.destination is None and self.priority == 0:
                raise FirewallError(errors.INVALID_RULE, "no element, no source, no destination")

        if type(self.element) not in [ Rich_IcmpBlock,
                                       Rich_ForwardPort,
                                       Rich_Masquerade ]:
            if self.log is None and self.audit is None and \
                    self.action is None:
                raise FirewallError(errors.INVALID_RULE, "no action, no log, no audit")

        # source
        if self.source is not None:
            if self.source.addr is not None:
                if self.family is None:
                    raise FirewallError(errors.INVALID_FAMILY)
                if self.source.mac is not None:
                    raise FirewallError(errors.INVALID_RULE, "address and mac")
                if self.source.ipset is not None:
                    raise FirewallError(errors.INVALID_RULE, "address and ipset")
                if not functions.check_address(self.family, self.source.addr):
                    raise FirewallError(errors.INVALID_ADDR, str(self.source.addr))

            elif self.source.mac is not None:
                if self.source.ipset is not None:
                    raise FirewallError(errors.INVALID_RULE, "mac and ipset")
                if not functions.check_mac(self.source.mac):
                    raise FirewallError(errors.INVALID_MAC, str(self.source.mac))

            elif self.source.ipset is not None:
                if not check_ipset_name(self.source.ipset):
                    raise FirewallError(errors.INVALID_IPSET, str(self.source.ipset))

            else:
                raise FirewallError(errors.INVALID_RULE, "invalid source")

        # destination
        if self.destination is not None:
            if self.destination.addr is not None:
                if self.family is None:
                    raise FirewallError(errors.INVALID_FAMILY)
                if self.destination.ipset is not None:
                    raise FirewallError(errors.INVALID_DESTINATION, "address and ipset")
                if not functions.check_address(self.family, self.destination.addr):
                    raise FirewallError(errors.INVALID_ADDR, str(self.destination.addr))

            elif self.destination.ipset is not None:
                if not check_ipset_name(self.destination.ipset):
                    raise FirewallError(errors.INVALID_IPSET, str(self.destination.ipset))

            else:
                raise FirewallError(errors.INVALID_RULE, "invalid destination")

        # service
        if type(self.element) == Rich_Service:
            # service availability needs to be checked in Firewall, here is no
            # knowledge about this, therefore only simple check
            if self.element.name is None or len(self.element.name) < 1:
                raise FirewallError(errors.INVALID_SERVICE, str(self.element.name))

        # port
        elif type(self.element) == Rich_Port:
            if not functions.check_port(self.element.port):
                raise FirewallError(errors.INVALID_PORT, self.element.port)
            if self.element.protocol not in [ "tcp", "udp", "sctp", "dccp" ]:
                raise FirewallError(errors.INVALID_PROTOCOL, self.element.protocol)

        # protocol
        elif type(self.element) == Rich_Protocol:
            if not functions.checkProtocol(self.element.value):
                raise FirewallError(errors.INVALID_PROTOCOL, self.element.value)

        # masquerade
        elif type(self.element) == Rich_Masquerade:
            if self.action is not None:
                raise FirewallError(errors.INVALID_RULE, "masquerade and action")
            if self.source is not None and self.source.mac is not None:
                raise FirewallError(errors.INVALID_RULE, "masquerade and mac source")

        # icmp-block
        elif type(self.element) == Rich_IcmpBlock:
            # icmp type availability needs to be checked in Firewall, here is no
            # knowledge about this, therefore only simple check
            if self.element.name is None or len(self.element.name) < 1:
                raise FirewallError(errors.INVALID_ICMPTYPE, str(self.element.name))
            if self.action:
                raise FirewallError(errors.INVALID_RULE, "icmp-block and action")

        # icmp-type
        elif type(self.element) == Rich_IcmpType:
            # icmp type availability needs to be checked in Firewall, here is no
            # knowledge about this, therefore only simple check
            if self.element.name is None or len(self.element.name) < 1:
                raise FirewallError(errors.INVALID_ICMPTYPE, str(self.element.name))

        # forward-port
        elif type(self.element) == Rich_ForwardPort:
            if not functions.check_port(self.element.port):
                raise FirewallError(errors.INVALID_PORT, self.element.port)
            if self.element.protocol not in [ "tcp", "udp", "sctp", "dccp" ]:
                raise FirewallError(errors.INVALID_PROTOCOL, self.element.protocol)
            if self.element.to_port == "" and self.element.to_address == "":
                raise FirewallError(errors.INVALID_PORT, self.element.to_port)
            if self.element.to_port != "" and \
                    not functions.check_port(self.element.to_port):
                raise FirewallError(errors.INVALID_PORT, self.element.to_port)
            if self.element.to_address != "" and \
                    not functions.check_single_address(self.family,
                                                       self.element.to_address):
                raise FirewallError(errors.INVALID_ADDR, self.element.to_address)
            if self.family is None:
                raise FirewallError(errors.INVALID_FAMILY)
            if self.action is not None:
                raise FirewallError(errors.INVALID_RULE, "forward-port and action")

        # source-port
        elif type(self.element) == Rich_SourcePort:
            if not functions.check_port(self.element.port):
                raise FirewallError(errors.INVALID_PORT, self.element.port)
            if self.element.protocol not in [ "tcp", "udp", "sctp", "dccp" ]:
                raise FirewallError(errors.INVALID_PROTOCOL, self.element.protocol)

        # other element and not empty?
        elif self.element is not None:
            raise FirewallError(errors.INVALID_RULE, "Unknown element %s" % 
                                type(self.element))

        # log
        if self.log is not None:
            if self.log.level and \
               self.log.level not in [ "emerg", "alert", "crit", "error",
                                       "warning", "notice", "info", "debug" ]:
                raise FirewallError(errors.INVALID_LOG_LEVEL, self.log.level)

            if self.log.limit is not None:
                self.log.limit.check()

        # audit
        if self.audit is not None:
            if type(self.action) not in [ Rich_Accept, Rich_Reject, Rich_Drop ]:
                raise FirewallError(errors.INVALID_AUDIT_TYPE, type(self.action))

            if self.audit.limit is not None:
                self.audit.limit.check()

        # action
        if self.action is not None:
            if type(self.action) == Rich_Reject:
                self.action.check(self.family)
            elif type(self.action) == Rich_Mark:
                self.action.check()

            if self.action.limit is not None:
                self.action.limit.check()

    def __str__(self):
        ret = 'rule'
        if self.priority:
            ret += ' priority="%d"' % self.priority
        if self.family:
            ret += ' family="%s"' % self.family
        if self.source:
            ret += " %s" % self.source
        if self.destination:
            ret += " %s" % self.destination
        if self.element:
            ret += " %s" % self.element
        if self.log:
            ret += " %s" % self.log
        if self.audit:
            ret += " %s" % self.audit
        if self.action:
            ret += " %s" % self.action

        return (functions.u2b(ret)) if functions.PY2 else ret


#class Rich_RawRule(object):
#class Rich_RuleSet(object):
#class Rich_AddressList(object):
core/fw_config.py000064400000136430150351351730010021 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "FirewallConfig" ]

import copy
import os
import os.path
import shutil
from firewall import config
from firewall.core.logger import log
from firewall.core.io.icmptype import IcmpType, icmptype_reader, icmptype_writer
from firewall.core.io.service import Service, service_reader, service_writer
from firewall.core.io.zone import Zone, zone_reader, zone_writer
from firewall.core.io.ipset import IPSet, ipset_reader, ipset_writer
from firewall.core.io.helper import Helper, helper_reader, helper_writer
from firewall.core.io.policy import Policy, policy_reader, policy_writer
from firewall import errors
from firewall.errors import FirewallError

class FirewallConfig(object):
    def __init__(self, fw):
        self._fw = fw
        self.__init_vars()

    def __repr__(self):
        return '%s(%r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r)' % \
            (self.__class__,
             self._ipsets, self._icmptypes, self._services, self._zones,
             self._helpers, self.policy_objects,
             self._builtin_ipsets, self._builtin_icmptypes,
             self._builtin_services, self._builtin_zones, self._builtin_helpers,
             self._builtin_policy_objects,
             self._firewalld_conf, self._policies, self._direct)

    def __init_vars(self):
        self._ipsets = { }
        self._icmptypes = { }
        self._services = { }
        self._zones = { }
        self._helpers = { }
        self._policy_objects = { }
        self._builtin_ipsets = { }
        self._builtin_icmptypes = { }
        self._builtin_services = { }
        self._builtin_zones = { }
        self._builtin_helpers = { }
        self._builtin_policy_objects = { }
        self._firewalld_conf = None
        self._policies = None
        self._direct = None

    def cleanup(self):
        for x in list(self._builtin_ipsets.keys()):
            self._builtin_ipsets[x].cleanup()
            del self._builtin_ipsets[x]
        for x in list(self._ipsets.keys()):
            self._ipsets[x].cleanup()
            del self._ipsets[x]

        for x in list(self._builtin_icmptypes.keys()):
            self._builtin_icmptypes[x].cleanup()
            del self._builtin_icmptypes[x]
        for x in list(self._icmptypes.keys()):
            self._icmptypes[x].cleanup()
            del self._icmptypes[x]

        for x in list(self._builtin_services.keys()):
            self._builtin_services[x].cleanup()
            del self._builtin_services[x]
        for x in list(self._services.keys()):
            self._services[x].cleanup()
            del self._services[x]

        for x in list(self._builtin_zones.keys()):
            self._builtin_zones[x].cleanup()
            del self._builtin_zones[x]
        for x in list(self._zones.keys()):
            self._zones[x].cleanup()
            del self._zones[x]

        for x in list(self._builtin_helpers.keys()):
            self._builtin_helpers[x].cleanup()
            del self._builtin_helpers[x]
        for x in list(self._helpers.keys()):
            self._helpers[x].cleanup()
            del self._helpers[x]

        if self._firewalld_conf:
            self._firewalld_conf.cleanup()
            del self._firewalld_conf
            self._firewalld_conf = None

        if self._policies:
            self._policies.cleanup()
            del self._policies
            self._policies = None

        if self._direct:
            self._direct.cleanup()
            del self._direct
            self._direct = None

        self.__init_vars()

    # access check

    def lockdown_enabled(self):
        return self._fw.policies.query_lockdown()

    def access_check(self, key, value):
        return self._fw.policies.access_check(key, value)

    # firewalld_conf

    def set_firewalld_conf(self, conf):
        self._firewalld_conf = conf

    def get_firewalld_conf(self):
        return self._firewalld_conf

    def update_firewalld_conf(self):
        if not os.path.exists(config.FIREWALLD_CONF):
            self._firewalld_conf.clear()
        else:
            self._firewalld_conf.read()

    # policies

    def set_policies(self, policies):
        self._policies = policies

    def get_policies(self):
        return self._policies

    def update_lockdown_whitelist(self):
        if not os.path.exists(config.LOCKDOWN_WHITELIST):
            self._policies.lockdown_whitelist.cleanup()
        else:
            self._policies.lockdown_whitelist.read()

    # direct

    def set_direct(self, direct):
        self._direct = direct

    def get_direct(self):
        return self._direct

    def update_direct(self):
        if not os.path.exists(config.FIREWALLD_DIRECT):
            self._direct.cleanup()
        else:
            self._direct.read()

    # ipset

    def get_ipsets(self):
        return sorted(set(list(self._ipsets.keys()) + \
                          list(self._builtin_ipsets.keys())))

    def add_ipset(self, obj):
        if obj.builtin:
            self._builtin_ipsets[obj.name] = obj
        else:
            self._ipsets[obj.name] = obj

    def get_ipset(self, name):
        if name in self._ipsets:
            return self._ipsets[name]
        elif name in self._builtin_ipsets:
            return self._builtin_ipsets[name]
        raise FirewallError(errors.INVALID_IPSET, name)

    def load_ipset_defaults(self, obj):
        if obj.name not in self._ipsets:
            raise FirewallError(errors.NO_DEFAULTS, obj.name)
        elif self._ipsets[obj.name] != obj:
            raise FirewallError(errors.NO_DEFAULTS,
                                "self._ipsets[%s] != obj" % obj.name)
        elif obj.name not in self._builtin_ipsets:
            raise FirewallError(errors.NO_DEFAULTS,
                            "'%s' not a built-in ipset" % obj.name)
        self._remove_ipset(obj)
        return self._builtin_ipsets[obj.name]

    def get_ipset_config(self, obj):
        return obj.export_config()

    def set_ipset_config(self, obj, conf):
        if obj.builtin:
            x = copy.copy(obj)
            x.import_config(conf)
            x.path = config.ETC_FIREWALLD_IPSETS
            x.builtin = False
            if obj.path != x.path:
                x.default = False
            self.add_ipset(x)
            ipset_writer(x)
            return x
        else:
            obj.import_config(conf)
            ipset_writer(obj)
            return obj

    def new_ipset(self, name, conf):
        if name in self._ipsets or name in self._builtin_ipsets:
            raise FirewallError(errors.NAME_CONFLICT,
                                "new_ipset(): '%s'" % name)

        x = IPSet()
        x.check_name(name)
        x.import_config(conf)
        x.name = name
        x.filename = "%s.xml" % name
        x.path = config.ETC_FIREWALLD_IPSETS
        # It is not possible to add a new one with a name of a buitin
        x.builtin = False
        x.default = True

        ipset_writer(x)
        self.add_ipset(x)
        return x

    def update_ipset_from_path(self, name):
        filename = os.path.basename(name)
        path = os.path.dirname(name)

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

            if path == config.ETC_FIREWALLD_IPSETS:
                # removed custom ipset
                for x in self._ipsets.keys():
                    obj = self._ipsets[x]
                    if obj.filename == filename:
                        del self._ipsets[x]
                        if obj.name in self._builtin_ipsets:
                            return ("update", self._builtin_ipsets[obj.name])
                        return ("remove", obj)
            else:
                # removed builtin ipset
                for x in self._builtin_ipsets.keys():
                    obj = self._builtin_ipsets[x]
                    if obj.filename == filename:
                        del self._builtin_ipsets[x]
                        if obj.name not in self._ipsets:
                            # update dbus ipset
                            return ("remove", obj)
                        else:
                            # builtin hidden, no update needed
                            return (None, None)

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

        # new or updated file

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

        # new ipset
        if obj.name not in self._builtin_ipsets and obj.name not in self._ipsets:
            self.add_ipset(obj)
            return ("new", obj)

        # updated ipset
        if path == config.ETC_FIREWALLD_IPSETS:
            # custom ipset update
            if obj.name in self._ipsets:
                obj.default = self._ipsets[obj.name].default
                self._ipsets[obj.name] = obj
            return ("update", obj)
        else:
            if obj.name in self._builtin_ipsets:
                # builtin ipset update
                del self._builtin_ipsets[obj.name]
                self._builtin_ipsets[obj.name] = obj

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

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

    def _remove_ipset(self, obj):
        if obj.name not in self._ipsets:
            raise FirewallError(errors.INVALID_IPSET, obj.name)
        if obj.path != config.ETC_FIREWALLD_IPSETS:
            raise FirewallError(errors.INVALID_DIRECTORY,
                                "'%s' != '%s'" % (obj.path,
                                                  config.ETC_FIREWALLD_IPSETS))

        name = "%s/%s.xml" % (obj.path, obj.name)
        try:
            shutil.move(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)
            os.remove(name)

        del self._ipsets[obj.name]

    def check_builtin_ipset(self, obj):
        if obj.builtin or not obj.default:
            raise FirewallError(errors.BUILTIN_IPSET,
                                "'%s' is built-in ipset" % obj.name)

    def remove_ipset(self, obj):
        self.check_builtin_ipset(obj)
        self._remove_ipset(obj)

    def rename_ipset(self, obj, name):
        self.check_builtin_ipset(obj)
        new_ipset = self._copy_ipset(obj, name)
        self._remove_ipset(obj)
        return new_ipset

    def _copy_ipset(self, obj, name):
        return self.new_ipset(name, obj.export_config())

    # icmptypes

    def get_icmptypes(self):
        return sorted(set(list(self._icmptypes.keys()) + \
                          list(self._builtin_icmptypes.keys())))

    def add_icmptype(self, obj):
        if obj.builtin:
            self._builtin_icmptypes[obj.name] = obj
        else:
            self._icmptypes[obj.name] = obj

    def get_icmptype(self, name):
        if name in self._icmptypes:
            return self._icmptypes[name]
        elif name in self._builtin_icmptypes:
            return self._builtin_icmptypes[name]
        raise FirewallError(errors.INVALID_ICMPTYPE, name)

    def load_icmptype_defaults(self, obj):
        if obj.name not in self._icmptypes:
            raise FirewallError(errors.NO_DEFAULTS, obj.name)
        elif self._icmptypes[obj.name] != obj:
            raise FirewallError(errors.NO_DEFAULTS,
                                "self._icmptypes[%s] != obj" % obj.name)
        elif obj.name not in self._builtin_icmptypes:
            raise FirewallError(errors.NO_DEFAULTS,
                                "'%s' not a built-in icmptype" % obj.name)
        self._remove_icmptype(obj)
        return self._builtin_icmptypes[obj.name]

    def get_icmptype_config(self, obj):
        return obj.export_config()

    def set_icmptype_config(self, obj, conf):
        if obj.builtin:
            x = copy.copy(obj)
            x.import_config(conf)
            x.path = config.ETC_FIREWALLD_ICMPTYPES
            x.builtin = False
            if obj.path != x.path:
                x.default = False
            self.add_icmptype(x)
            icmptype_writer(x)
            return x
        else:
            obj.import_config(conf)
            icmptype_writer(obj)
            return obj

    def new_icmptype(self, name, conf):
        if name in self._icmptypes or name in self._builtin_icmptypes:
            raise FirewallError(errors.NAME_CONFLICT,
                                "new_icmptype(): '%s'" % name)

        x = IcmpType()
        x.check_name(name)
        x.import_config(conf)
        x.name = name
        x.filename = "%s.xml" % name
        x.path = config.ETC_FIREWALLD_ICMPTYPES
        # It is not possible to add a new one with a name of a buitin
        x.builtin = False
        x.default = True

        icmptype_writer(x)
        self.add_icmptype(x)
        return x

    def update_icmptype_from_path(self, name):
        filename = os.path.basename(name)
        path = os.path.dirname(name)

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

            if path == config.ETC_FIREWALLD_ICMPTYPES:
                # removed custom icmptype
                for x in self._icmptypes.keys():
                    obj = self._icmptypes[x]
                    if obj.filename == filename:
                        del self._icmptypes[x]
                        if obj.name in self._builtin_icmptypes:
                            return ("update", self._builtin_icmptypes[obj.name])
                        return ("remove", obj)
            else:
                # removed builtin icmptype
                for x in self._builtin_icmptypes.keys():
                    obj = self._builtin_icmptypes[x]
                    if obj.filename == filename:
                        del self._builtin_icmptypes[x]
                        if obj.name not in self._icmptypes:
                            # update dbus icmptype
                            return ("remove", obj)
                        else:
                            # builtin hidden, no update needed
                            return (None, None)

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

        # new or updated file

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

        # new icmptype
        if obj.name not in self._builtin_icmptypes and obj.name not in self._icmptypes:
            self.add_icmptype(obj)
            return ("new", obj)

        # updated icmptype
        if path == config.ETC_FIREWALLD_ICMPTYPES:
            # custom icmptype update
            if obj.name in self._icmptypes:
                obj.default = self._icmptypes[obj.name].default
                self._icmptypes[obj.name] = obj
            return ("update", obj)
        else:
            if obj.name in self._builtin_icmptypes:
                # builtin icmptype update
                del self._builtin_icmptypes[obj.name]
                self._builtin_icmptypes[obj.name] = obj

                if obj.name not in self._icmptypes:
                    # update dbus icmptype
                    return ("update", obj)
                else:
                    # builtin hidden, no update needed
                    return (None, None)
            
        # icmptype not known to firewalld, yet (timeout, ..)
        return (None, None)

    def _remove_icmptype(self, obj):
        if obj.name not in self._icmptypes:
            raise FirewallError(errors.INVALID_ICMPTYPE, obj.name)
        if obj.path != config.ETC_FIREWALLD_ICMPTYPES:
            raise FirewallError(errors.INVALID_DIRECTORY,
                                "'%s' != '%s'" % \
                                (obj.path, config.ETC_FIREWALLD_ICMPTYPES))

        name = "%s/%s.xml" % (obj.path, obj.name)
        try:
            shutil.move(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)
            os.remove(name)

        del self._icmptypes[obj.name]

    def check_builtin_icmptype(self, obj):
        if obj.builtin or not obj.default:
            raise FirewallError(errors.BUILTIN_ICMPTYPE,
                                "'%s' is built-in icmp type" % obj.name)

    def remove_icmptype(self, obj):
        self.check_builtin_icmptype(obj)
        self._remove_icmptype(obj)

    def rename_icmptype(self, obj, name):
        self.check_builtin_icmptype(obj)
        new_icmptype = self._copy_icmptype(obj, name)
        self._remove_icmptype(obj)
        return new_icmptype

    def _copy_icmptype(self, obj, name):
        return self.new_icmptype(name, obj.export_config())

    # services

    def get_services(self):
        return sorted(set(list(self._services.keys()) + \
                          list(self._builtin_services.keys())))

    def add_service(self, obj):
        if obj.builtin:
            self._builtin_services[obj.name] = obj
        else:
            self._services[obj.name] = obj

    def get_service(self, name):
        if name in self._services:
            return self._services[name]
        elif name in self._builtin_services:
            return self._builtin_services[name]
        raise FirewallError(errors.INVALID_SERVICE, "get_service(): '%s'" % name)

    def load_service_defaults(self, obj):
        if obj.name not in self._services:
            raise FirewallError(errors.NO_DEFAULTS, obj.name)
        elif self._services[obj.name] != obj:
            raise FirewallError(errors.NO_DEFAULTS,
                                "self._services[%s] != obj" % obj.name)
        elif obj.name not in self._builtin_services:
            raise FirewallError(errors.NO_DEFAULTS,
                                "'%s' not a built-in service" % obj.name)
        self._remove_service(obj)
        return self._builtin_services[obj.name]

    def get_service_config(self, obj):
        conf_dict = obj.export_config_dict()
        conf_list = []
        for i in range(8): # tuple based dbus API has 8 elements
            if obj.IMPORT_EXPORT_STRUCTURE[i][0] not in conf_dict:
                # old API needs the empty elements as well. Grab it from the
                # object otherwise we don't know the type.
                conf_list.append(copy.deepcopy(getattr(obj, obj.IMPORT_EXPORT_STRUCTURE[i][0])))
            else:
                conf_list.append(conf_dict[obj.IMPORT_EXPORT_STRUCTURE[i][0]])
        return tuple(conf_list)

    def get_service_config_dict(self, obj):
        return obj.export_config_dict()

    def set_service_config(self, obj, conf):
        conf_dict = {}
        for i,value in enumerate(conf):
            conf_dict[obj.IMPORT_EXPORT_STRUCTURE[i][0]] = value

        if obj.builtin:
            x = copy.copy(obj)
            x.import_config_dict(conf_dict)
            x.path = config.ETC_FIREWALLD_SERVICES
            x.builtin = False
            if obj.path != x.path:
                x.default = False
            self.add_service(x)
            service_writer(x)
            return x
        else:
            obj.import_config_dict(conf_dict)
            service_writer(obj)
            return obj

    def set_service_config_dict(self, obj, conf):
        if obj.builtin:
            x = copy.copy(obj)
            x.import_config_dict(conf)
            x.path = config.ETC_FIREWALLD_SERVICES
            x.builtin = False
            if obj.path != x.path:
                x.default = False
            self.add_service(x)
            service_writer(x)
            return x
        else:
            obj.import_config_dict(conf)
            service_writer(obj)
            return obj

    def new_service(self, name, conf):
        if name in self._services or name in self._builtin_services:
            raise FirewallError(errors.NAME_CONFLICT,
                                "new_service(): '%s'" % name)

        conf_dict = {}
        for i,value in enumerate(conf):
            conf_dict[Service.IMPORT_EXPORT_STRUCTURE[i][0]] = value

        x = Service()
        x.check_name(name)
        x.import_config_dict(conf_dict)
        x.name = name
        x.filename = "%s.xml" % name
        x.path = config.ETC_FIREWALLD_SERVICES
        # It is not possible to add a new one with a name of a buitin
        x.builtin = False
        x.default = True

        service_writer(x)
        self.add_service(x)
        return x

    def new_service_dict(self, name, conf):
        if name in self._services or name in self._builtin_services:
            raise FirewallError(errors.NAME_CONFLICT,
                                "new_service(): '%s'" % name)

        x = Service()
        x.check_name(name)
        x.import_config_dict(conf)
        x.name = name
        x.filename = "%s.xml" % name
        x.path = config.ETC_FIREWALLD_SERVICES
        # It is not possible to add a new one with a name of a buitin
        x.builtin = False
        x.default = True

        service_writer(x)
        self.add_service(x)
        return x

    def update_service_from_path(self, name):
        filename = os.path.basename(name)
        path = os.path.dirname(name)

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

            if path == config.ETC_FIREWALLD_SERVICES:
                # removed custom service
                for x in self._services.keys():
                    obj = self._services[x]
                    if obj.filename == filename:
                        del self._services[x]
                        if obj.name in self._builtin_services:
                            return ("update", self._builtin_services[obj.name])
                        return ("remove", obj)
            else:
                # removed builtin service
                for x in self._builtin_services.keys():
                    obj = self._builtin_services[x]
                    if obj.filename == filename:
                        del self._builtin_services[x]
                        if obj.name not in self._services:
                            # update dbus service
                            return ("remove", obj)
                        else:
                            # builtin hidden, no update needed
                            return (None, None)

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

        # new or updated file

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

        # new service
        if obj.name not in self._builtin_services and obj.name not in self._services:
            self.add_service(obj)
            return ("new", obj)

        # updated service
        if path == config.ETC_FIREWALLD_SERVICES:
            # custom service update
            if obj.name in self._services:
                obj.default = self._services[obj.name].default
                self._services[obj.name] = obj
            return ("update", obj)
        else:
            if obj.name in self._builtin_services:
                # builtin service update
                del self._builtin_services[obj.name]
                self._builtin_services[obj.name] = obj

                if obj.name not in self._services:
                    # update dbus service
                    return ("update", obj)
                else:
                    # builtin hidden, no update needed
                    return (None, None)
            
        # service not known to firewalld, yet (timeout, ..)
        return (None, None)

    def _remove_service(self, obj):
        if obj.name not in self._services:
            raise FirewallError(errors.INVALID_SERVICE, obj.name)
        if obj.path != config.ETC_FIREWALLD_SERVICES:
            raise FirewallError(errors.INVALID_DIRECTORY,
                                "'%s' != '%s'" % \
                                (obj.path, config.ETC_FIREWALLD_SERVICES))

        name = "%s/%s.xml" % (obj.path, obj.name)
        try:
            shutil.move(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)
            os.remove(name)

        del self._services[obj.name]

    def check_builtin_service(self, obj):
        if obj.builtin or not obj.default:
            raise FirewallError(errors.BUILTIN_SERVICE,
                                "'%s' is built-in service" % obj.name)

    def remove_service(self, obj):
        self.check_builtin_service(obj)
        self._remove_service(obj)

    def rename_service(self, obj, name):
        self.check_builtin_service(obj)
        new_service = self._copy_service(obj, name)
        self._remove_service(obj)
        return new_service

    def _copy_service(self, obj, name):
        return self.new_service_dict(name, obj.export_config_dict())

    # zones

    def get_zones(self):
        return sorted(set(list(self._zones.keys()) + \
                          list(self._builtin_zones.keys())))

    def add_zone(self, obj):
        if obj.builtin:
            self._builtin_zones[obj.name] = obj
        else:
            self._zones[obj.name] = obj

    def forget_zone(self, name):
        if name in self._builtin_zones:
            del self._builtin_zones[name]
        if name in self._zones:
            del self._zones[name]

    def get_zone(self, name):
        if name in self._zones:
            return self._zones[name]
        elif name in self._builtin_zones:
            return self._builtin_zones[name]
        raise FirewallError(errors.INVALID_ZONE, "get_zone(): %s" % name)

    def load_zone_defaults(self, obj):
        if obj.name not in self._zones:
            raise FirewallError(errors.NO_DEFAULTS, obj.name)
        elif self._zones[obj.name] != obj:
            raise FirewallError(errors.NO_DEFAULTS,
                                "self._zones[%s] != obj" % obj.name)
        elif obj.name not in self._builtin_zones:
            raise FirewallError(errors.NO_DEFAULTS,
                                "'%s' not a built-in zone" % obj.name)
        self._remove_zone(obj)
        return self._builtin_zones[obj.name]

    def get_zone_config(self, obj):
        conf_dict = obj.export_config_dict()
        conf_list = []
        for i in range(16): # tuple based dbus API has 16 elements
            if obj.IMPORT_EXPORT_STRUCTURE[i][0] not in conf_dict:
                # old API needs the empty elements as well. Grab it from the
                # object otherwise we don't know the type.
                conf_list.append(copy.deepcopy(getattr(obj, obj.IMPORT_EXPORT_STRUCTURE[i][0])))
            else:
                conf_list.append(conf_dict[obj.IMPORT_EXPORT_STRUCTURE[i][0]])
        return tuple(conf_list)

    def get_zone_config_dict(self, obj):
        return obj.export_config_dict()

    def set_zone_config(self, obj, conf):
        conf_dict = {}
        for i,value in enumerate(conf):
            conf_dict[obj.IMPORT_EXPORT_STRUCTURE[i][0]] = value

        if obj.builtin:
            x = copy.copy(obj)
            x.fw_config = self
            x.import_config_dict(conf_dict)
            x.path = config.ETC_FIREWALLD_ZONES
            x.builtin = False
            if obj.path != x.path:
                x.default = False
            self.add_zone(x)
            zone_writer(x)
            return x
        else:
            obj.fw_config = self
            obj.import_config_dict(conf_dict)
            zone_writer(obj)
            return obj

    def set_zone_config_dict(self, obj, conf):
        if obj.builtin:
            x = copy.copy(obj)
            x.fw_config = self
            x.import_config_dict(conf)
            x.path = config.ETC_FIREWALLD_ZONES
            x.builtin = False
            if obj.path != x.path:
                x.default = False
            self.add_zone(x)
            zone_writer(x)
            return x
        else:
            obj.fw_config = self
            obj.import_config_dict(conf)
            zone_writer(obj)
            return obj

    def new_zone(self, name, conf):
        if name in self._zones or name in self._builtin_zones:
            raise FirewallError(errors.NAME_CONFLICT, "new_zone(): '%s'" % name)

        conf_dict = {}
        for i,value in enumerate(conf):
            conf_dict[Zone.IMPORT_EXPORT_STRUCTURE[i][0]] = value

        x = Zone()
        x.fw_config = self
        x.check_name(name)
        x.import_config_dict(conf_dict)
        x.name = name
        x.filename = "%s.xml" % name
        x.path = config.ETC_FIREWALLD_ZONES
        # It is not possible to add a new one with a name of a buitin
        x.builtin = False
        x.default = True

        zone_writer(x)
        self.add_zone(x)
        return x

    def new_zone_dict(self, name, conf):
        if name in self._zones or name in self._builtin_zones:
            raise FirewallError(errors.NAME_CONFLICT, "new_zone(): '%s'" % name)

        x = Zone()
        x.fw_config = self
        x.check_name(name)
        x.import_config_dict(conf)
        x.name = name
        x.filename = "%s.xml" % name
        x.path = config.ETC_FIREWALLD_ZONES
        # It is not possible to add a new one with a name of a buitin
        x.builtin = False
        x.default = True

        zone_writer(x)
        self.add_zone(x)
        return x

    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)

    def _remove_zone(self, obj):
        if obj.name not in self._zones:
            raise FirewallError(errors.INVALID_ZONE, obj.name)
        if not obj.path.startswith(config.ETC_FIREWALLD_ZONES):
            raise FirewallError(errors.INVALID_DIRECTORY,
                                "'%s' doesn't start with '%s'" % \
                                (obj.path, config.ETC_FIREWALLD_ZONES))

        name = "%s/%s.xml" % (obj.path, obj.name)
        try:
            shutil.move(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)
            os.remove(name)

        del self._zones[obj.name]

    def check_builtin_zone(self, obj):
        if obj.builtin or not obj.default:
            raise FirewallError(errors.BUILTIN_ZONE,
                                "'%s' is built-in zone" % obj.name)

    def remove_zone(self, obj):
        self.check_builtin_zone(obj)
        self._remove_zone(obj)

    def rename_zone(self, obj, name):
        self.check_builtin_zone(obj)
        obj_conf = obj.export_config_dict()
        self._remove_zone(obj)
        try:
            new_zone = self.new_zone_dict(name, obj_conf)
        except:
            # re-add original if rename failed
            self.new_zone_dict(obj.name, obj_conf)
            raise
        return new_zone

    # policy objects

    def get_policy_objects(self):
        return sorted(set(list(self._policy_objects.keys()) + \
                          list(self._builtin_policy_objects.keys())))

    def add_policy_object(self, obj):
        if obj.builtin:
            self._builtin_policy_objects[obj.name] = obj
        else:
            self._policy_objects[obj.name] = obj

    def get_policy_object(self, name):
        if name in self._policy_objects:
            return self._policy_objects[name]
        elif name in self._builtin_policy_objects:
            return self._builtin_policy_objects[name]
        raise FirewallError(errors.INVALID_POLICY, "get_policy_object(): %s" % name)

    def load_policy_object_defaults(self, obj):
        if obj.name not in self._policy_objects:
            raise FirewallError(errors.NO_DEFAULTS, obj.name)
        elif self._policy_objects[obj.name] != obj:
            raise FirewallError(errors.NO_DEFAULTS,
                                "self._policy_objects[%s] != obj" % obj.name)
        elif obj.name not in self._builtin_policy_objects:
            raise FirewallError(errors.NO_DEFAULTS,
                                "'%s' not a built-in policy" % obj.name)
        self._remove_policy_object(obj)
        return self._builtin_policy_objects[obj.name]

    def get_policy_object_config_dict(self, obj):
        return obj.export_config_dict()

    def set_policy_object_config_dict(self, obj, conf):
        if obj.builtin:
            x = copy.copy(obj)
            x.fw_config = self
            x.import_config_dict(conf)
            x.path = config.ETC_FIREWALLD_POLICIES
            x.builtin = False
            if obj.path != x.path:
                x.default = False
            self.add_policy_object(x)
            policy_writer(x)
            return x
        else:
            obj.fw_config = self
            obj.import_config_dict(conf)
            policy_writer(obj)
            return obj

    def new_policy_object_dict(self, name, conf):
        if name in self._policy_objects or name in self._builtin_policy_objects:
            raise FirewallError(errors.NAME_CONFLICT, "new_policy_object(): '%s'" % name)

        x = Policy()
        x.fw_config = self
        x.check_name(name)
        x.import_config_dict(conf)
        x.name = name
        x.filename = "%s.xml" % name
        x.path = config.ETC_FIREWALLD_POLICIES
        # It is not possible to add a new one with a name of a buitin
        x.builtin = False
        x.default = True

        policy_writer(x)
        self.add_policy_object(x)
        return x

    def update_policy_object_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_POLICIES):
                # removed custom policy_object
                for x in self._policy_objects.keys():
                    obj = self._policy_objects[x]
                    if obj.filename == filename:
                        del self._policy_objects[x]
                        if obj.name in self._builtin_policy_objects:
                            return ("update", self._builtin_policy_objects[obj.name])
                        return ("remove", obj)
            else:
                # removed builtin policy_object
                for x in self._builtin_policy_objects.keys():
                    obj = self._builtin_policy_objects[x]
                    if obj.filename == filename:
                        del self._builtin_policy_objects[x]
                        if obj.name not in self._policy_objects:
                            # update dbus policy_object
                            return ("remove", obj)
                        else:
                            # builtin hidden, no update needed
                            return (None, None)

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

        # new or updated file

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

        obj.fw_config = self

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

        # new policy_object
        if obj.name not in self._builtin_policy_objects and obj.name not in self._policy_objects:
            self.add_policy_object(obj)
            return ("new", obj)

        # updated policy_object
        if path.startswith(config.ETC_FIREWALLD_POLICIES):
            # custom policy_object update
            if obj.name in self._policy_objects:
                obj.default = self._policy_objects[obj.name].default
                self._policy_objects[obj.name] = obj
            return ("update", obj)
        else:
            if obj.name in self._builtin_policy_objects:
                # builtin policy_object update
                del self._builtin_policy_objects[obj.name]
                self._builtin_policy_objects[obj.name] = obj

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

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

    def _remove_policy_object(self, obj):
        if obj.name not in self._policy_objects:
            raise FirewallError(errors.INVALID_POLICY, obj.name)
        if not obj.path.startswith(config.ETC_FIREWALLD_POLICIES):
            raise FirewallError(errors.INVALID_DIRECTORY,
                                "'%s' doesn't start with '%s'" % \
                                (obj.path, config.ETC_FIREWALLD_POLICIES))

        name = "%s/%s.xml" % (obj.path, obj.name)
        try:
            shutil.move(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)
            os.remove(name)

        del self._policy_objects[obj.name]

    def check_builtin_policy_object(self, obj):
        if obj.builtin or not obj.default:
            raise FirewallError(errors.BUILTIN_POLICY,
                                "'%s' is built-in policy" % obj.name)

    def remove_policy_object(self, obj):
        self.check_builtin_policy_object(obj)
        self._remove_policy_object(obj)

    def rename_policy_object(self, obj, name):
        self.check_builtin_policy_object(obj)
        new_policy_object = self._copy_policy_object(obj, name)
        self._remove_policy_object(obj)
        return new_policy_object

    def _copy_policy_object(self, obj, name):
        return self.new_policy_object_dict(name, obj.export_config_dict())

    # helper

    def get_helpers(self):
        return sorted(set(list(self._helpers.keys()) + \
                          list(self._builtin_helpers.keys())))

    def add_helper(self, obj):
        if obj.builtin:
            self._builtin_helpers[obj.name] = obj
        else:
            self._helpers[obj.name] = obj

    def get_helper(self, name):
        if name in self._helpers:
            return self._helpers[name]
        elif name in self._builtin_helpers:
            return self._builtin_helpers[name]
        raise FirewallError(errors.INVALID_HELPER, name)

    def load_helper_defaults(self, obj):
        if obj.name not in self._helpers:
            raise FirewallError(errors.NO_DEFAULTS, obj.name)
        elif self._helpers[obj.name] != obj:
            raise FirewallError(errors.NO_DEFAULTS,
                                "self._helpers[%s] != obj" % obj.name)
        elif obj.name not in self._builtin_helpers:
            raise FirewallError(errors.NO_DEFAULTS,
                            "'%s' not a built-in helper" % obj.name)
        self._remove_helper(obj)
        return self._builtin_helpers[obj.name]

    def get_helper_config(self, obj):
        return obj.export_config()

    def set_helper_config(self, obj, conf):
        if obj.builtin:
            x = copy.copy(obj)
            x.import_config(conf)
            x.path = config.ETC_FIREWALLD_HELPERS
            x.builtin = False
            if obj.path != x.path:
                x.default = False
            self.add_helper(x)
            helper_writer(x)
            return x
        else:
            obj.import_config(conf)
            helper_writer(obj)
            return obj

    def new_helper(self, name, conf):
        if name in self._helpers or name in self._builtin_helpers:
            raise FirewallError(errors.NAME_CONFLICT,
                                "new_helper(): '%s'" % name)

        x = Helper()
        x.check_name(name)
        x.import_config(conf)
        x.name = name
        x.filename = "%s.xml" % name
        x.path = config.ETC_FIREWALLD_HELPERS
        # It is not possible to add a new one with a name of a buitin
        x.builtin = False
        x.default = True

        helper_writer(x)
        self.add_helper(x)
        return x

    def update_helper_from_path(self, name):
        filename = os.path.basename(name)
        path = os.path.dirname(name)

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

            if path == config.ETC_FIREWALLD_HELPERS:
                # removed custom helper
                for x in self._helpers.keys():
                    obj = self._helpers[x]
                    if obj.filename == filename:
                        del self._helpers[x]
                        if obj.name in self._builtin_helpers:
                            return ("update", self._builtin_helpers[obj.name])
                        return ("remove", obj)
            else:
                # removed builtin helper
                for x in self._builtin_helpers.keys():
                    obj = self._builtin_helpers[x]
                    if obj.filename == filename:
                        del self._builtin_helpers[x]
                        if obj.name not in self._helpers:
                            # update dbus helper
                            return ("remove", obj)
                        else:
                            # builtin hidden, no update needed
                            return (None, None)

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

        # new or updated file

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

        # new helper
        if obj.name not in self._builtin_helpers and obj.name not in self._helpers:
            self.add_helper(obj)
            return ("new", obj)

        # updated helper
        if path == config.ETC_FIREWALLD_HELPERS:
            # custom helper update
            if obj.name in self._helpers:
                obj.default = self._helpers[obj.name].default
                self._helpers[obj.name] = obj
            return ("update", obj)
        else:
            if obj.name in self._builtin_helpers:
                # builtin helper update
                del self._builtin_helpers[obj.name]
                self._builtin_helpers[obj.name] = obj

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

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

    def _remove_helper(self, obj):
        if obj.name not in self._helpers:
            raise FirewallError(errors.INVALID_HELPER, obj.name)
        if obj.path != config.ETC_FIREWALLD_HELPERS:
            raise FirewallError(errors.INVALID_DIRECTORY,
                                "'%s' != '%s'" % (obj.path,
                                                  config.ETC_FIREWALLD_HELPERS))

        name = "%s/%s.xml" % (obj.path, obj.name)
        try:
            shutil.move(name, "%s.old" % name)
        except Exception as msg:
            log.error("Backup of file '%s' failed: %s", name, msg)
            os.remove(name)

        del self._helpers[obj.name]

    def check_builtin_helper(self, obj):
        if obj.builtin or not obj.default:
            raise FirewallError(errors.BUILTIN_HELPER,
                                "'%s' is built-in helper" % obj.name)

    def remove_helper(self, obj):
        self.check_builtin_helper(obj)
        self._remove_helper(obj)

    def rename_helper(self, obj, name):
        self.check_builtin_helper(obj)
        new_helper = self._copy_helper(obj, name)
        self._remove_helper(obj)
        return new_helper

    def _copy_helper(self, obj, name):
        return self.new_helper(name, obj.export_config())
core/logger.py000064400000074476150351351730007352 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2005-2007,2012 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "LogTarget", "FileLog", "Logger", "log" ]

import sys
import types
import time
import inspect
import fnmatch
import syslog
import traceback
import fcntl
import os.path
import os

# ---------------------------------------------------------------------------

# abstract class for logging targets
class LogTarget(object):
    """ Abstract class for logging targets. """
    def __init__(self):
        self.fd = None

    def write(self, data, level, logger, is_debug=0):
        raise NotImplementedError("LogTarget.write is an abstract method")

    def flush(self):
        raise NotImplementedError("LogTarget.flush is an abstract method")

    def close(self):
        raise NotImplementedError("LogTarget.close is an abstract method")

# ---------------------------------------------------------------------------

# private class for stdout
class _StdoutLog(LogTarget):
    def __init__(self):
        LogTarget.__init__(self)
        self.fd = sys.stdout

    def write(self, data, level, logger, is_debug=0):
        # ignore level
        self.fd.write(data)
        self.flush()

    def close(self):
        self.flush()

    def flush(self):
        self.fd.flush()

# ---------------------------------------------------------------------------

# private class for stderr
class _StderrLog(_StdoutLog):
    def __init__(self):
        _StdoutLog.__init__(self)
        self.fd = sys.stderr

# ---------------------------------------------------------------------------

# private class for syslog
class _SyslogLog(LogTarget):
    def __init__(self):
        # Only initialize LogTarget here as fs should be None
        LogTarget.__init__(self)
        #
        # Derived from: https://github.com/canvon/firewalld/commit/af0edfee1cc1891b7b13f302ca5911b24e9b0f13
        #
        # Work around Python issue 27875, "Syslogs /usr/sbin/foo as /foo
        # instead of as foo"
        # (but using openlog explicitly might be better anyway)
        #
        # Set ident to basename, log PID as well, and log to facility "daemon".
        syslog.openlog(os.path.basename(sys.argv[0]),
                       syslog.LOG_PID, syslog.LOG_DAEMON)

    def write(self, data, level, logger, is_debug=0):
        priority = None
        if is_debug:
            priority = syslog.LOG_DEBUG
        else:
            if level >= logger.INFO1:
                priority = syslog.LOG_INFO
            elif level == logger.WARNING:
                priority = syslog.LOG_WARNING
            elif level == logger.ERROR:
                priority = syslog.LOG_ERR
            elif level == logger.FATAL:
                priority = syslog.LOG_CRIT

        if data.endswith("\n"):
            data = data[:len(data)-1]
        if len(data) > 0:
            if priority is None:
                syslog.syslog(data)
            else:
                syslog.syslog(priority, data)

    def close(self):
        syslog.closelog()

    def flush(self):
        pass

# ---------------------------------------------------------------------------

class FileLog(LogTarget):
    """ FileLog class.
    File will be opened on the first write. """
    def __init__(self, filename, mode="w"):
        LogTarget.__init__(self)
        self.filename = filename
        self.mode = mode

    def open(self):
        if self.fd:
            return
        flags = os.O_CREAT | os.O_WRONLY
        if self.mode.startswith('a'):
            flags |= os.O_APPEND
        self.fd = os.open(self.filename, flags, 0o640)
        # Make sure that existing file has correct perms
        os.fchmod(self.fd, 0o640)
        # Make it an object
        self.fd = os.fdopen(self.fd, self.mode)
        fcntl.fcntl(self.fd, fcntl.F_SETFD, fcntl.FD_CLOEXEC)

    def write(self, data, level, logger, is_debug=0):
        if not self.fd:
            self.open()
        self.fd.write(data)
        self.fd.flush()

    def close(self):
        if not self.fd:
            return
        self.fd.close()
        self.fd = None

    def flush(self):
        if not self.fd:
            return
        self.fd.flush()

# ---------------------------------------------------------------------------

class Logger(object):
    r"""
    Format string:

    %(class)s      Calling class the function belongs to, else empty
    %(date)s       Date using Logger.date_format, see time module
    %(domain)s     Full Domain: %(module)s.%(class)s.%(function)s
    %(file)s       Filename of the module
    %(function)s   Function name, empty in __main__
    %(label)s      Label according to log function call from Logger.label
    %(level)d      Internal logging level
    %(line)d       Line number in module
    %(module)s     Module name
    %(message)s    Log message

    Standard levels:

    FATAL                 Fatal error messages
    ERROR                 Error messages
    WARNING               Warning messages
    INFOx, x in [1..5]    Information
    DEBUGy, y in [1..10]  Debug messages
    NO_INFO               No info output
    NO_DEBUG              No debug output
    INFO_MAX              Maximum info level
    DEBUG_MAX             Maximum debug level

    x and y depend on info_max and debug_max from Logger class
    initialization. See __init__ function.

    Default logging targets:

    stdout        Logs to stdout
    stderr        Logs to stderr
    syslog        Logs to syslog

    Additional arguments for logging functions (fatal, error, warning, info
    and debug):

    nl       Disable newline at the end with nl=0, default is nl=1.
    fmt      Format string for this logging entry, overloads global format
             string. Example: fmt="%(file)s:%(line)d %(message)s"
    nofmt    Only output message with nofmt=1. The nofmt argument wins over
             the fmt argument.

    Example:

    from logger import log
    log.setInfoLogLevel(log.INFO1)
    log.setDebugLogLevel(log.DEBUG1)
    for i in range(1, log.INFO_MAX+1):
        log.setInfoLogLabel(i, "INFO%d: " % i)
    log.setFormat("%(date)s %(module)s:%(line)d [%(domain)s] %(label)s: "
                  "%(level)d %(message)s")
    log.setDateFormat("%Y-%m-%d %H:%M:%S")

    fl = FileLog("/tmp/log", "a")
    log.addInfoLogging("*", fl)
    log.addDebugLogging("*", fl)
    log.addInfoLogging("*", log.syslog, fmt="%(label)s%(message)s")

    log.debug3("debug3")
    log.debug2("debug2")
    log.debug1("debug1")
    log.info2("info2")
    log.info1("info1")
    log.warning("warning\n", nl=0)
    log.error("error\n", nl=0)
    log.fatal("fatal")
    log.info(log.INFO1, "nofmt info", nofmt=1)

    """

    ALL       = -5
    NOTHING   = -4
    FATAL     = -3
    TRACEBACK = -2
    ERROR     = -1
    WARNING   =  0

    # Additional levels are generated in class initilization

    stdout = _StdoutLog()
    stderr = _StderrLog()
    syslog = _SyslogLog()

    def __init__(self, info_max=5, debug_max=10):
        """ Logger class initialization """
        self._level = { }
        self._debug_level = { }
        self._format = ""
        self._date_format = ""
        self._label = { }
        self._debug_label = { }
        self._logging = { }
        self._debug_logging = { }
        self._domains = { }
        self._debug_domains = { }

        # INFO1 is required for standard log level
        if info_max < 1:
            raise ValueError("Logger: info_max %d is too low" % info_max)
        if debug_max < 0:
            raise ValueError("Logger: debug_max %d is too low" % debug_max)

        self.NO_INFO   = self.WARNING # = 0
        self.INFO_MAX  = info_max
        self.NO_DEBUG  = 0
        self.DEBUG_MAX = debug_max

        self.setInfoLogLabel(self.FATAL, "FATAL ERROR: ")
        self.setInfoLogLabel(self.TRACEBACK, "")
        self.setInfoLogLabel(self.ERROR, "ERROR: ")
        self.setInfoLogLabel(self.WARNING, "WARNING: ")

        # generate info levels and infox functions
        for _level in range(1, self.INFO_MAX+1):
            setattr(self, "INFO%d" % _level, _level)
            self.setInfoLogLabel(_level, "")
            setattr(self, "info%d" % (_level),
                    (lambda self, x:
                     lambda message, *args, **kwargs:
                     self.info(x, message, *args, **kwargs))(self, _level)) # pylint: disable=E0602

        # generate debug levels and debugx functions
        for _level in range(1, self.DEBUG_MAX+1):
            setattr(self, "DEBUG%d" % _level, _level)
            self.setDebugLogLabel(_level, "DEBUG%d: " % _level)
            setattr(self, "debug%d" % (_level),
                    (lambda self, x:
                     lambda message, *args, **kwargs:
                     self.debug(x, message, *args, **kwargs))(self, _level)) # pylint: disable=E0602

        # set initial log levels, formats and targets
        self.setInfoLogLevel(self.INFO1)
        self.setDebugLogLevel(self.NO_DEBUG)
        self.setFormat("%(label)s%(message)s")
        self.setDateFormat("%d %b %Y %H:%M:%S")
        self.setInfoLogging("*", self.stderr, [ self.FATAL, self.ERROR,
                                                self.WARNING ])
        self.setInfoLogging("*", self.stdout,
                            [ i for i in range(self.INFO1, self.INFO_MAX+1) ])
        self.setDebugLogging("*", self.stdout,
                             [ i for i in range(1, self.DEBUG_MAX+1) ])

    def close(self):
        """ Close all logging targets """
        for level in range(self.FATAL, self.DEBUG_MAX+1):
            if level not in self._logging:
                continue
            for (dummy, target, dummy) in self._logging[level]:
                target.close()

    def getInfoLogLevel(self, domain="*"):
        """ Get info log level. """
        self._checkDomain(domain)
        if domain in self._level:
            return self._level[domain]
        return self.NOTHING

    def setInfoLogLevel(self, level, domain="*"):
        """ Set log level [NOTHING .. INFO_MAX] """
        self._checkDomain(domain)
        if level < self.NOTHING:
            level = self.NOTHING
        if level > self.INFO_MAX:
            level = self.INFO_MAX
        self._level[domain] = level

    def getDebugLogLevel(self, domain="*"):
        """ Get debug log level. """
        self._checkDomain(domain)
        if domain in self._debug_level:
            return self._debug_level[domain] + self.NO_DEBUG
        return self.NO_DEBUG

    def setDebugLogLevel(self, level, domain="*"):
        """ Set debug log level [NO_DEBUG .. DEBUG_MAX] """
        self._checkDomain(domain)
        if level < 0:
            level = 0
        if level > self.DEBUG_MAX:
            level = self.DEBUG_MAX
        self._debug_level[domain] = level - self.NO_DEBUG

    def getFormat(self):
        return self._format

    def setFormat(self, _format):
        self._format = _format

    def getDateFormat(self):
        return self._date_format

    def setDateFormat(self, _format):
        self._date_format = _format

    def setInfoLogLabel(self, level, label):
        """ Set log label for level. Level can be a single level or an array
        of levels. """
        levels = self._getLevels(level)
        for level in levels:
            self._checkLogLevel(level, min_level=self.FATAL,
                                max_level=self.INFO_MAX)
            self._label[level] = label

    def setDebugLogLabel(self, level, label):
        """ Set log label for level. Level can be a single level or an array
        of levels. """
        levels = self._getLevels(level, is_debug=1)
        for level in levels:
            self._checkLogLevel(level, min_level=self.INFO1,
                                max_level=self.DEBUG_MAX)
            self._debug_label[level] = label

    def setInfoLogging(self, domain, target, level=ALL, fmt=None):
        """ Set info log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. """
        self._setLogging(domain, target, level, fmt, is_debug=0)

    def setDebugLogging(self, domain, target, level=ALL, fmt=None):
        """ Set debug log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. """
        self._setLogging(domain, target, level, fmt, is_debug=1)

    def addInfoLogging(self, domain, target, level=ALL, fmt=None):
        """ Add info log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. """
        self._addLogging(domain, target, level, fmt, is_debug=0)

    def addDebugLogging(self, domain, target, level=ALL, fmt=None):
        """ Add debg log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. """
        self._addLogging(domain, target, level, fmt, is_debug=1)

    def delInfoLogging(self, domain, target, level=ALL, fmt=None):
        """ Delete info log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. """
        self._delLogging(domain, target, level, fmt, is_debug=0)

    def delDebugLogging(self, domain, target, level=ALL, fmt=None):
        """ Delete debug log target for domain and level. Level can be a single
        level or an array of levels. Use level ALL to set for all levels.
        If no format is specified, the default format will be used. """
        self._delLogging(domain, target, level, fmt, is_debug=1)

    def isInfoLoggingHere(self, level):
        """ Is there currently any info logging for this log level (and
        domain)? """
        return self._isLoggingHere(level, is_debug=0)

    def isDebugLoggingHere(self, level):
        """ Is there currently any debug logging for this log level (and
        domain)? """
        return self._isLoggingHere(level, is_debug=1)

    ### log functions

    def fatal(self, _format, *args, **kwargs):
        """ Fatal error log. """
        self._checkKWargs(kwargs)
        kwargs["is_debug"] = 0
        self._log(self.FATAL, _format, *args, **kwargs)

    def error(self, _format, *args, **kwargs):
        """ Error log. """
        self._checkKWargs(kwargs)
        kwargs["is_debug"] = 0
        self._log(self.ERROR, _format, *args, **kwargs)

    def warning(self, _format, *args, **kwargs):
        """ Warning log. """
        self._checkKWargs(kwargs)
        kwargs["is_debug"] = 0
        self._log(self.WARNING, _format, *args, **kwargs)

    def info(self, level, _format, *args, **kwargs):
        """ Information log using info level [1..info_max].
        There are additional infox functions according to info_max from
        __init__"""
        self._checkLogLevel(level, min_level=1, max_level=self.INFO_MAX)
        self._checkKWargs(kwargs)
        kwargs["is_debug"] = 0
        self._log(level+self.NO_INFO, _format, *args, **kwargs)

    def debug(self, level, _format, *args, **kwargs):
        """ Debug log using debug level [1..debug_max].
        There are additional debugx functions according to debug_max
        from __init__"""
        self._checkLogLevel(level, min_level=1, max_level=self.DEBUG_MAX)
        self._checkKWargs(kwargs)
        kwargs["is_debug"] = 1
        self._log(level, _format, *args, **kwargs)

    def exception(self):
        self._log(self.TRACEBACK, traceback.format_exc(), args=[], kwargs={})

    ### internal functions

    def _checkLogLevel(self, level, min_level, max_level):
        if level < min_level or level > max_level:
            raise ValueError("Level %d out of range, should be [%d..%d]." % \
                             (level, min_level, max_level))

    def _checkKWargs(self, kwargs):
        if not kwargs:
            return
        for key in kwargs.keys():
            if key not in [ "nl", "fmt", "nofmt" ]:
                raise ValueError("Key '%s' is not allowed as argument for logging." % key)

    def _checkDomain(self, domain):
        if not domain or domain == "":
            raise ValueError("Domain '%s' is not valid." % domain)

    def _getLevels(self, level, is_debug=0):
        """ Generate log level array. """
        if level != self.ALL:
            if isinstance(level, list) or isinstance(level, tuple):
                levels = level
            else:
                levels = [ level ]
            for level in levels:
                if is_debug:
                    self._checkLogLevel(level, min_level=1,
                                        max_level=self.DEBUG_MAX)
                else:
                    self._checkLogLevel(level, min_level=self.FATAL,
                                        max_level=self.INFO_MAX)
        else:
            if is_debug:
                levels = [ i for i in range(self.DEBUG1, self.DEBUG_MAX) ]
            else:
                levels = [ i for i in range(self.FATAL, self.INFO_MAX) ]
        return levels

    def _getTargets(self, target):
        """ Generate target array. """
        if isinstance(target, list) or isinstance(target, tuple):
            targets = target
        else:
            targets = [ target ]
        for _target in targets:
            if not issubclass(_target.__class__, LogTarget):
                raise ValueError("'%s' is no valid logging target." % \
                      _target.__class__.__name__)
        return targets

    def _genDomains(self, is_debug=0):
        # private method for self._domains array creation, speeds up
        """ Generate dict with domain by level. """
        if is_debug:
            _domains = self._debug_domains
            _logging = self._debug_logging
            _range = ( 1, self.DEBUG_MAX+1 )
        else:
            _domains = self._domains
            _logging = self._logging
            _range = ( self.FATAL, self.INFO_MAX+1 )

        if len(_domains) > 0:
            _domains.clear()

        for level in range(_range[0], _range[1]):
            if level not in _logging:
                continue
            for (domain, dummy, dummy) in _logging[level]:
                if domain not in _domains:
                    _domains.setdefault(level, [ ]).append(domain)

    def _setLogging(self, domain, target, level=ALL, fmt=None, is_debug=0):
        self._checkDomain(domain)
        levels = self._getLevels(level, is_debug)
        targets = self._getTargets(target)

        if is_debug:
            _logging = self._debug_logging
        else:
            _logging = self._logging

        for level in levels:
            for target in targets:
                _logging[level] = [ (domain, target, fmt) ]
        self._genDomains(is_debug)

    def _addLogging(self, domain, target, level=ALL, fmt=None, is_debug=0):
        self._checkDomain(domain)
        levels = self._getLevels(level, is_debug)
        targets = self._getTargets(target)

        if is_debug:
            _logging = self._debug_logging
        else:
            _logging = self._logging

        for level in levels:
            for target in targets:
                _logging.setdefault(level, [ ]).append((domain, target, fmt))
        self._genDomains(is_debug)

    def _delLogging(self, domain, target, level=ALL, fmt=None, is_debug=0):
        self._checkDomain(domain)
        levels = self._getLevels(level, is_debug)
        targets = self._getTargets(target)

        if is_debug:
            _logging = self._debug_logging
        else:
            _logging = self._logging

        for _level in levels:
            for target in targets:
                if _level not in _logging:
                    continue
                if (domain, target, fmt) in _logging[_level]:
                    _logging[_level].remove( (domain, target, fmt) )
                    if len(_logging[_level]) == 0:
                        del _logging[_level]
                        continue
                if level != self.ALL:
                    raise ValueError("No mathing logging for " \
                          "level %d, domain %s, target %s and format %s." % \
                          (_level, domain, target.__class__.__name__, fmt))
        self._genDomains(is_debug)

    def _isLoggingHere(self, level, is_debug=0):
        _dict = self._genDict(level, is_debug)
        if not _dict:
            return False

        point_domain = _dict["domain"] + "."

        if is_debug:
            _logging = self._debug_logging
        else:
            _logging = self._logging

        # do we need to log?
        for (domain, dummy, dummy) in _logging[level]:
            if domain == "*" or \
                   point_domain.startswith(domain) or \
                   fnmatch.fnmatchcase(_dict["domain"], domain):
                return True
        return False

    def _getClass(self, frame):
        """ Function to get calling class. Returns class or None. """
        # get class by first function argument, if there are any
        if frame.f_code.co_argcount > 0:
            selfname = frame.f_code.co_varnames[0]
            if selfname in frame.f_locals:
                _self = frame.f_locals[selfname]
                obj = self._getClass2(_self.__class__, frame.f_code)
                if obj:
                    return obj

        module = inspect.getmodule(frame.f_code)
        code = frame.f_code

        # function in module?
        if code.co_name in module.__dict__:
            if hasattr(module.__dict__[code.co_name], "func_code") and \
                   module.__dict__[code.co_name].__code__  == code:
                return None

        # class in module
        for (dummy, obj) in module.__dict__.items():
            if isinstance(obj, types.ClassType):
                if hasattr(obj, code.co_name):
                    value = getattr(obj, code.co_name)
                    if isinstance(value, types.FunctionType):
                        if value.__code__ == code:
                            return obj

        # nothing found
        return None

    def _getClass2(self, obj, code):
        """ Internal function to get calling class. Returns class or None. """
        for value in obj.__dict__.values():
            if isinstance(value, types.FunctionType):
                if value.__code__ == code:
                    return obj

        for base in obj.__bases__:
            _obj = self._getClass2(base, code)
            if _obj:
                return _obj
        return None

    # internal log class
    def _log(self, level, _format, *args, **kwargs):
        is_debug = 0
        if "is_debug" in kwargs:
            is_debug = kwargs["is_debug"]

        nl = 1
        if "nl" in kwargs:
            nl = kwargs["nl"]

        nofmt = 0
        if "nofmt" in kwargs:
            nofmt = kwargs["nofmt"]

        _dict = self._genDict(level, is_debug)
        if not _dict:
            return

        if len(args) > 1:
            _dict['message'] = _format % args
        elif len(args) == 1:  # needed for _format % _dict
            _dict['message'] = _format % args[0]
        else:
            _dict['message'] = _format

        point_domain = _dict["domain"] + "."

        if is_debug:
            _logging = self._debug_logging
        else:
            _logging = self._logging

        used_targets = [ ]
        # log to target(s)
        for (domain, target, _format) in _logging[level]:
            if target in used_targets:
                continue
            if domain == "*" \
                   or point_domain.startswith(domain+".") \
                   or fnmatch.fnmatchcase(_dict["domain"], domain):
                if not _format:
                    _format = self._format
                if "fmt" in kwargs:
                    _format = kwargs["fmt"]
                if nofmt:
                    target.write(_dict["message"], level, self, is_debug)
                else:
                    target.write(_format % _dict, level, self, is_debug)
                if nl: # newline
                    target.write("\n", level, self, is_debug)
                used_targets.append(target)

    # internal function to generate the dict, needed for logging
    def _genDict(self, level, is_debug=0):
        """ Internal function. """
        check_domains = [ ]
        simple_match = False

        if is_debug:
            _dict = self._debug_level
            _domains = self._debug_domains
            _label = self._debug_label
        else:
            _dict = self._level
            _domains = self._domains
            _label = self._label

        # no debug
        for domain in _dict:
            if domain == "*":
                # '*' matches everything: simple match
                if _dict[domain] >= level:
                    simple_match = True
                    if len(check_domains) > 0:
                        check_domains = [ ]
                    break
            else:
                if _dict[domain] >= level:
                    check_domains.append(domain)

        if not simple_match and len(check_domains) < 1:
            return None

        if level not in _domains:
            return None

        f = inspect.currentframe()

        # go outside of logger module as long as there is a lower frame
        while f and f.f_back and f.f_globals["__name__"] == self.__module__:
            f = f.f_back

        if not f:
            raise ValueError("Frame information not available.")

        # get module name
        module_name = f.f_globals["__name__"]

        # simple module match test for all entries of check_domain
        point_module = module_name + "."
        for domain in check_domains:
            if point_module.startswith(domain):
                # found domain in module name
                check_domains = [ ]
                break

        # get code
        co = f.f_code

        # optimization: bail out early if domain can not match at all
        _len = len(module_name)
        for domain in _domains[level]:
            i = domain.find("*")
            if i == 0:
                continue
            elif i > 0:
                d = domain[:i]
            else:
                d = domain
            if _len >= len(d):
                if not module_name.startswith(d):
                    return None
            else:
                if not d.startswith(module_name):
                    return None

        # generate _dict for format output
        level_str = ""
        if level in _label:
            level_str = _label[level]
        _dict = { 'file': co.co_filename,
                  'line': f.f_lineno,
                  'module': module_name,
                  'class': '',
                  'function': co.co_name,
                  'domain': '',
                  'label' : level_str,
                  'level' : level,
                  'date' : time.strftime(self._date_format, time.localtime()) }
        if _dict["function"] == "?":
            _dict["function"] = ""

        # domain match needed?
        domain_needed = False
        for domain in _domains[level]:
            # standard domain, matches everything
            if domain == "*":
                continue
            # domain is needed
            domain_needed = True
            break

        # do we need to get the class object?
        if self._format.find("%(domain)") >= 0 or \
               self._format.find("%(class)") >= 0 or \
               domain_needed or \
               len(check_domains) > 0:
            obj = self._getClass(f)
            if obj:
                _dict["class"] = obj.__name__

        # build domain string
        _dict["domain"] = "" + _dict["module"]
        if _dict["class"] != "":
            _dict["domain"] += "." + _dict["class"]
        if _dict["function"] != "":
            _dict["domain"] += "." + _dict["function"]

        if len(check_domains) < 1:
            return _dict

        point_domain = _dict["domain"] + "."
        for domain in check_domains:
            if point_domain.startswith(domain) or \
                   fnmatch.fnmatchcase(_dict["domain"], domain):
                return _dict

        return None

# ---------------------------------------------------------------------------

# Global logging object.
log = Logger()

# ---------------------------------------------------------------------------

"""
# Example
if __name__ == '__main__':
    log.setInfoLogLevel(log.INFO2)
    log.setDebugLogLevel(log.DEBUG5)
    for i in range(log.INFO1, log.INFO_MAX+1):
        log.setInfoLogLabel(i, "INFO%d: " % i)
    for i in range(log.DEBUG1, log.DEBUG_MAX+1):
        log.setDebugLogLabel(i, "DEBUG%d: " % i)

    log.setFormat("%(date)s %(module)s:%(line)d %(label)s"
                  "%(message)s")
    log.setDateFormat("%Y-%m-%d %H:%M:%S")

    fl = FileLog("/tmp/log", "a")
    log.addInfoLogging("*", fl)
    log.delDebugLogging("*", log.stdout)
    log.setDebugLogging("*", log.stdout, [ log.DEBUG1, log.DEBUG2 ] )
    log.addDebugLogging("*", fl)
#    log.addInfoLogging("*", log.syslog, fmt="%(label)s%(message)s")
#    log.addDebugLogging("*", log.syslog, fmt="%(label)s%(message)s")

    log.debug10("debug10")
    log.debug9("debug9")
    log.debug8("debug8")
    log.debug7("debug7")
    log.debug6("debug6")
    log.debug5("debug5")
    log.debug4("debug4")
    log.debug3("debug3")
    log.debug2("debug2", fmt="%(file)s:%(line)d %(message)s")
    log.debug1("debug1", nofmt=1)
    log.info5("info5")
    log.info4("info4")
    log.info3("info3")
    log.info2("info2")
    log.info1("info1")
    log.warning("warning\n", nl=0)
    log.error("error ", nl=0)
    log.error("error", nofmt=1)
    log.fatal("fatal")
    log.info(log.INFO1, "nofmt info", nofmt=1)
    log.info(log.INFO2, "info2 fmt", fmt="%(file)s:%(line)d %(message)s")

    try:
        a = b
    except Exception as e:
        log.exception()
"""

# vim:ts=4:sw=4:showmatch:expandtab
core/ipset.py000064400000031161150351351730007177 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2015-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""The ipset command wrapper"""

__all__ = [ "ipset", "check_ipset_name", "remove_default_create_options" ]

import os.path
import ipaddress

from firewall import errors
from firewall.errors import FirewallError
from firewall.core.prog import runProg
from firewall.core.logger import log
from firewall.functions import tempFile, readfile
from firewall.config import COMMANDS

IPSET_MAXNAMELEN = 32
IPSET_TYPES = [
    # bitmap and set types are currently not supported
    # "bitmap:ip",
    # "bitmap:ip,mac",
    # "bitmap:port",
    # "list:set",

    "hash:ip",
    "hash:ip,port",
    "hash:ip,port,ip",
    "hash:ip,port,net",
    "hash:ip,mark",

    "hash:net",
    "hash:net,net",
    "hash:net,port",
    "hash:net,port,net",
    "hash:net,iface",

    "hash:mac",
]
IPSET_CREATE_OPTIONS = {
    "family": "inet|inet6",
    "hashsize": "value",
    "maxelem": "value",
    "timeout": "value in secs",
    #"counters": None,
    #"comment": None,
}
IPSET_DEFAULT_CREATE_OPTIONS = {
    "family": "inet",
    "hashsize": "1024",
    "maxelem": "65536",
}

class ipset(object):
    """ipset command wrapper class"""

    def __init__(self):
        self._command = COMMANDS["ipset"]
        self.name = "ipset"

    def __run(self, args):
        """Call ipset with args"""
        # convert to string list
        _args = ["%s" % item for item in args]
        log.debug2("%s: %s %s", self.__class__, self._command, " ".join(_args))
        (status, ret) = runProg(self._command, _args)
        if status != 0:
            raise ValueError("'%s %s' failed: %s" % (self._command,
                                                     " ".join(_args), ret))
        return ret

    def check_name(self, name):
        """Check ipset name"""
        if len(name) > IPSET_MAXNAMELEN:
            raise FirewallError(errors.INVALID_NAME,
                                "ipset name '%s' is not valid" % name)

    def set_supported_types(self):
        """Return types that are supported by the ipset command and kernel"""
        ret = [ ]
        output = ""
        try:
            output = self.__run(["--help"])
        except ValueError as ex:
            log.debug1("ipset error: %s" % ex)
        lines = output.splitlines()

        in_types = False
        for line in lines:
            #print(line)
            if in_types:
                splits = line.strip().split(None, 2)
                if splits[0] not in ret and splits[0] in IPSET_TYPES:
                    ret.append(splits[0])
            if line.startswith("Supported set types:"):
                in_types = True
        return ret

    def check_type(self, type_name):
        """Check ipset type"""
        if len(type_name) > IPSET_MAXNAMELEN or type_name not in IPSET_TYPES:
            raise FirewallError(errors.INVALID_TYPE,
                                "ipset type name '%s' is not valid" % type_name)

    def set_create(self, set_name, type_name, options=None):
        """Create an ipset with name, type and options"""
        self.check_name(set_name)
        self.check_type(type_name)

        args = [ "create", set_name, type_name ]
        if isinstance(options, dict):
            for key, val in options.items():
                args.append(key)
                if val != "":
                    args.append(val)
        return self.__run(args)

    def set_destroy(self, set_name):
        self.check_name(set_name)
        return self.__run([ "destroy", set_name ])

    def set_add(self, set_name, entry):
        args = [ "add", set_name, entry ]
        return self.__run(args)

    def set_delete(self, set_name, entry):
        args = [ "del", set_name, entry ]
        return self.__run(args)

    def test(self, set_name, entry, options=None):
        args = [ "test", set_name, entry ]
        if options:
            args.append("%s" % " ".join(options))
        return self.__run(args)

    def set_list(self, set_name=None, options=None):
        args = [ "list" ]
        if set_name:
            args.append(set_name)
        if options:
            args.extend(options)
        return self.__run(args).split("\n")

    def set_get_active_terse(self):
        """ Get active ipsets (only headers) """
        lines = self.set_list(options=["-terse"])

        ret = { }
        _name = _type = None
        _options = { }
        for line in lines:
            if len(line) < 1:
                continue
            pair = [ x.strip() for x in line.split(":", 1) ]
            if len(pair) != 2:
                continue
            elif pair[0] == "Name":
                _name = pair[1]
            elif pair[0] == "Type":
                _type = pair[1]
            elif pair[0] == "Header":
                splits = pair[1].split()
                i = 0
                while i < len(splits):
                    opt = splits[i]
                    if opt in [ "family", "hashsize", "maxelem", "timeout",
                                "netmask" ]:
                        if len(splits) > i:
                            i += 1
                            _options[opt] = splits[i]
                        else:
                            log.error("Malformed ipset list -terse output: %s",
                                      line)
                            return { }
                    i += 1
                if _name and _type:
                    ret[_name] = (_type,
                                  remove_default_create_options(_options))
                _name = _type = None
                _options.clear()
        return ret

    def save(self, set_name=None):
        args = [ "save" ]
        if set_name:
            args.append(set_name)
        return self.__run(args)

    def set_restore(self, set_name, type_name, entries,
                create_options=None, entry_options=None):
        self.check_name(set_name)
        self.check_type(type_name)

        temp_file = tempFile()

        if ' ' in set_name:
            set_name = "'%s'" % set_name
        args = [ "create", set_name, type_name, "-exist" ]
        if create_options:
            for key, val in create_options.items():
                args.append(key)
                if val != "":
                    args.append(val)
        temp_file.write("%s\n" % " ".join(args))
        temp_file.write("flush %s\n" % set_name)

        for entry in entries:
            if ' ' in entry:
                entry = "'%s'" % entry
            if entry_options:
                temp_file.write("add %s %s %s\n" % \
                                (set_name, entry, " ".join(entry_options)))
            else:
                temp_file.write("add %s %s\n" % (set_name, entry))
        temp_file.close()

        stat = os.stat(temp_file.name)
        log.debug2("%s: %s restore %s", self.__class__, self._command,
                   "%s: %d" % (temp_file.name, stat.st_size))

        args = [ "restore" ]
        (status, ret) = runProg(self._command, args,
                                stdin=temp_file.name)

        if log.getDebugLogLevel() > 2:
            try:
                readfile(temp_file.name)
            except Exception:
                pass
            else:
                i = 1
                for line in readfile(temp_file.name):
                    log.debug3("%8d: %s" % (i, line), nofmt=1, nl=0)
                    if not line.endswith("\n"):
                        log.debug3("", nofmt=1)
                    i += 1

        os.unlink(temp_file.name)

        if status != 0:
            raise ValueError("'%s %s' failed: %s" % (self._command,
                                                     " ".join(args), ret))
        return ret

    def set_flush(self, set_name):
        args = [ "flush" ]
        if set_name:
            args.append(set_name)
        return self.__run(args)

    def rename(self, old_set_name, new_set_name):
        return self.__run([ "rename", old_set_name, new_set_name ])

    def swap(self, set_name_1, set_name_2):
        return self.__run([ "swap", set_name_1, set_name_2 ])

    def version(self):
        return self.__run([ "version" ])


def check_ipset_name(name):
    """Return true if ipset name is valid"""
    if len(name) > IPSET_MAXNAMELEN:
        return False
    return True

def remove_default_create_options(options):
    """ Return only non default create options """
    _options = options.copy()
    for opt in IPSET_DEFAULT_CREATE_OPTIONS:
        if opt in _options and \
           IPSET_DEFAULT_CREATE_OPTIONS[opt] == _options[opt]:
            del _options[opt]
    return _options

def normalize_ipset_entry(entry):
    """ Normalize IP addresses in entry """
    _entry = []
    for _part in entry.split(","):
        try:
            _part.index("/")
            _entry.append(str(ipaddress.ip_network(_part, strict=False)))
        except ValueError:
            _entry.append(_part)

    return ",".join(_entry)

def check_entry_overlaps_existing(entry, entries):
    """ Check if entry overlaps any entry in the list of entries """
    # Only check simple types
    if len(entry.split(",")) > 1:
        return

    try:
        entry_network = ipaddress.ip_network(entry, strict=False)
    except ValueError:
        # could not parse the new IP address, maybe a MAC
        return

    for itr in entries:
        if entry_network.overlaps(ipaddress.ip_network(itr, strict=False)):
            raise FirewallError(errors.INVALID_ENTRY, "Entry '{}' overlaps with existing entry '{}'".format(entry, itr))

def check_for_overlapping_entries(entries):
    """ Check if any entry overlaps any entry in the list of entries """
    try:
        entries = [ipaddress.ip_network(x, strict=False) for x in entries]
    except ValueError:
        # at least one entry can not be parsed
        return

    if len(entries) == 0:
        return

    # We can take advantage of some facts of IPv4Network/IPv6Network and
    # how Python sorts the networks to quickly detect overlaps.
    #
    # Facts:
    #
    #   1. IPv{4,6}Network are normalized to remove host bits, e.g.
    #     10.1.1.0/16 will become 10.1.0.0/16.
    #
    #   2. IPv{4,6}Network objects are sorted by:
    #     a. IP address (network bits)
    #   then
    #     b. netmask (significant bits count)
    #
    # Because of the above we have these properties:
    #
    #   1. big networks (netA) are sorted before smaller networks (netB)
    #      that overlap the big network (netA)
    #     - e.g. 10.1.128.0/17 (netA) sorts before 10.1.129.0/24 (netB)
    #   2. same value addresses (network bits) are grouped together even
    #      if the number of network bits vary. e.g. /16 vs /24
    #     - recall that address are normalized to remove host bits
    #     - e.g. 10.1.128.0/17 (netA) sorts before 10.1.128.0/24 (netC)
    #   3. non-overlapping networks (netD, netE) are always sorted before or
    #      after networks that overlap (netB, netC) the current one (netA)
    #     - e.g. 10.1.128.0/17 (netA) sorts before 10.2.128.0/16 (netD)
    #     - e.g. 10.1.128.0/17 (netA) sorts after 9.1.128.0/17 (netE)
    #     - e.g. 9.1.128.0/17 (netE) sorts before 10.1.129.0/24 (netB)
    #
    # With this we know the sorted list looks like:
    #
    #   list: [ netE, netA, netB, netC, netD ]
    #
    #   netE = non-overlapping network
    #   netA = big network
    #   netB = smaller network that overlaps netA (subnet)
    #   netC = smaller network that overlaps netA (subnet)
    #   netD = non-overlapping network
    #
    #   If networks netB and netC exist in the list, they overlap and are
    #   adjacent to netA.
    #
    # Checking for overlaps on a sorted list is thus:
    #
    #   1. compare adjacent elements in the list for overlaps
    #
    # Recall that we only need to detect a single overlap. We do not need to
    # detect them all.
    #
    entries.sort()
    prev_network = entries.pop(0)
    for current_network in entries:
        if prev_network.overlaps(current_network):
            raise FirewallError(errors.INVALID_ENTRY, "Entry '{}' overlaps entry '{}'".format(prev_network, current_network))
        prev_network = current_network
core/fw_direct.py000064400000053766150351351730010040 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "FirewallDirect" ]

from firewall.fw_types import LastUpdatedOrderedDict
from firewall.core import ipXtables
from firewall.core import ebtables
from firewall.core.fw_transaction import FirewallTransaction
from firewall.core.logger import log
from firewall import errors
from firewall.errors import FirewallError

############################################################################
#
# class Firewall
#
############################################################################

class FirewallDirect(object):
    def __init__(self, fw):
        self._fw = fw
        self.__init_vars()

    def __repr__(self):
        return '%s(%r, %r, %r)' % (self.__class__, self._chains, self._rules,
                                   self._rule_priority_positions)

    def __init_vars(self):
        self._chains = { }
        self._rules = { }
        self._rule_priority_positions = { }
        self._passthroughs = { }
        self._obj = None

    def cleanup(self):
        self.__init_vars()

    # transaction

    def new_transaction(self):
        return FirewallTransaction(self._fw)

    # configuration

    def set_permanent_config(self, obj):
        self._obj = obj

    def has_runtime_configuration(self):
        if len(self._chains) + len(self._rules) + len(self._passthroughs) > 0:
            return True
        return False

    def has_configuration(self):
        if self.has_runtime_configuration():
            return True
        if len(self._obj.get_all_chains()) + \
           len(self._obj.get_all_rules()) + \
           len(self._obj.get_all_passthroughs()) > 0:
            return True
        return False

    def apply_direct(self, use_transaction=None):
        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        # Apply permanent configuration and save the obj to be able to
        # remove permanent configuration settings within get_runtime_config
        # for use in firewalld reload.
        self.set_config((self._obj.get_all_chains(),
                         self._obj.get_all_rules(),
                         self._obj.get_all_passthroughs()),
                        transaction)

        if use_transaction is None:
            transaction.execute(True)

    def get_runtime_config(self):
        # Return only runtime changes
        # Remove all chains, rules and passthroughs that are in self._obj
        # (permanent config applied in firewalld _start.
        chains = { }
        rules = { }
        passthroughs = { }

        for table_id in self._chains:
            (ipv, table) = table_id
            for chain in self._chains[table_id]:
                if not self._obj.query_chain(ipv, table, chain):
                    chains.setdefault(table_id, [ ]).append(chain)

        for chain_id in self._rules:
            (ipv, table, chain) = chain_id
            for (priority, args) in self._rules[chain_id]:
                if not self._obj.query_rule(ipv, table, chain, priority, args):
                    if chain_id not in rules:
                        rules[chain_id] = LastUpdatedOrderedDict()
                    rules[chain_id][(priority, args)] = priority

        for ipv in self._passthroughs:
            for args in self._passthroughs[ipv]:
                if not self._obj.query_passthrough(ipv, args):
                    if ipv not in passthroughs:
                        passthroughs[ipv] = [ ]
                    passthroughs[ipv].append(args)

        return (chains, rules, passthroughs)

    def get_config(self):
        return (self._chains, self._rules, self._passthroughs)

    def set_config(self, conf, use_transaction=None):
        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        (_chains, _rules, _passthroughs) = conf
        for table_id in _chains:
            (ipv, table) = table_id
            for chain in _chains[table_id]:
                if not self.query_chain(ipv, table, chain):
                    try:
                        self.add_chain(ipv, table, chain,
                                       use_transaction=transaction)
                    except FirewallError as error:
                        log.warning(str(error))

        for chain_id in _rules:
            (ipv, table, chain) = chain_id
            for (priority, args) in _rules[chain_id]:
                if not self.query_rule(ipv, table, chain, priority, args):
                    try:
                        self.add_rule(ipv, table, chain, priority, args,
                                      use_transaction=transaction)
                    except FirewallError as error:
                        log.warning(str(error))

        for ipv in _passthroughs:
            for args in _passthroughs[ipv]:
                if not self.query_passthrough(ipv, args):
                    try:
                        self.add_passthrough(ipv, args,
                                             use_transaction=transaction)
                    except FirewallError as error:
                        log.warning(str(error))

        if use_transaction is None:
            transaction.execute(True)

    def _check_ipv(self, ipv):
        ipvs = ['ipv4', 'ipv6', 'eb']
        if ipv not in ipvs:
            raise FirewallError(errors.INVALID_IPV,
                                "'%s' not in '%s'" % (ipv, ipvs))

    def _check_ipv_table(self, ipv, table):
        self._check_ipv(ipv)

        tables = ipXtables.BUILT_IN_CHAINS.keys() if ipv in [ 'ipv4', 'ipv6' ] \
                                         else ebtables.BUILT_IN_CHAINS.keys()
        if table not in tables:
            raise FirewallError(errors.INVALID_TABLE,
                                "'%s' not in '%s'" % (table, tables))

    def _check_builtin_chain(self, ipv, table, chain):
        if ipv in ['ipv4', 'ipv6']:
            built_in_chains = ipXtables.BUILT_IN_CHAINS[table]
            if self._fw.nftables_enabled:
                our_chains = {}
            else:
                our_chains = self._fw.get_direct_backend_by_ipv(ipv).our_chains[table]
        else:
            built_in_chains = ebtables.BUILT_IN_CHAINS[table]
            our_chains = ebtables.OUR_CHAINS[table]
        if chain in built_in_chains:
            raise FirewallError(errors.BUILTIN_CHAIN,
                                "chain '%s' is built-in chain" % chain)
        if chain in our_chains:
            raise FirewallError(errors.BUILTIN_CHAIN,
                                "chain '%s' is reserved" % chain)
        if ipv in [ "ipv4", "ipv6" ]:
            if self._fw.zone.zone_from_chain(chain) is not None:
                raise FirewallError(errors.INVALID_CHAIN,
                                    "Chain '%s' is reserved" % chain)


    def _register_chain(self, table_id, chain, add):
        if add:
            self._chains.setdefault(table_id, [ ]).append(chain)
        else:
            self._chains[table_id].remove(chain)
            if len(self._chains[table_id]) == 0:
                del self._chains[table_id]

    def add_chain(self, ipv, table, chain, use_transaction=None):
        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if self._fw.may_skip_flush_direct_backends():
            transaction.add_pre(self._fw.flush_direct_backends)

        #TODO: policy="ACCEPT"
        self._chain(True, ipv, table, chain, transaction)

        if use_transaction is None:
            transaction.execute(True)

    def remove_chain(self, ipv, table, chain, use_transaction=None):
        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        self._chain(False, ipv, table, chain, transaction)

        if use_transaction is None:
            transaction.execute(True)

    def query_chain(self, ipv, table, chain):
        self._check_ipv_table(ipv, table)
        self._check_builtin_chain(ipv, table, chain)
        table_id = (ipv, table)
        return (table_id in self._chains and
                chain in self._chains[table_id])

    def get_chains(self, ipv, table):
        self._check_ipv_table(ipv, table)
        table_id = (ipv, table)
        if table_id in self._chains:
            return self._chains[table_id]
        return [ ]

    def get_all_chains(self):
        r = [ ]
        for key in self._chains:
            (ipv, table) = key
            for chain in self._chains[key]:
                r.append((ipv, table, chain))
        return r


    def add_rule(self, ipv, table, chain, priority, args, use_transaction=None):
        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if self._fw.may_skip_flush_direct_backends():
            transaction.add_pre(self._fw.flush_direct_backends)

        self._rule(True, ipv, table, chain, priority, args, transaction)

        if use_transaction is None:
            transaction.execute(True)

    def remove_rule(self, ipv, table, chain, priority, args,
                    use_transaction=None):
        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        self._rule(False, ipv, table, chain, priority, args, transaction)

        if use_transaction is None:
            transaction.execute(True)

    def query_rule(self, ipv, table, chain, priority, args):
        self._check_ipv_table(ipv, table)
        chain_id = (ipv, table, chain)
        return chain_id in self._rules and \
            (priority, args) in self._rules[chain_id]

    def get_rules(self, ipv, table, chain):
        self._check_ipv_table(ipv, table)
        chain_id = (ipv, table, chain)
        if chain_id in self._rules:
            return list(self._rules[chain_id].keys())
        return [ ]

    def get_all_rules(self):
        r = [ ]
        for key in self._rules:
            (ipv, table, chain) = key
            for (priority, args) in self._rules[key]:
                r.append((ipv, table, chain, priority, list(args)))
        return r

    def _register_rule(self, rule_id, chain_id, priority, enable, count):
        if enable:
            if chain_id not in self._rules:
                self._rules[chain_id] = LastUpdatedOrderedDict()
            self._rules[chain_id][rule_id] = priority
            if chain_id not in self._rule_priority_positions:
                self._rule_priority_positions[chain_id] = { }

            if priority in self._rule_priority_positions[chain_id]:
                self._rule_priority_positions[chain_id][priority] += count
            else:
                self._rule_priority_positions[chain_id][priority] = count
        else:
            del self._rules[chain_id][rule_id]
            if len(self._rules[chain_id]) == 0:
                del self._rules[chain_id]
            self._rule_priority_positions[chain_id][priority] -= count

    # DIRECT PASSTHROUGH (untracked)

    def passthrough(self, ipv, args):
        try:
            return self._fw.rule(self._fw.get_direct_backend_by_ipv(ipv).name, args)
        except Exception as msg:
            log.debug2(msg)
            raise FirewallError(errors.COMMAND_FAILED, msg)


    def _register_passthrough(self, ipv, args, enable):
        if enable:
            if ipv not in self._passthroughs:
                self._passthroughs[ipv] = [ ]
            self._passthroughs[ipv].append(args)
        else:
            self._passthroughs[ipv].remove(args)
            if len(self._passthroughs[ipv]) == 0:
                del self._passthroughs[ipv]

    def add_passthrough(self, ipv, args, use_transaction=None):
        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if self._fw.may_skip_flush_direct_backends():
            transaction.add_pre(self._fw.flush_direct_backends)

        self._passthrough(True, ipv, list(args), transaction)

        if use_transaction is None:
            transaction.execute(True)

    def remove_passthrough(self, ipv, args, use_transaction=None):
        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        self._passthrough(False, ipv, list(args), transaction)

        if use_transaction is None:
            transaction.execute(True)

    def query_passthrough(self, ipv, args):
        return ipv in self._passthroughs and \
            tuple(args) in self._passthroughs[ipv]

    def get_all_passthroughs(self):
        r = [ ]
        for ipv in self._passthroughs:
            for args in self._passthroughs[ipv]:
                r.append((ipv, list(args)))
        return r

    def get_passthroughs(self, ipv):
        r = [ ]
        if ipv in self._passthroughs:
            for args in self._passthroughs[ipv]:
                r.append(list(args))
        return r

    def split_value(self, rules, opts):
        """Split values combined with commas for options in opts"""

        out_rules = [ ]
        for rule in rules:
            processed = False
            for opt in opts:
                try:
                    i = rule.index(opt)
                except ValueError:
                    pass
                else:
                    if len(rule) > i and "," in rule[i+1]:
                        # For all items in the comma separated list in index
                        # i of the rule, a new rule is created with a single
                        # item from this list
                        processed = True
                        items = rule[i+1].split(",")
                        for item in items:
                            _rule = rule[:]
                            _rule[i+1] = item
                            out_rules.append(_rule)
            if not processed:
                out_rules.append(rule)

        return out_rules


    def _rule(self, enable, ipv, table, chain, priority, args, transaction):
        self._check_ipv_table(ipv, table)
        # Do not create zone chains if we're using nftables. Only allow direct
        # rules in the built in chains.
        if not self._fw.nftables_enabled \
           and ipv in [ "ipv4", "ipv6" ]:
            self._fw.zone.create_zone_base_by_chain(ipv, table, chain,
                                                    transaction)

        _chain = chain

        backend = self._fw.get_direct_backend_by_ipv(ipv)

        # if nftables is in use, just put the direct rules in the chain
        # specified by the user. i.e. don't append _direct.
        if not self._fw.nftables_enabled \
           and backend.is_chain_builtin(ipv, table, chain):
            _chain = "%s_direct" % (chain)
        elif self._fw.nftables_enabled and chain[-7:] == "_direct" \
             and backend.is_chain_builtin(ipv, table, chain[:-7]):
            # strip _direct suffix. If we're using nftables we don't bother
            # creating the *_direct chains for builtin chains.
            _chain = chain[:-7]

        chain_id = (ipv, table, chain)
        rule_id = (priority, args)

        if enable:
            if chain_id in self._rules and \
                    rule_id in self._rules[chain_id]:
                raise FirewallError(errors.ALREADY_ENABLED,
                                    "rule '%s' already is in '%s:%s:%s'" % \
                                    (args, ipv, table, chain))
        else:
            if chain_id not in self._rules or \
                    rule_id not in self._rules[chain_id]:
                raise FirewallError(errors.NOT_ENABLED,
                                    "rule '%s' is not in '%s:%s:%s'" % \
                                    (args, ipv, table, chain))

            # get priority of rule
            priority = self._rules[chain_id][rule_id]

        # If a rule gets added, the initial rule index position within the
        # ipv, table and chain combination (chain_id) is 1.
        # Tf the chain_id exists in _rule_priority_positions, there are already
        # other rules for this chain_id. The number of rules for a priority
        # less or equal to the priority of the new rule will increase the
        # index of the new rule. The index is the ip*tables -I insert rule
        # number.
        #
        # Example: We have the following rules for chain_id (ipv4, filter,
        # INPUT) already:
        #   ipv4, filter, INPUT, 1, -i, foo1, -j, ACCEPT
        #   ipv4, filter, INPUT, 2, -i, foo2, -j, ACCEPT
        #   ipv4, filter, INPUT, 2, -i, foo2_1, -j, ACCEPT
        #   ipv4, filter, INPUT, 3, -i, foo3, -j, ACCEPT
        # This results in the following _rule_priority_positions structure:
        #   _rule_priority_positions[(ipv4,filter,INPUT)][1] = 1
        #   _rule_priority_positions[(ipv4,filter,INPUT)][2] = 2
        #   _rule_priority_positions[(ipv4,filter,INPUT)][3] = 1
        # The new rule
        #   ipv4, filter, INPUT, 2, -i, foo2_2, -j, ACCEPT
        # has the same pritority as the second rule before and will be added
        # right after it.
        # The initial index is 1 and the chain_id is already in
        # _rule_priority_positions. Therefore the index will increase for
        # the number of rules in every rule position in
        # _rule_priority_positions[(ipv4,filter,INPUT)].keys()
        # where position is smaller or equal to the entry in keys.
        # With the example from above:
        # The priority of the new rule is 2. Therefore for all keys in
        # _rule_priority_positions[chain_id] where priority is 1 or 2, the
        # number of the rules will increase the index of the rule.
        # For _rule_priority_positions[chain_id][1]: index += 1
        # _rule_priority_positions[chain_id][2]: index += 2
        # index will be 4 in the end and the rule in the table chain
        # combination will be added at index 4.
        # If there are no rules in the table chain combination, a new rule
        # has index 1.

        index = 1
        count = 0
        if chain_id in self._rule_priority_positions:
            positions = sorted(self._rule_priority_positions[chain_id].keys())
            j = 0
            while j < len(positions) and priority >= positions[j]:
                index += self._rule_priority_positions[chain_id][positions[j]]
                j += 1

        # split the direct rule in some cases as iptables-restore can't handle
        # compound args.
        #
        args_list = [list(args)]
        args_list = self.split_value(args_list, [ "-s", "--source" ])
        args_list = self.split_value(args_list, [ "-d", "--destination" ])

        for _args in args_list:
            transaction.add_rule(backend, backend.build_rule(enable, table, _chain, index, tuple(_args)))
            index += 1
            count += 1

        self._register_rule(rule_id, chain_id, priority, enable, count)
        transaction.add_fail(self._register_rule,
                             rule_id, chain_id, priority, not enable, count)

    def _chain(self, add, ipv, table, chain, transaction):
        self._check_ipv_table(ipv, table)
        self._check_builtin_chain(ipv, table, chain)
        table_id = (ipv, table)

        if add:
            if table_id in self._chains and \
                    chain in self._chains[table_id]:
                raise FirewallError(errors.ALREADY_ENABLED,
                                    "chain '%s' already is in '%s:%s'" % \
                                    (chain, ipv, table))
        else:
            if table_id not in self._chains or \
                    chain not in self._chains[table_id]:
                raise FirewallError(errors.NOT_ENABLED,
                                    "chain '%s' is not in '%s:%s'" % \
                                    (chain, ipv, table))

        backend = self._fw.get_direct_backend_by_ipv(ipv)
        transaction.add_rules(backend, backend.build_chain_rules(add, table, chain))

        self._register_chain(table_id, chain, add)
        transaction.add_fail(self._register_chain, table_id, chain, not add)

    def _passthrough(self, enable, ipv, args, transaction):
        self._check_ipv(ipv)

        tuple_args = tuple(args)
        if enable:
            if ipv in self._passthroughs and \
               tuple_args in self._passthroughs[ipv]:
                raise FirewallError(errors.ALREADY_ENABLED,
                                    "passthrough '%s', '%s'" % (ipv, args))
        else:
            if ipv not in self._passthroughs or \
               tuple_args not in self._passthroughs[ipv]:
                raise FirewallError(errors.NOT_ENABLED,
                                    "passthrough '%s', '%s'" % (ipv, args))

        backend = self._fw.get_direct_backend_by_ipv(ipv)

        if enable:
            backend.check_passthrough(args)
            # try to find out if a zone chain should be used
            if ipv in [ "ipv4", "ipv6" ]:
                table, chain = backend.passthrough_parse_table_chain(args)
                if table and chain:
                    self._fw.zone.create_zone_base_by_chain(ipv, table, chain)
            _args = args
        else:
            _args = backend.reverse_passthrough(args)

        transaction.add_rule(backend, _args)

        self._register_passthrough(ipv, tuple_args, enable)
        transaction.add_fail(self._register_passthrough, ipv, tuple_args,
                             not enable)
core/fw_transaction.py000064400000014246150351351730011101 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""Transaction classes for firewalld"""

__all__ = [ "FirewallTransaction" ]

import traceback

from firewall.core.logger import log
from firewall import errors
from firewall.errors import FirewallError

class FirewallTransaction(object):
    def __init__(self, fw):
        self.fw = fw
        self.rules = { } # [ ( backend.name, [ rule,.. ] ),.. ]
        self.pre_funcs = [ ] # [ (func, args),.. ]
        self.post_funcs = [ ] # [ (func, args),.. ]
        self.fail_funcs = [ ] # [ (func, args),.. ]
        self.modules = [ ] # [ module,.. ]

    def clear(self):
        self.rules.clear()
        del self.pre_funcs[:]
        del self.post_funcs[:]
        del self.fail_funcs[:]

    def add_rule(self, backend, rule):
        self.rules.setdefault(backend.name, [ ]).append(rule)

    def add_rules(self, backend, rules):
        for rule in rules:
            self.add_rule(backend, rule)

    def query_rule(self, backend, rule):
        return backend.name in self.rules and rule in self.rules[backend.name]

    def remove_rule(self, backend, rule):
        if backend.name in self.rules and rule in self.rules[backend.name]:
            self.rules[backend.name].remove(rule)

    def add_pre(self, func, *args):
        self.pre_funcs.append((func, args))

    def add_post(self, func, *args):
        self.post_funcs.append((func, args))

    def add_fail(self, func, *args):
        self.fail_funcs.append((func, args))

    def add_module(self, module):
        if module not in self.modules:
            self.modules.append(module)

    def remove_module(self, module):
        if module in self.modules:
            self.modules.remove(module)

    def add_modules(self, modules):
        for module in modules:
            self.add_module(module)

    def remove_modules(self, modules):
        for module in modules:
            self.remove_module(module)

    def prepare(self, enable):
        log.debug4("%s.prepare(%s, %s)" % (type(self), enable, "..."))

        rules = { }
        if not enable:
            # reverse rule order for cleanup
            for backend_name in self.rules:
                for rule in reversed(self.rules[backend_name]):
                    rules.setdefault(backend_name, [ ]).append(
                        self.fw.get_backend_by_name(backend_name).reverse_rule(rule))
        else:
            for backend_name in self.rules:
                rules.setdefault(backend_name, [ ]).extend(self.rules[backend_name])

        return rules, self.modules

    def execute(self, enable):
        log.debug4("%s.execute(%s)" % (type(self), enable))

        rules, modules = self.prepare(enable)

        # pre
        self.pre()

        # stage 1: apply rules
        error = False
        errorMsg = ""
        done = [ ]
        for backend_name in rules:
            try:
                self.fw.rules(backend_name, rules[backend_name])
            except Exception as msg:
                error = True
                errorMsg = msg
                log.debug1(traceback.format_exc())
                log.error(msg)
            else:
                done.append(backend_name)

        # stage 2: load modules
        if not error:
            module_return = self.fw.handle_modules(modules, enable)
            if module_return:
                # Debug log about issues loading modules, but don't error. The
                # modules may be builtin or CONFIG_MODULES=n, in which case
                # modprobe will fail. Or we may be running inside a container
                # that doesn't have sufficient privileges. Unfortunately there
                # is no way for us to know.
                (status, msg) = module_return
                if status:
                    log.debug1(msg)

        # error case: revert rules
        if error:
            undo_rules = { }
            for backend_name in done:
                undo_rules[backend_name] = [ ]
                for rule in reversed(rules[backend_name]):
                    undo_rules[backend_name].append(
                        self.fw.get_backend_by_name(backend_name).reverse_rule(rule))
            for backend_name in undo_rules:
                try:
                    self.fw.rules(backend_name, undo_rules[backend_name])
                except Exception as msg:
                    log.debug1(traceback.format_exc())
                    log.error(msg)
            # call failure functions
            for (func, args) in self.fail_funcs:
                try:
                    func(*args)
                except Exception as msg:
                    log.debug1(traceback.format_exc())
                    log.error("Calling fail func %s(%s) failed: %s" % \
                              (func, args, msg))

            raise FirewallError(errors.COMMAND_FAILED, errorMsg)

        # post
        self.post()

    def pre(self):
        log.debug4("%s.pre()" % type(self))

        for (func, args) in self.pre_funcs:
            try:
                func(*args)
            except Exception as msg:
                log.debug1(traceback.format_exc())
                log.error("Calling pre func %s(%s) failed: %s" % \
                          (func, args, msg))

    def post(self):
        log.debug4("%s.post()" % type(self))

        for (func, args) in self.post_funcs:
            try:
                func(*args)
            except Exception as msg:
                log.debug1(traceback.format_exc())
                log.error("Calling post func %s(%s) failed: %s" % \
                          (func, args, msg))
core/watcher.py000064400000006234150351351730007513 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2012-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "Watcher" ]

from gi.repository import Gio, GLib

class Watcher(object):
    def __init__(self, callback, timeout):
        self._callback = callback
        self._timeout = timeout
        self._monitors = { }
        self._timeouts = { }
        self._blocked = [ ]

    def add_watch_dir(self, directory):
        gfile = Gio.File.new_for_path(directory)
        self._monitors[directory] = gfile.monitor_directory(\
            Gio.FileMonitorFlags.NONE, None)
        self._monitors[directory].connect("changed", self._file_changed_cb)

    def add_watch_file(self, filename):
        gfile = Gio.File.new_for_path(filename)
        self._monitors[filename] = gfile.monitor_file(\
            Gio.FileMonitorFlags.NONE, None)
        self._monitors[filename].connect("changed", self._file_changed_cb)

    def get_watches(self):
        return self._monitors.keys()
        
    def has_watch(self, filename):
        return filename in self._monitors

    def remove_watch(self, filename):
        del self._monitors[filename]

    def block_source(self, filename):
        if filename not in self._blocked:
            self._blocked.append(filename)

    def unblock_source(self, filename):
        if filename in self._blocked:
            self._blocked.remove(filename)

    def clear_timeouts(self):
        for filename in list(self._timeouts.keys()):
            GLib.source_remove(self._timeouts[filename])
            del self._timeouts[filename]

    def _call_callback(self, filename):
        if filename not in self._blocked:
            self._callback(filename)
        del self._timeouts[filename]

    def _file_changed_cb(self, monitor, gio_file, gio_other_file, event):
        filename = gio_file.get_parse_name()
        if filename in self._blocked:
            if filename in self._timeouts:
                GLib.source_remove(self._timeouts[filename])
                del self._timeouts[filename]
            return

        if event == Gio.FileMonitorEvent.CHANGED or \
                event == Gio.FileMonitorEvent.CREATED or \
                event == Gio.FileMonitorEvent.DELETED or \
                event == Gio.FileMonitorEvent.ATTRIBUTE_CHANGED:
            if filename in self._timeouts:
                GLib.source_remove(self._timeouts[filename])
                del self._timeouts[filename]
            self._timeouts[filename] = GLib.timeout_add_seconds(\
                self._timeout, self._call_callback, filename)
core/fw_policies.py000064400000005363150351351730010363 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "FirewallPolicies" ]

from firewall import config
from firewall.core.logger import log
from firewall.core.io.lockdown_whitelist import LockdownWhitelist
from firewall import errors
from firewall.errors import FirewallError

class FirewallPolicies(object):
    def __init__(self):
        self._lockdown = False
        self.lockdown_whitelist = LockdownWhitelist(config.LOCKDOWN_WHITELIST)

    def __repr__(self):
        return '%s(%r, %r)' % (self.__class__, self._lockdown,
                                           self.lockdown_whitelist)

    def cleanup(self):
        self._lockdown = False
        self.lockdown_whitelist.cleanup()

    # lockdown

    def access_check(self, key, value):
        if key == "context":
            log.debug2('Doing access check for context "%s"' % value)
            if self.lockdown_whitelist.match_context(value):
                log.debug3('context matches.')
                return True
        elif key == "uid":
            log.debug2('Doing access check for uid %d' % value)
            if self.lockdown_whitelist.match_uid(value):
                log.debug3('uid matches.')
                return True
        elif key == "user":
            log.debug2('Doing access check for user "%s"' % value)
            if self.lockdown_whitelist.match_user(value):
                log.debug3('user matches.')
                return True
        elif key == "command":
            log.debug2('Doing access check for command "%s"' % value)
            if self.lockdown_whitelist.match_command(value):
                log.debug3('command matches.')
                return True
        return False

    def enable_lockdown(self):
        if self._lockdown:
            raise FirewallError(errors.ALREADY_ENABLED, "enable_lockdown()")
        self._lockdown = True

    def disable_lockdown(self):
        if not self._lockdown:
            raise FirewallError(errors.NOT_ENABLED, "disable_lockdown()")
        self._lockdown = False

    def query_lockdown(self):
        return self._lockdown

core/fw_nm.py000064400000016022150351351730007160 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""Functions for NetworkManager interaction"""

__all__ = [ "check_nm_imported", "nm_is_imported",
            "nm_get_zone_of_connection", "nm_set_zone_of_connection",
            "nm_get_connections", "nm_get_connection_of_interface",
            "nm_get_bus_name", "nm_get_dbus_interface" ]

import gi
from gi.repository import GLib
try:
    gi.require_version('NM', '1.0')
except ValueError:
    _nm_imported = False
else:
    try:
        from gi.repository import NM
        _nm_imported = True
    except (ImportError, ValueError, GLib.Error):
        _nm_imported = False
_nm_client = None

from firewall import errors
from firewall.errors import FirewallError
from firewall.core.logger import log
import dbus

def check_nm_imported():
    """Check function to raise a MISSING_IMPORT error if the import of NM failed
    """
    if not _nm_imported:
        raise FirewallError(errors.MISSING_IMPORT, "gi.repository.NM = 1.0")

def nm_is_imported():
    """Returns true if NM has been properly imported
    @return True if import was successful, False otherwirse
    """
    return _nm_imported

def nm_get_client():
    """Returns the NM client object or None if the import of NM failed
    @return NM.Client instance if import was successful, None otherwise
    """
    global _nm_client
    if not _nm_client:
        _nm_client = NM.Client.new(None)
    return _nm_client

def nm_get_zone_of_connection(connection):
    """Get zone of connection from NM
    @param connection name
    @return zone string setting of connection, empty string if not set, None if connection is unknown
    """
    check_nm_imported()

    con = nm_get_client().get_connection_by_uuid(connection)
    if con is None:
        return None

    setting_con = con.get_setting_connection()
    if setting_con is None:
        return None

    try:
        if con.get_flags() & (NM.SettingsConnectionFlags.NM_GENERATED
                              | NM.SettingsConnectionFlags.NM_VOLATILE):
            return ""
    except AttributeError:
        # Prior to NetworkManager 1.12, we can only guess
        # that a connection was generated/volatile.
        if con.get_unsaved():
            return ""

    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
    @param zone name
    @param connection name
    @return True if zone was set, else False
    """
    check_nm_imported()

    con = nm_get_client().get_connection_by_uuid(connection)
    if con is None:
        return False

    setting_con = con.get_setting_connection()
    if setting_con is None:
        return False

    if zone == "":
        zone = None
    setting_con.set_property("zone", zone)
    return con.commit_changes(True, None)

def nm_get_connections(connections, connections_name):
    """Get active connections from NM
    @param connections return dict
    @param connections_name return dict
    """

    connections.clear()
    connections_name.clear()

    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

        name = active_con.get_id()
        uuid = active_con.get_uuid()
        devices = active_con.get_devices()

        connections_name[uuid] = name
        for dev in devices:
            ip_iface = dev.get_ip_iface()
            if ip_iface:
                connections[ip_iface] = uuid

def nm_get_interfaces():
    """Get active interfaces from NM
    @returns list of interface names
    """

    check_nm_imported()

    active_interfaces = []

    for active_con in nm_get_client().get_active_connections():
        # ignore vpn devices for now
        if active_con.get_vpn():
            continue

        try:
            con = active_con.get_connection()
            if con.get_flags() & (NM.SettingsConnectionFlags.NM_GENERATED
                                  | NM.SettingsConnectionFlags.NM_VOLATILE):
                continue
        except AttributeError:
            # Prior to NetworkManager 1.12, we can only guess
            # that a connection was generated/volatile.
            if con.get_unsaved():
                continue

        for dev in active_con.get_devices():
            ip_iface = dev.get_ip_iface()
            if ip_iface:
                active_interfaces.append(ip_iface)

    return active_interfaces

def nm_get_interfaces_in_zone(zone):
    interfaces = []
    for interface in nm_get_interfaces():
        conn = nm_get_connection_of_interface(interface)
        if zone == nm_get_zone_of_connection(conn):
            interfaces.append(interface)

    return interfaces

def nm_get_device_by_ip_iface(interface):
    """Get device from NM which has the given IP interface
    @param interface name
    @returns NM.Device instance or None
    """
    check_nm_imported()

    for device in nm_get_client().get_devices():
        ip_iface = device.get_ip_iface()
        if ip_iface is None:
            continue
        if ip_iface == interface:
            return device

    return None

def nm_get_connection_of_interface(interface):
    """Get connection from NM that is using the interface
    @param interface name
    @returns connection that is using interface or None
    """
    check_nm_imported()

    device = nm_get_device_by_ip_iface(interface)
    if device is None:
        return None

    active_con = device.get_active_connection()
    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():
    if not _nm_imported:
        return None
    try:
        bus = dbus.SystemBus()
        obj = bus.get_object(NM.DBUS_INTERFACE, NM.DBUS_PATH)
        name = obj.bus_name
        del obj, bus
        return name
    except Exception:
        log.debug2("Failed to get bus name of NetworkManager")
    return None

def nm_get_dbus_interface():
    if not _nm_imported:
        return ""
    return NM.DBUS_INTERFACE
core/fw_icmptype.py000064400000004665150351351730010412 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "FirewallIcmpType" ]

from firewall.core.logger import log
from firewall import errors
from firewall.errors import FirewallError

class FirewallIcmpType(object):
    def __init__(self, fw):
        self._fw = fw
        self._icmptypes = { }

    def __repr__(self):
        return '%s(%r)' % (self.__class__, self._icmptypes)

    def cleanup(self):
        self._icmptypes.clear()

    # zones

    def get_icmptypes(self):
        return sorted(self._icmptypes.keys())

    def check_icmptype(self, icmptype):
        if icmptype not in self._icmptypes:
            raise FirewallError(errors.INVALID_ICMPTYPE, icmptype)

    def get_icmptype(self, icmptype):
        self.check_icmptype(icmptype)
        return self._icmptypes[icmptype]

    def add_icmptype(self, obj):
        orig_ipvs = obj.destination
        if len(orig_ipvs) == 0:
            orig_ipvs = [ "ipv4", "ipv6" ]
        for ipv in orig_ipvs:
            if ipv == "ipv4":
                if not self._fw.ip4tables_enabled and not self._fw.nftables_enabled:
                    continue
                supported_icmps = self._fw.ipv4_supported_icmp_types
            elif ipv == "ipv6":
                if not self._fw.ip6tables_enabled and not self._fw.nftables_enabled:
                    continue
                supported_icmps = self._fw.ipv6_supported_icmp_types
            else:
                supported_icmps = [ ]
            if obj.name.lower() not in supported_icmps:
                log.info1("ICMP type '%s' is not supported by the kernel for %s." % (obj.name, ipv))
        self._icmptypes[obj.name] = obj

    def remove_icmptype(self, icmptype):
        self.check_icmptype(icmptype)
        del self._icmptypes[icmptype]
core/icmp.py000064400000006035150351351730007005 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2017 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "ICMP_TYPES", "ICMPV6_TYPES",
            "check_icmp_type", "check_icmpv6_type" ]

ICMP_TYPES = {
     "echo-reply": "0/0",
     "pong": "0/0",
     "network-unreachable": "3/0",
     "host-unreachable": "3/1",
     "protocol-unreachable": "3/2",
     "port-unreachable": "3/3",
     "fragmentation-needed": "3/4",
     "source-route-failed": "3/5",
     "network-unknown": "3/6",
     "host-unknown": "3/7",
     "network-prohibited": "3/9",
     "host-prohibited": "3/10",
     "TOS-network-unreachable": "3/11",
     "TOS-host-unreachable": "3/12",
     "communication-prohibited": "3/13",
     "host-precedence-violation": "3/14",
     "precedence-cutoff": "3/15",
     "source-quench": "4/0",
     "network-redirect": "5/0",
     "host-redirect": "5/1",
     "TOS-network-redirect": "5/2",
     "TOS-host-redirect": "5/3",
     "echo-request": "8/0",
     "ping": "8/0",
     "router-advertisement": "9/0",
     "router-solicitation": "10/0",
     "ttl-zero-during-transit": "11/0",
     "ttl-zero-during-reassembly": "11/1",
     "ip-header-bad": "12/0",
     "required-option-missing": "12/1",
     "timestamp-request": "13/0",
     "timestamp-reply": "14/0",
     "address-mask-request": "17/0",
     "address-mask-reply": "18/0",
}

ICMPV6_TYPES = {
    "no-route": "1/0",
    "communication-prohibited": "1/1",
    "address-unreachable": "1/3",
    "port-unreachable": "1/4",
    "packet-too-big": "2/0",
    "ttl-zero-during-transit": "3/0",
    "ttl-zero-during-reassembly": "3/1",
    "bad-header": "4/0",
    "unknown-header-type": "4/1",
    "unknown-option": "4/2",
    "echo-request": "128/0",
    "ping": "128/0",
    "echo-reply": "129/0",
    "pong": "129/0",
    "router-solicitation": "133/0",
    "router-advertisement": "134/0",
    "neighbour-solicitation": "135/0",
    "neigbour-solicitation": "135/0",
    "neighbour-advertisement": "136/0",
    "neigbour-advertisement": "136/0",
    "redirect": "137/0",
}

def check_icmp_name(_name):
    if _name in ICMP_TYPES:
        return True
    return False

def check_icmp_type(_type):
    if _type in ICMP_TYPES.values():
        return True
    return False

def check_icmpv6_name(_name):
    if _name in ICMP_TYPES:
        return True
    return False

def check_icmpv6_type(_type):
    if _type in ICMPV6_TYPES.values():
        return True
    return False
core/fw.py000064400000142345150351351730006476 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

__all__ = [ "Firewall" ]

import os.path
import sys
import copy
import time
import traceback
from firewall import config
from firewall import functions
from firewall.core import ipXtables
from firewall.core import ebtables
from firewall.core import nftables
from firewall.core import ipset
from firewall.core import modules
from firewall.core.fw_icmptype import FirewallIcmpType
from firewall.core.fw_service import FirewallService
from firewall.core.fw_zone import FirewallZone
from firewall.core.fw_direct import FirewallDirect
from firewall.core.fw_config import FirewallConfig
from firewall.core.fw_policies import FirewallPolicies
from firewall.core.fw_ipset import FirewallIPSet
from firewall.core.fw_transaction import FirewallTransaction
from firewall.core.fw_helper import FirewallHelper
from firewall.core.fw_policy import FirewallPolicy
from firewall.core.fw_nm import nm_get_bus_name, nm_get_interfaces_in_zone
from firewall.core.logger import log
from firewall.core.io.firewalld_conf import firewalld_conf
from firewall.core.io.direct import Direct
from firewall.core.io.service import service_reader
from firewall.core.io.icmptype import icmptype_reader
from firewall.core.io.zone import zone_reader, Zone
from firewall.core.io.ipset import ipset_reader
from firewall.core.ipset import IPSET_TYPES
from firewall.core.io.helper import helper_reader
from firewall.core.io.policy import policy_reader
from firewall import errors
from firewall.errors import FirewallError

############################################################################
#
# class Firewall
#
############################################################################

class Firewall(object):
    def __init__(self, offline=False):
        self._firewalld_conf = firewalld_conf(config.FIREWALLD_CONF)
        self._offline = offline

        if self._offline:
            self.ip4tables_enabled = False
            self.ip6tables_enabled = False
            self.ebtables_enabled = False
            self.ipset_enabled = False
            self.ipset_supported_types = IPSET_TYPES
            self.nftables_enabled = False
        else:
            self.ip4tables_backend = ipXtables.ip4tables(self)
            self.ip4tables_enabled = True
            self.ipv4_supported_icmp_types = [ ]
            self.ip6tables_backend = ipXtables.ip6tables(self)
            self.ip6tables_enabled = True
            self.ipv6_supported_icmp_types = [ ]
            self.ebtables_backend = ebtables.ebtables()
            self.ebtables_enabled = True
            self.ipset_backend = ipset.ipset()
            self.ipset_enabled = True
            self.ipset_supported_types = [ ]
            self.nftables_backend = nftables.nftables(self)
            self.nftables_enabled = True

            self.modules_backend = modules.modules()

        self.icmptype = FirewallIcmpType(self)
        self.service = FirewallService(self)
        self.zone = FirewallZone(self)
        self.direct = FirewallDirect(self)
        self.config = FirewallConfig(self)
        self.policies = FirewallPolicies()
        self.ipset = FirewallIPSet(self)
        self.helper = FirewallHelper(self)
        self.policy = FirewallPolicy(self)

        self.__init_vars()

    def __repr__(self):
        return '%s(%r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r)' % \
            (self.__class__, self.ip4tables_enabled, self.ip6tables_enabled,
             self.ebtables_enabled, self._state, self._panic,
             self._default_zone, self._module_refcount, self._marks,
             self.cleanup_on_exit, self.cleanup_modules_on_exit,
             self.ipv6_rpfilter_enabled, self.ipset_enabled,
             self._individual_calls, self._log_denied)

    def __init_vars(self):
        self._state = "INIT"
        self._panic = False
        self._default_zone = ""
        self._module_refcount = { }
        self._marks = [ ]
        # fallback settings will be overloaded by firewalld.conf
        self.cleanup_on_exit = config.FALLBACK_CLEANUP_ON_EXIT
        self.cleanup_modules_on_exit = config.FALLBACK_CLEANUP_MODULES_ON_EXIT
        self.ipv6_rpfilter_enabled = config.FALLBACK_IPV6_RPFILTER
        self._individual_calls = config.FALLBACK_INDIVIDUAL_CALLS
        self._log_denied = config.FALLBACK_LOG_DENIED
        self._firewall_backend = config.FALLBACK_FIREWALL_BACKEND
        self._flush_all_on_reload = config.FALLBACK_FLUSH_ALL_ON_RELOAD
        self._rfc3964_ipv4 = config.FALLBACK_RFC3964_IPV4
        self._allow_zone_drifting = config.FALLBACK_ALLOW_ZONE_DRIFTING

    def _check_tables(self):
        # check if iptables, ip6tables and ebtables are usable, else disable
        if self.ip4tables_enabled and \
           "filter" not in self.ip4tables_backend.get_available_tables():
            log.info1("iptables is not usable.")
            self.ip4tables_enabled = False

        if self.ip6tables_enabled and \
           "filter" not in self.ip6tables_backend.get_available_tables():
            log.info1("ip6tables is not usable.")
            self.ip6tables_enabled = False

        if self.ebtables_enabled and \
           "filter" not in self.ebtables_backend.get_available_tables():
            log.info1("ebtables is not usable.")
            self.ebtables_enabled = False

        # is there at least support for ipv4 or ipv6
        if not self.ip4tables_enabled and not self.ip6tables_enabled \
           and not self.nftables_enabled:
            log.fatal("No IPv4 and IPv6 firewall.")
            sys.exit(1)

    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")

    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
                if value is not None and value.lower() in [ "no", "false" ]:
                    self.cleanup_modules_on_exit = False
                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
        if not reload:
            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))

    def start(self):
        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
        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)

    def cleanup(self):
        self.icmptype.cleanup()
        self.service.cleanup()
        self.zone.cleanup()
        self.ipset.cleanup()
        self.helper.cleanup()
        self.config.cleanup()
        self.direct.cleanup()
        self.policies.cleanup()
        self.policy.cleanup()
        self._firewalld_conf.cleanup()
        self.__init_vars()

    def stop(self):
        if not self._offline:
            if self.cleanup_on_exit:
                self.flush()
                self.ipset.flush()
                self.set_policy("ACCEPT")

            if self.cleanup_modules_on_exit:
                log.debug1('Unloading firewall kernel modules')
                self.modules_backend.unload_firewall_modules()

        self.cleanup()

    # handle modules

    def handle_modules(self, _modules, enable):
        num_failed = 0
        error_msgs = ""
        for i,module in enumerate(_modules):
            if enable:
                (status, msg) = self.modules_backend.load_module(module)
            else:
                if self._module_refcount[module] > 1:
                    status = 0 # module referenced more then one, do not unload
                else:
                    (status, msg) = self.modules_backend.unload_module(module)
            if status != 0:
                num_failed += 1
                error_msgs += msg
                continue

            if enable:
                self._module_refcount.setdefault(module, 0)
                self._module_refcount[module] += 1
            else:
                if module in self._module_refcount:
                    self._module_refcount[module] -= 1
                    if self._module_refcount[module] == 0:
                        del self._module_refcount[module]
        return (num_failed, error_msgs)

    def _select_firewall_backend(self, backend):
        if backend != "nftables":
            self.nftables_enabled = False
        # even if using nftables, the other backends are enabled for use with
        # the direct interface. nftables is used for the firewalld primitives.

    def get_backend_by_name(self, name):
        for backend in self.all_backends():
            if backend.name == name:
                return backend
        raise FirewallError(errors.UNKNOWN_ERROR,
                            "'%s' backend does not exist" % name)

    def get_backend_by_ipv(self, ipv):
        if self.nftables_enabled:
            return self.nftables_backend
        if ipv == "ipv4" and self.ip4tables_enabled:
            return self.ip4tables_backend
        elif ipv == "ipv6" and self.ip6tables_enabled:
            return self.ip6tables_backend
        elif ipv == "eb" and self.ebtables_enabled:
            return self.ebtables_backend
        raise FirewallError(errors.INVALID_IPV,
                            "'%s' is not a valid backend or is unavailable" % ipv)

    def get_direct_backend_by_ipv(self, ipv):
        if ipv == "ipv4" and self.ip4tables_enabled:
            return self.ip4tables_backend
        elif ipv == "ipv6" and self.ip6tables_enabled:
            return self.ip6tables_backend
        elif ipv == "eb" and self.ebtables_enabled:
            return self.ebtables_backend
        raise FirewallError(errors.INVALID_IPV,
                            "'%s' is not a valid backend or is unavailable" % ipv)

    def is_backend_enabled(self, name):
        if name == "ip4tables":
            return self.ip4tables_enabled
        elif name == "ip6tables":
            return self.ip6tables_enabled
        elif name == "ebtables":
            return self.ebtables_enabled
        elif name == "nftables":
            return self.nftables_enabled
        return False

    def is_ipv_enabled(self, ipv):
        if self.nftables_enabled:
            return True
        if ipv == "ipv4":
            return self.ip4tables_enabled
        elif ipv == "ipv6":
            return self.ip6tables_enabled
        elif ipv == "eb":
            return self.ebtables_enabled
        return False

    def enabled_backends(self):
        backends = []
        if self.nftables_enabled:
            backends.append(self.nftables_backend)
        else:
            if self.ip4tables_enabled:
                backends.append(self.ip4tables_backend)
            if self.ip6tables_enabled:
                backends.append(self.ip6tables_backend)
            if self.ebtables_enabled:
                backends.append(self.ebtables_backend)
        return backends

    def all_backends(self):
        backends = []
        if self.ip4tables_enabled:
            backends.append(self.ip4tables_backend)
        if self.ip6tables_enabled:
            backends.append(self.ip6tables_backend)
        if self.ebtables_enabled:
            backends.append(self.ebtables_backend)
        if self.nftables_enabled:
            backends.append(self.nftables_backend)
        return backends

    def apply_default_tables(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for backend in self.enabled_backends():
            transaction.add_rules(backend, backend.build_default_tables())

        if use_transaction is None:
            transaction.execute(True)

    def apply_default_rules(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for backend in self.enabled_backends():
            rules = backend.build_default_rules(self._log_denied)
            transaction.add_rules(backend, rules)

        if self.is_ipv_enabled("ipv6"):
            ipv6_backend = self.get_backend_by_ipv("ipv6")
            if "raw" in ipv6_backend.get_available_tables():
                if self.ipv6_rpfilter_enabled:
                    rules = ipv6_backend.build_rpfilter_rules(self._log_denied)
                    transaction.add_rules(ipv6_backend, rules)

        if self.is_ipv_enabled("ipv6") and self._rfc3964_ipv4:
            rules = ipv6_backend.build_rfc3964_ipv4_rules()
            transaction.add_rules(ipv6_backend, rules)

        if use_transaction is None:
            transaction.execute(True)

    def may_skip_flush_direct_backends(self):
        if self.nftables_enabled and not self.direct.has_runtime_configuration():
            return True

        return False

    def flush_direct_backends(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for backend in self.all_backends():
            if backend in self.enabled_backends():
                continue
            rules = backend.build_flush_rules()
            transaction.add_rules(backend, rules)

        if use_transaction is None:
            transaction.execute(True)

    def flush(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        log.debug1("Flushing rule set")

        if not self.may_skip_flush_direct_backends():
            self.flush_direct_backends(use_transaction=transaction)

        for backend in self.enabled_backends():
            rules = backend.build_flush_rules()
            transaction.add_rules(backend, rules)

        if use_transaction is None:
            transaction.execute(True)

    def set_policy(self, policy, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

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

        for backend in self.enabled_backends():
            rules = backend.build_set_policy_rules(policy)
            transaction.add_rules(backend, rules)

        if use_transaction is None:
            transaction.execute(True)

    # rule function used in handle_ functions

    def rule(self, backend_name, rule):
        if not rule:
            return ""

        backend = self.get_backend_by_name(backend_name)
        if not backend:
            raise FirewallError(errors.INVALID_IPV,
                                "'%s' is not a valid backend" % backend_name)

        if not self.is_backend_enabled(backend_name):
            return ""

        return backend.set_rule(rule, self._log_denied)

    def rules(self, backend_name, rules):
        _rules = list(filter(None, rules))

        backend = self.get_backend_by_name(backend_name)
        if not backend:
            raise FirewallError(errors.INVALID_IPV,
                                "'%s' is not a valid backend" % backend_name)

        if not self.is_backend_enabled(backend_name):
            return

        if self._individual_calls or \
           not backend.restore_command_exists or \
           (backend_name == "ebtables" and not self.ebtables_backend.restore_noflush_option):
            for i,rule in enumerate(_rules):
                try:
                    backend.set_rule(rule, self._log_denied)
                except Exception as msg:
                    log.debug1(traceback.format_exc())
                    log.error(msg)
                    for rule in reversed(_rules[:i]):
                        try:
                            backend.set_rule(backend.reverse_rule(rule), self._log_denied)
                        except Exception:
                            # ignore errors here
                            pass
                    raise msg
        else:
            backend.set_rules(_rules, self._log_denied)

    # check functions

    def check_panic(self):
        if self._panic:
            raise FirewallError(errors.PANIC_MODE)

    def check_policy(self, policy):
        _policy = policy
        if _policy not in self.policy.get_policies():
            raise FirewallError(errors.INVALID_POLICY, _policy)
        return _policy

    def check_zone(self, zone):
        _zone = zone
        if not _zone or _zone == "":
            _zone = self.get_default_zone()
        if _zone not in self.zone.get_zones():
            raise FirewallError(errors.INVALID_ZONE, _zone)
        return _zone

    def check_interface(self, interface):
        if not functions.checkInterface(interface):
            raise FirewallError(errors.INVALID_INTERFACE, interface)

    def check_service(self, service):
        self.service.check_service(service)

    def check_port(self, port):
        if not functions.check_port(port):
            raise FirewallError(errors.INVALID_PORT, port)

    def check_tcpudp(self, protocol):
        if not protocol:
            raise FirewallError(errors.MISSING_PROTOCOL)
        if protocol not in [ "tcp", "udp", "sctp", "dccp" ]:
            raise FirewallError(errors.INVALID_PROTOCOL,
                                "'%s' not in {'tcp'|'udp'|'sctp'|'dccp'}" % \
                                protocol)

    def check_ip(self, ip):
        if not functions.checkIP(ip):
            raise FirewallError(errors.INVALID_ADDR, ip)

    def check_address(self, ipv, source):
        if ipv == "ipv4":
            if not functions.checkIPnMask(source):
                raise FirewallError(errors.INVALID_ADDR, source)
        elif ipv == "ipv6":
            if not functions.checkIP6nMask(source):
                raise FirewallError(errors.INVALID_ADDR, source)
        else:
            raise FirewallError(errors.INVALID_IPV,
                                "'%s' not in {'ipv4'|'ipv6'}")

    def check_icmptype(self, icmp):
        self.icmptype.check_icmptype(icmp)

    def check_timeout(self, timeout):
        if not isinstance(timeout, int):
            raise TypeError("%s is %s, expected int" % (timeout, type(timeout)))
        if int(timeout) < 0:
            raise FirewallError(errors.INVALID_VALUE,
                                "timeout '%d' is not positive number" % timeout)

    # RELOAD

    def reload(self, stop=False):
        _panic = self._panic

        # must stash this. The value may change after _start()
        flush_all = self._flush_all_on_reload

        if not flush_all:
            # 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()

        _ipset_objs = []
        for _name in self.ipset.get_ipsets():
            _ipset_objs.append(self.ipset.get_ipset(_name))

        if not _panic:
            self.set_policy("DROP")

        self.flush()
        self.cleanup()

        start_exception = None
        try:
            self._start(reload=True, complete_reload=stop)
        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

        # destroy ipsets no longer in the permanent configuration
        if flush_all:
            for obj in _ipset_objs:
                if not self.ipset.query_ipset(obj.name):
                    for backend in self.ipset.backends():
                        # nftables sets are part of the normal firewall ruleset.
                        if backend.name == "nftables":
                            continue
                        backend.set_destroy(obj.name)

        if not flush_all:
            # 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:

                    for interface_id in _zone_interfaces[zone]:
                        self.zone.change_zone_of_interface(zone, interface_id,
                                                           _zone_interfaces[zone][interface_id]["sender"])

                    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 runtime-only ipsets
            for obj in _ipset_objs:
                if self.ipset.query_ipset(obj.name):
                    for entry in obj.entries:
                        try:
                            self.ipset.add_entry(obj.name, entry)
                        except FirewallError as msg:
                            if msg.code != errors.ALREADY_ENABLED:
                                raise msg
                else:
                    self.ipset.add_ipset(obj)
                    self.ipset.apply_ipset(obj.name)

            # restore direct config
            self.direct.set_config(_direct_config)

        # Restore permanent interfaces from NetworkManager
        nm_bus_name = nm_get_bus_name()
        if nm_bus_name:
            for zone in self.zone.get_zones() + [""]:
                for interface in nm_get_interfaces_in_zone(zone):
                    self.zone.change_zone_of_interface(zone, interface, sender=nm_bus_name)

        self._panic = _panic
        if not self._panic:
            self.set_policy("ACCEPT")

        if start_exception:
            self._state = "FAILED"
            raise start_exception
        else:
            self._state = "RUNNING"

    # STATE

    def get_state(self):
        return self._state

    # PANIC MODE

    def enable_panic_mode(self):
        if self._panic:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "panic mode already enabled")

        try:
            self.set_policy("PANIC")
        except Exception as msg:
            raise FirewallError(errors.COMMAND_FAILED, msg)
        self._panic = True

    def disable_panic_mode(self):
        if not self._panic:
            raise FirewallError(errors.NOT_ENABLED,
                                "panic mode is not enabled")

        try:
            self.set_policy("ACCEPT")
        except Exception as msg:
            raise FirewallError(errors.COMMAND_FAILED, msg)
        self._panic = False

    def query_panic_mode(self):
        return self._panic

    # LOG DENIED

    def get_log_denied(self):
        return self._log_denied

    def set_log_denied(self, value):
        if value not in config.LOG_DENIED_VALUES:
            raise FirewallError(errors.INVALID_VALUE,
                                "'%s', choose from '%s'" % \
                                (value, "','".join(config.LOG_DENIED_VALUES)))

        if value != self.get_log_denied():
            self._log_denied = value
            self._firewalld_conf.set("LogDenied", value)
            self._firewalld_conf.write()
        else:
            raise FirewallError(errors.ALREADY_SET, value)

    # DEFAULT ZONE

    def get_default_zone(self):
        return self._default_zone

    def set_default_zone(self, zone):
        _zone = self.check_zone(zone)
        if _zone != self._default_zone:
            _old_dz = self._default_zone
            self._default_zone = _zone
            self._firewalld_conf.set("DefaultZone", _zone)
            self._firewalld_conf.write()

            # remove old default zone from ZONES and add new default zone
            self.zone.change_default_zone(_old_dz, _zone)

            # Move interfaces from old default zone to the new one.
            _old_dz_settings = self.zone.get_settings(_old_dz)
            for iface, settings in list(_old_dz_settings["interfaces"].items()):
                if settings["__default__"]:
                    # move only those that were added to default zone
                    # (not those that were added to specific zone same as default)
                    self.zone.change_zone_of_interface("", iface)
        else:
            raise FirewallError(errors.ZONE_ALREADY_SET, _zone)

    def combine_runtime_with_permanent_settings(self, permanent, runtime):
        combined = permanent.copy()

        for key,value in runtime.items():
            # omit empty entries
            if value or isinstance(value, bool):
                combined[key] = value
            # make sure to remove values that were in permanent, but no
            # longer in runtime.
            elif key in combined:
                del combined[key]

        return combined

    def get_added_and_removed_settings(self, old_settings, new_settings):
        add_settings = {}
        remove_settings = {}
        for key in (set(old_settings.keys()) | set(new_settings.keys())):
            if key in new_settings:
                if isinstance(new_settings[key], list):
                    old = set(old_settings[key] if key in old_settings else [])
                    add_settings[key] = list(set(new_settings[key]) - old)
                    remove_settings[key] = list((old ^ set(new_settings[key])) & old)
                # check for bool or int because dbus.Boolean is a subclass of
                # int (because bool can't be subclassed).
                elif isinstance(new_settings[key], bool) or isinstance(new_settings[key], int):
                    if not old_settings[key] and new_settings[key]:
                        add_settings[key] = True
                    elif old_settings[key] and not new_settings[key]:
                        remove_settings[key] = False
                else:
                    raise FirewallError(errors.INVALID_SETTING, "Unhandled setting type {} key {}".format(type(new_settings[key]), key))

        return (add_settings, remove_settings)
core/fw_policy.py000064400000253075150351351730010060 0ustar00# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: GPL-2.0-or-later

import time
import copy
from firewall.core.logger import log
from firewall.functions import portStr, checkIPnMask, checkIP6nMask, \
    checkProtocol, enable_ip_forwarding, check_single_address, \
    portInPortRange, get_nf_conntrack_short_name, coalescePortRange, breakPortRange
from firewall.core.rich import Rich_Rule, Rich_Accept, \
    Rich_Service, Rich_Port, Rich_Protocol, \
    Rich_Masquerade, Rich_ForwardPort, Rich_SourcePort, Rich_IcmpBlock, \
    Rich_IcmpType, Rich_Mark
from firewall.core.fw_transaction import FirewallTransaction
from firewall import errors
from firewall.errors import FirewallError
from firewall.fw_types import LastUpdatedOrderedDict
from firewall.core.base import SOURCE_IPSET_TYPES

class FirewallPolicy(object):
    def __init__(self, fw):
        self._fw = fw
        self._chains = { }
        self._policies = { }

    def __repr__(self):
        return '%s(%r, %r)' % (self.__class__, self._chains, self._policies)

    def cleanup(self):
        self._chains.clear()
        self._policies.clear()

    # transaction

    def new_transaction(self):
        return FirewallTransaction(self._fw)

    # policies

    def get_policies(self):
        return sorted(self._policies.keys())

    def get_policies_not_derived_from_zone(self):
        policies = []
        for p in self.get_policies():
            p_obj = self.get_policy(p)
            if not p_obj.derived_from_zone:
                policies.append(p)
        return sorted(policies)

    def get_active_policies_not_derived_from_zone(self):
        active_policies = []
        for policy in self.get_policies_not_derived_from_zone():
            settings = self.get_settings(policy)
            if (set(settings["ingress_zones"]) & (set(self._fw.zone.get_active_zones()) | set(["HOST", "ANY"]))) and \
               (set(settings["egress_zones"]) & (set(self._fw.zone.get_active_zones()) | set(["HOST", "ANY"]))):
                active_policies.append(policy)

        return active_policies

    def get_policy(self, policy):
        p = self._fw.check_policy(policy)
        return self._policies[p]

    def add_policy(self, obj):
        obj.settings = { x : LastUpdatedOrderedDict()
                         for x in [ "services", "ports",
                                    "masquerade", "forward_ports",
                                    "source_ports",
                                    "icmp_blocks", "rules",
                                    "protocols", "icmp_block_inversion",
                                    "ingress_zones", "egress_zones" ] }

        self._policies[obj.name] = obj
        self.copy_permanent_to_runtime(obj.name)

    def remove_policy(self, policy):
        obj = self._policies[policy]
        if obj.applied:
            self.unapply_policy_settings(policy)
        obj.settings.clear()
        del self._policies[policy]

    def copy_permanent_to_runtime(self, policy):
        obj = self._policies[policy]

        if obj.applied:
            return

        for args in obj.ingress_zones:
            self.add_ingress_zone(policy, args, allow_apply=False)
        for args in obj.egress_zones:
            self.add_egress_zone(policy, args, allow_apply=False)
        for args in obj.icmp_blocks:
            self.add_icmp_block(policy, args)
        for args in obj.forward_ports:
            self.add_forward_port(policy, *args)
        for args in obj.services:
            self.add_service(policy, args)
        for args in obj.ports:
            try:
                self.add_port(policy, *args)
            except FirewallError as error:
                if error.code in [errors.ALREADY_ENABLED]:
                    log.warning(error)
                else:
                    raise error
        for args in obj.protocols:
            self.add_protocol(policy, args)
        for args in obj.source_ports:
            try:
                self.add_source_port(policy, *args)
            except FirewallError as error:
                if error.code in [errors.ALREADY_ENABLED]:
                    log.warning(error)
                else:
                    raise error
        for args in obj.rules:
            self.add_rule(policy, args)
        if obj.masquerade:
            self.add_masquerade(policy)

    def apply_policies(self, use_transaction=None):
        for policy in self.get_policies():
            p_obj = self._policies[policy]
            if p_obj.derived_from_zone:
                continue
            if policy in self.get_active_policies_not_derived_from_zone():
                log.debug1("Applying policy '%s'", policy)
                self.apply_policy_settings(policy, use_transaction=use_transaction)

    def set_policy_applied(self, policy, applied):
        obj = self._policies[policy]
        obj.applied = applied

    # settings

    # generate settings record with sender, timeout
    def __gen_settings(self, timeout, sender):
        ret = {
            "date": time.time(),
            "sender": sender,
            "timeout": timeout,
        }
        return ret

    def get_settings(self, policy):
        return self.get_policy(policy).settings

    def _policy_settings(self, enable, policy, use_transaction=None):
        _policy = self._fw.check_policy(policy)
        obj = self._policies[_policy]
        if (enable and obj.applied) or (not enable and not obj.applied):
            return
        if enable:
            obj.applied = True

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if enable:
            # build the base chain layout of the policy
            for (table, chain) in self._get_table_chains_for_policy_dispatch(policy) if not obj.derived_from_zone \
                             else self._get_table_chains_for_zone_dispatch(policy):
                self.gen_chain_rules(policy, True, table, chain, transaction)

        settings = self.get_settings(policy)
        if not obj.derived_from_zone:
            self._ingress_egress_zones(enable, _policy, transaction)
        for key in settings:
            for args in settings[key]:
                if key == "icmp_blocks":
                    self._icmp_block(enable, _policy, args, transaction)
                elif key == "icmp_block_inversion":
                    continue
                elif key == "forward_ports":
                    self._forward_port(enable, _policy, transaction,
                                       *args)
                elif key == "services":
                    self._service(enable, _policy, args, transaction)
                elif key == "ports":
                    self._port(enable, _policy, args[0], args[1],
                                transaction)
                elif key == "protocols":
                    self._protocol(enable, _policy, args, transaction)
                elif key == "source_ports":
                    self._source_port(enable, _policy, args[0], args[1],
                                       transaction)
                elif key == "masquerade":
                    self._masquerade(enable, _policy, transaction)
                elif key == "rules":
                    self.__rule(enable, _policy, Rich_Rule(rule_str=args),
                                transaction)
                elif key == "ingress_zones":
                    continue
                elif key == "egress_zones":
                    continue
                else:
                    log.warning("Policy '%s': Unknown setting '%s:%s', "
                                "unable to apply", policy, key, args)

        if not enable:
            for (table, chain) in self._get_table_chains_for_policy_dispatch(policy) if not obj.derived_from_zone \
                             else self._get_table_chains_for_zone_dispatch(policy):
                self.gen_chain_rules(policy, False, table, chain, transaction)
            obj.applied = False

        if use_transaction is None:
            transaction.execute(enable)

    def apply_policy_settings(self, policy, use_transaction=None):
        self._policy_settings(True, policy, use_transaction=use_transaction)

    def unapply_policy_settings(self, policy, use_transaction=None):
        self._policy_settings(False, policy, use_transaction=use_transaction)

    def get_config_with_settings_dict(self, policy):
        """
        :return: exported config updated with runtime settings
        """
        permanent = self.get_policy(policy).export_config_dict()
        runtime = { "services": self.list_services(policy),
                    "ports": self.list_ports(policy),
                    "icmp_blocks": self.list_icmp_blocks(policy),
                    "masquerade": self.query_masquerade(policy),
                    "forward_ports": self.list_forward_ports(policy),
                    "rich_rules": self.list_rules(policy),
                    "protocols": self.list_protocols(policy),
                    "source_ports": self.list_source_ports(policy),
                    "ingress_zones": self.list_ingress_zones(policy),
                    "egress_zones": self.list_egress_zones(policy),
                    }
        return self._fw.combine_runtime_with_permanent_settings(permanent, runtime)

    def set_config_with_settings_dict(self, policy, settings, sender):
        # stupid wrappers to convert rich rule string to rich rule object
        from firewall.core.rich import Rich_Rule
        def add_rule_wrapper(policy, rule_str, timeout=0, sender=None):
            self.add_rule(policy, Rich_Rule(rule_str=rule_str), timeout=0, sender=sender)
        def remove_rule_wrapper(policy, rule_str):
            self.remove_rule(policy, Rich_Rule(rule_str=rule_str))

        setting_to_fn = {
            "services": (self.add_service, self.remove_service),
            "ports": (self.add_port, self.remove_port),
            "icmp_blocks": (self.add_icmp_block, self.remove_icmp_block),
            "masquerade": (self.add_masquerade, self.remove_masquerade),
            "forward_ports": (self.add_forward_port, self.remove_forward_port),
            "rich_rules": (add_rule_wrapper, remove_rule_wrapper),
            "protocols": (self.add_protocol, self.remove_protocol),
            "source_ports": (self.add_source_port, self.remove_source_port),
            "ingress_zones": (self.add_ingress_zone, self.remove_ingress_zone),
            "egress_zones": (self.add_egress_zone, self.remove_egress_zone),
        }

        old_settings = self.get_config_with_settings_dict(policy)
        (add_settings, remove_settings) = self._fw.get_added_and_removed_settings(old_settings, settings)

        for key in remove_settings:
            if isinstance(remove_settings[key], list):
                for args in remove_settings[key]:
                    if isinstance(args, tuple):
                        setting_to_fn[key][1](policy, *args)
                    else:
                        setting_to_fn[key][1](policy, args)
            else: # bool
                setting_to_fn[key][1](policy)

        for key in add_settings:
            if isinstance(add_settings[key], list):
                for args in add_settings[key]:
                    if isinstance(args, tuple):
                        setting_to_fn[key][0](policy, *args, timeout=0, sender=sender)
                    else:
                        setting_to_fn[key][0](policy, args, timeout=0, sender=sender)
            else: # bool
                setting_to_fn[key][0](policy, timeout=0, sender=sender)

    # ingress zones

    def check_ingress_zone(self, zone):
        if not zone:
            raise FirewallError(errors.INVALID_ZONE)
        if zone not in ["HOST", "ANY"]:
            self._fw.check_zone(zone)

    def __ingress_zone_id(self, zone):
        self.check_ingress_zone(zone)
        return zone

    def add_ingress_zone(self, policy, zone, timeout=0, sender=None,
                         use_transaction=None, allow_apply=True):
        _policy = self._fw.check_policy(policy)
        self._fw.check_timeout(timeout)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        zone_id = self.__ingress_zone_id(zone)
        if zone_id in _obj.settings["ingress_zones"]:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s' already in '%s'" % (zone, _policy))

        if "ANY" in _obj.settings["ingress_zones"] or "HOST" in _obj.settings["ingress_zones"] or \
           zone in ["ANY", "HOST"] and _obj.settings["ingress_zones"]:
            raise FirewallError(errors.INVALID_ZONE, "'ingress-zones' may only contain one of: many regular zones, ANY, or HOST")

        if zone == "HOST" and "HOST" in _obj.settings["egress_zones"]:
            raise FirewallError(errors.INVALID_ZONE, "'HOST' can only appear in either ingress or egress zones, but not both")

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if allow_apply:
            if _obj.applied:
                self._ingress_egress_zones(False, _policy, transaction)

            # register early so backends can access updated zone list
            self.__register_ingress_zone(_obj, zone_id, timeout, sender)
            transaction.add_fail(self.__unregister_ingress_zone, _obj, zone_id)

            if not _obj.applied:
                if _policy in self.get_active_policies_not_derived_from_zone():
                    self.apply_policy_settings(_policy, use_transaction=transaction)
                    transaction.add_fail(self.set_policy_applied, _policy, False)
            else:
                self._ingress_egress_zones(True, _policy, transaction)
        else:
            self.__register_ingress_zone(_obj, zone_id, timeout, sender)
            transaction.add_fail(self.__unregister_ingress_zone, _obj, zone_id)

        if use_transaction is None:
            transaction.execute(True)

    def __register_ingress_zone(self, _obj, zone_id, timeout, sender):
        _obj.settings["ingress_zones"][zone_id] = self.__gen_settings(timeout, sender)

    def remove_ingress_zone(self, policy, zone, use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        zone_id = self.__ingress_zone_id(zone)
        if zone_id not in _obj.settings["ingress_zones"]:
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s' not in '%s'" % (zone, _policy))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            if len(_obj.settings["ingress_zones"]) == 1:
                self.unapply_policy_settings(_policy, transaction)
            else:
                self._ingress_egress_zones(False, _policy, transaction)

            # unregister early so backends have updated zone list
            self.__unregister_ingress_zone(_obj, zone_id)
            transaction.add_fail(self.__register_ingress_zone, _obj, zone_id, None, None)

            if _policy in self.get_active_policies_not_derived_from_zone():
                self._ingress_egress_zones(True, _policy, transaction)
        else:
            transaction.add_post(self.__unregister_ingress_zone, _obj, zone_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __unregister_ingress_zone(self, _obj, zone_id):
        if zone_id in _obj.settings["ingress_zones"]:
            del _obj.settings["ingress_zones"][zone_id]

    def query_ingress_zone(self, policy, zone):
        return self.__ingress_zone_id(zone) in self.get_settings(policy)["ingress_zones"]

    def list_ingress_zones(self, policy):
        return list(self.get_settings(policy)["ingress_zones"].keys())

    # egress zones

    def check_egress_zone(self, zone):
        if not zone:
            raise FirewallError(errors.INVALID_ZONE)
        if zone not in ["HOST", "ANY"]:
            self._fw.check_zone(zone)

    def __egress_zone_id(self, zone):
        self.check_egress_zone(zone)
        return zone

    def add_egress_zone(self, policy, zone, timeout=0, sender=None,
                         use_transaction=None, allow_apply=True):
        _policy = self._fw.check_policy(policy)
        self._fw.check_timeout(timeout)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        zone_id = self.__egress_zone_id(zone)
        if zone_id in _obj.settings["egress_zones"]:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s' already in '%s'" % (zone, _policy))

        if "ANY" in _obj.settings["egress_zones"] or "HOST" in _obj.settings["egress_zones"] or \
           zone in ["ANY", "HOST"] and _obj.settings["egress_zones"]:
            raise FirewallError(errors.INVALID_ZONE, "'egress-zones' may only contain one of: many regular zones, ANY, or HOST")

        if zone == "HOST" and "HOST" in _obj.settings["ingress_zones"]:
            raise FirewallError(errors.INVALID_ZONE, "'HOST' can only appear in either ingress or egress zones, but not both")

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if allow_apply:
            if _obj.applied:
                self._ingress_egress_zones(False, _policy, transaction)

            # register early so backends can access updated zone list
            self.__register_egress_zone(_obj, zone_id, timeout, sender)
            transaction.add_fail(self.__unregister_egress_zone, _obj, zone_id)

            if not _obj.applied:
                if _policy in self.get_active_policies_not_derived_from_zone():
                    self.apply_policy_settings(_policy, use_transaction=transaction)
                    transaction.add_fail(self.set_policy_applied, _policy, False)
            else:
                self._ingress_egress_zones(True, _policy, transaction)
        else:
            self.__register_egress_zone(_obj, zone_id, timeout, sender)
            transaction.add_fail(self.__unregister_egress_zone, _obj, zone_id)

        if use_transaction is None:
            transaction.execute(True)

    def __register_egress_zone(self, _obj, zone_id, timeout, sender):
        _obj.settings["egress_zones"][zone_id] = self.__gen_settings(timeout, sender)

    def remove_egress_zone(self, policy, zone, use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        zone_id = self.__egress_zone_id(zone)
        if zone_id not in _obj.settings["egress_zones"]:
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s' not in '%s'" % (zone, _policy))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            if len(_obj.settings["egress_zones"]) == 1:
                self.unapply_policy_settings(_policy, transaction)
            else:
                self._ingress_egress_zones(False, _policy, transaction)

            # unregister early so backends have updated zone list
            self.__unregister_egress_zone(_obj, zone_id)
            transaction.add_fail(self.__register_egress_zone, _obj, zone_id, None, None)

            if _policy in self.get_active_policies_not_derived_from_zone():
                self._ingress_egress_zones(True, _policy, transaction)
        else:
            transaction.add_post(self.__unregister_egress_zone, _obj, zone_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __unregister_egress_zone(self, _obj, zone_id):
        if zone_id in _obj.settings["egress_zones"]:
            del _obj.settings["egress_zones"][zone_id]

    def query_egress_zone(self, policy, zone):
        return self.__egress_zone_id(zone) in self.get_settings(policy)["egress_zones"]

    def list_egress_zones(self, policy):
        return list(self.get_settings(policy)["egress_zones"].keys())

    # RICH LANGUAGE

    def check_rule(self, rule):
        rule.check()

    def __rule_id(self, rule):
        self.check_rule(rule)
        return str(rule)

    def _rule_source_ipv(self, source):
        if not source:
            return None

        if source.addr:
            if checkIPnMask(source.addr):
                return "ipv4"
            elif checkIP6nMask(source.addr):
                return "ipv6"
        elif hasattr(source, "mac") and source.mac:
            return ""
        elif hasattr(source, "ipset") and source.ipset:
            self._check_ipset_type_for_source(source.ipset)
            self._check_ipset_applied(source.ipset)
            return self._ipset_family(source.ipset)

        return None

    def __rule(self, enable, policy, rule, transaction):
        self._rule_prepare(enable, policy, rule, transaction)

    def add_rule(self, policy, rule, timeout=0, sender=None,
                 use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_timeout(timeout)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        rule_id = self.__rule_id(rule)
        if rule_id in _obj.settings["rules"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s' already in '%s'" % (rule, _name))

        if not _obj.derived_from_zone:
            if rule.element and isinstance(rule.element, Rich_Masquerade):
                if "HOST" in _obj.settings["egress_zones"]:
                    raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for egress zone 'HOST'")
                if "HOST" in _obj.settings["ingress_zones"]:
                    raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for ingress zone 'HOST'")
                for zone in _obj.settings["ingress_zones"]:
                    if zone == "ANY":
                        continue
                    if self._fw.zone.list_interfaces(zone):
                        raise FirewallError(errors.INVALID_ZONE, "'masquerade' cannot be used in a policy if an ingress zone has assigned interfaces")
            if rule.element and isinstance(rule.element, Rich_ForwardPort):
                if "HOST" in _obj.settings["egress_zones"]:
                    if rule.element.to_address:
                        raise FirewallError(errors.INVALID_FORWARD, "A 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'")
                elif _obj.settings["egress_zones"]:
                    if not rule.element.to_address:
                        raise FirewallError(errors.INVALID_FORWARD, "'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zone")
                    for zone in _obj.settings["egress_zones"]:
                        if zone == "ANY":
                            continue
                        if self._fw.zone.list_interfaces(zone):
                            raise FirewallError(errors.INVALID_ZONE, "'forward-port' cannot be used in a policy if an egress zone has assigned interfaces")
            if rule.action and isinstance(rule.action, Rich_Mark):
                for zone in _obj.settings["egress_zones"]:
                    if zone in ["ANY", "HOST"]:
                        continue
                    if self._fw.zone.list_interfaces(zone):
                        raise FirewallError(errors.INVALID_ZONE, "'mark' action cannot be used in a policy if an egress zone has assigned interfaces")

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self.__rule(True, _policy, rule, transaction)

        self.__register_rule(_obj, rule_id, timeout, sender)
        transaction.add_fail(self.__unregister_rule, _obj, rule_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __register_rule(self, _obj, rule_id, timeout, sender):
        _obj.settings["rules"][rule_id] = self.__gen_settings(
            timeout, sender)

    def remove_rule(self, policy, rule,
                    use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        rule_id = self.__rule_id(rule)
        if rule_id not in _obj.settings["rules"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s' not in '%s'" % (rule, _name))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self.__rule(False, _policy, rule, transaction)

        transaction.add_post(self.__unregister_rule, _obj, rule_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __unregister_rule(self, _obj, rule_id):
        if rule_id in _obj.settings["rules"]:
            del _obj.settings["rules"][rule_id]

    def query_rule(self, policy, rule):
        return self.__rule_id(rule) in self.get_settings(policy)["rules"]

    def list_rules(self, policy):
        return list(self.get_settings(policy)["rules"].keys())

    # SERVICES

    def check_service(self, service):
        self._fw.check_service(service)

    def __service_id(self, service):
        self.check_service(service)
        return service

    def add_service(self, policy, service, timeout=0, sender=None,
                    use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_timeout(timeout)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        service_id = self.__service_id(service)
        if service_id in _obj.settings["services"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s' already in '%s'" % (service, _name))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._service(True, _policy, service, transaction)

        self.__register_service(_obj, service_id, timeout, sender)
        transaction.add_fail(self.__unregister_service, _obj, service_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __register_service(self, _obj, service_id, timeout, sender):
        _obj.settings["services"][service_id] = \
            self.__gen_settings(timeout, sender)

    def remove_service(self, policy, service,
                       use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        service_id = self.__service_id(service)
        if service_id not in _obj.settings["services"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s' not in '%s'" % (service, _name))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._service(False, _policy, service, transaction)

        transaction.add_post(self.__unregister_service, _obj, service_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __unregister_service(self, _obj, service_id):
        if service_id in _obj.settings["services"]:
            del _obj.settings["services"][service_id]

    def query_service(self, policy, service):
        return self.__service_id(service) in self.get_settings(policy)["services"]

    def list_services(self, policy):
        return self.get_settings(policy)["services"].keys()

    def get_helpers_for_service_helpers(self, helpers):
        _helpers = [ ]
        for helper in helpers:
            try:
                _helper = self._fw.helper.get_helper(helper)
            except FirewallError:
                raise FirewallError(errors.INVALID_HELPER, helper)
            _helpers.append(_helper)
        return _helpers

    def get_helpers_for_service_modules(self, modules, enable):
        # If automatic helper assignment is turned off, helpers that
        # do not have ports defined will be replaced by the helpers
        # that the helper.module defines.
        _helpers = [ ]
        for module in modules:
            try:
                helper = self._fw.helper.get_helper(module)
            except FirewallError:
                raise FirewallError(errors.INVALID_HELPER, module)
            if len(helper.ports) < 1:
                _module_short_name = get_nf_conntrack_short_name(helper.module)
                try:
                    _helper = self._fw.helper.get_helper(_module_short_name)
                    _helpers.append(_helper)
                except FirewallError:
                    if enable:
                        log.warning("Helper '%s' is not available" % _module_short_name)
                    continue
            else:
                _helpers.append(helper)
        return _helpers

    # PORTS

    def check_port(self, port, protocol):
        self._fw.check_port(port)
        self._fw.check_tcpudp(protocol)

    def __port_id(self, port, protocol):
        self.check_port(port, protocol)
        return (portStr(port, "-"), protocol)

    def add_port(self, policy, port, protocol, timeout=0, sender=None,
                 use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_timeout(timeout)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        existing_port_ids = list(filter(lambda x: x[1] == protocol, _obj.settings["ports"]))
        for port_id in existing_port_ids:
            if portInPortRange(port, port_id[0]):
                _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
                raise FirewallError(errors.ALREADY_ENABLED,
                                    "'%s:%s' already in '%s'" % (port, protocol, _name))

        added_ranges, removed_ranges = coalescePortRange(port, [_port for (_port, _protocol) in existing_port_ids])

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            for range in added_ranges:
                self._port(True, _policy, portStr(range, "-"), protocol, transaction)
            for range in removed_ranges:
                self._port(False, _policy, portStr(range, "-"), protocol, transaction)

        for range in added_ranges:
            port_id = self.__port_id(range, protocol)
            self.__register_port(_obj, port_id, timeout, sender)
            transaction.add_fail(self.__unregister_port, _obj, port_id)
        for range in removed_ranges:
            port_id = self.__port_id(range, protocol)
            transaction.add_post(self.__unregister_port, _obj, port_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __register_port(self, _obj, port_id, timeout, sender):
        _obj.settings["ports"][port_id] = \
            self.__gen_settings(timeout, sender)

    def remove_port(self, policy, port, protocol,
                    use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        existing_port_ids = list(filter(lambda x: x[1] == protocol, _obj.settings["ports"]))
        for port_id in existing_port_ids:
            if portInPortRange(port, port_id[0]):
                break
        else:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s:%s' not in '%s'" % (port, protocol, _name))

        added_ranges, removed_ranges = breakPortRange(port, [_port for (_port, _protocol) in existing_port_ids])

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            for range in added_ranges:
                self._port(True, _policy, portStr(range, "-"), protocol, transaction)
            for range in removed_ranges:
                self._port(False, _policy, portStr(range, "-"), protocol, transaction)

        for range in added_ranges:
            port_id = self.__port_id(range, protocol)
            self.__register_port(_obj, port_id, 0, None)
            transaction.add_fail(self.__unregister_port, _obj, port_id)
        for range in removed_ranges:
            port_id = self.__port_id(range, protocol)
            transaction.add_post(self.__unregister_port, _obj, port_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __unregister_port(self, _obj, port_id):
        if port_id in _obj.settings["ports"]:
            del _obj.settings["ports"][port_id]

    def query_port(self, policy, port, protocol):
        for (_port, _protocol) in self.get_settings(policy)["ports"]:
            if portInPortRange(port, _port) and protocol == _protocol:
                return True

        return False

    def list_ports(self, policy):
        return list(self.get_settings(policy)["ports"].keys())

    # PROTOCOLS

    def check_protocol(self, protocol):
        if not checkProtocol(protocol):
            raise FirewallError(errors.INVALID_PROTOCOL, protocol)

    def __protocol_id(self, protocol):
        self.check_protocol(protocol)
        return protocol

    def add_protocol(self, policy, protocol, timeout=0, sender=None,
                     use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_timeout(timeout)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        protocol_id = self.__protocol_id(protocol)
        if protocol_id in _obj.settings["protocols"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s' already in '%s'" % (protocol, _name))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._protocol(True, _policy, protocol, transaction)

        self.__register_protocol(_obj, protocol_id, timeout, sender)
        transaction.add_fail(self.__unregister_protocol, _obj, protocol_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __register_protocol(self, _obj, protocol_id, timeout, sender):
        _obj.settings["protocols"][protocol_id] = \
            self.__gen_settings(timeout, sender)

    def remove_protocol(self, policy, protocol,
                        use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        protocol_id = self.__protocol_id(protocol)
        if protocol_id not in _obj.settings["protocols"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s' not in '%s'" % (protocol, _name))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._protocol(False, _policy, protocol, transaction)

        transaction.add_post(self.__unregister_protocol, _obj,
                                  protocol_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __unregister_protocol(self, _obj, protocol_id):
        if protocol_id in _obj.settings["protocols"]:
            del _obj.settings["protocols"][protocol_id]

    def query_protocol(self, policy, protocol):
        return self.__protocol_id(protocol) in self.get_settings(policy)["protocols"]

    def list_protocols(self, policy):
        return list(self.get_settings(policy)["protocols"].keys())

    # SOURCE PORTS

    def __source_port_id(self, port, protocol):
        self.check_port(port, protocol)
        return (portStr(port, "-"), protocol)

    def add_source_port(self, policy, port, protocol, timeout=0, sender=None,
                        use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_timeout(timeout)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        existing_port_ids = list(filter(lambda x: x[1] == protocol, _obj.settings["source_ports"]))
        for port_id in existing_port_ids:
            if portInPortRange(port, port_id[0]):
                _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
                raise FirewallError(errors.ALREADY_ENABLED,
                                    "'%s:%s' already in '%s'" % (port, protocol, _name))

        added_ranges, removed_ranges = coalescePortRange(port, [_port for (_port, _protocol) in existing_port_ids])

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            for range in added_ranges:
                self._source_port(True, _policy, portStr(range, "-"), protocol, transaction)
            for range in removed_ranges:
                self._source_port(False, _policy, portStr(range, "-"), protocol, transaction)

        for range in added_ranges:
            port_id = self.__source_port_id(range, protocol)
            self.__register_source_port(_obj, port_id, timeout, sender)
            transaction.add_fail(self.__unregister_source_port, _obj, port_id)
        for range in removed_ranges:
            port_id = self.__source_port_id(range, protocol)
            transaction.add_post(self.__unregister_source_port, _obj, port_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __register_source_port(self, _obj, port_id, timeout, sender):
        _obj.settings["source_ports"][port_id] = \
            self.__gen_settings(timeout, sender)

    def remove_source_port(self, policy, port, protocol,
                           use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        existing_port_ids = list(filter(lambda x: x[1] == protocol, _obj.settings["source_ports"]))
        for port_id in existing_port_ids:
            if portInPortRange(port, port_id[0]):
                break
        else:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s:%s' not in '%s'" % (port, protocol, _name))

        added_ranges, removed_ranges = breakPortRange(port, [_port for (_port, _protocol) in existing_port_ids])

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            for range in added_ranges:
                self._source_port(True, _policy, portStr(range, "-"), protocol, transaction)
            for range in removed_ranges:
                self._source_port(False, _policy, portStr(range, "-"), protocol, transaction)

        for range in added_ranges:
            port_id = self.__source_port_id(range, protocol)
            self.__register_source_port(_obj, port_id, 0, None)
            transaction.add_fail(self.__unregister_source_port, _obj, port_id)
        for range in removed_ranges:
            port_id = self.__source_port_id(range, protocol)
            transaction.add_post(self.__unregister_source_port, _obj, port_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __unregister_source_port(self, _obj, port_id):
        if port_id in _obj.settings["source_ports"]:
            del _obj.settings["source_ports"][port_id]

    def query_source_port(self, policy, port, protocol):
        for (_port, _protocol) in self.get_settings(policy)["source_ports"]:
            if portInPortRange(port, _port) and protocol == _protocol:
                return True

        return False

    def list_source_ports(self, policy):
        return list(self.get_settings(policy)["source_ports"].keys())

    # MASQUERADE

    def __masquerade_id(self):
        return True

    def add_masquerade(self, policy, timeout=0, sender=None,
                       use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_timeout(timeout)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        masquerade_id = self.__masquerade_id()
        if masquerade_id in _obj.settings["masquerade"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.ALREADY_ENABLED,
                                "masquerade already enabled in '%s'" % _name)

        if not _obj.derived_from_zone:
            if "HOST" in _obj.settings["egress_zones"]:
                raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for egress zone 'HOST'")
            if "HOST" in _obj.settings["ingress_zones"]:
                raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for ingress zone 'HOST'")
            for zone in _obj.settings["ingress_zones"]:
                if zone == "ANY":
                    continue
                if self._fw.zone.list_interfaces(zone):
                    raise FirewallError(errors.INVALID_ZONE, "'masquerade' cannot be used in a policy if an ingress zone has assigned interfaces")

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._masquerade(True, _policy, transaction)

        self.__register_masquerade(_obj, masquerade_id, timeout, sender)
        transaction.add_fail(self.__unregister_masquerade, _obj, masquerade_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __register_masquerade(self, _obj, masquerade_id, timeout, sender):
        _obj.settings["masquerade"][masquerade_id] = \
            self.__gen_settings(timeout, sender)

    def remove_masquerade(self, policy, use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        masquerade_id = self.__masquerade_id()
        if masquerade_id not in _obj.settings["masquerade"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.NOT_ENABLED,
                                "masquerade not enabled in '%s'" % _name)

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._masquerade(False, _policy, transaction)

        transaction.add_post(self.__unregister_masquerade, _obj, masquerade_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __unregister_masquerade(self, _obj, masquerade_id):
        if masquerade_id in _obj.settings["masquerade"]:
            del _obj.settings["masquerade"][masquerade_id]

    def query_masquerade(self, policy):
        return self.__masquerade_id() in self.get_settings(policy)["masquerade"]

    # PORT FORWARDING

    def check_forward_port(self, ipv, port, protocol, toport=None, toaddr=None):
        self._fw.check_port(port)
        self._fw.check_tcpudp(protocol)
        if toport:
            self._fw.check_port(toport)
        if toaddr:
            if not check_single_address(ipv, toaddr):
                raise FirewallError(errors.INVALID_ADDR, toaddr)
        if not toport and not toaddr:
            raise FirewallError(
                errors.INVALID_FORWARD,
                "port-forwarding is missing to-port AND to-addr")

    def __forward_port_id(self, port, protocol, toport=None, toaddr=None):
        if check_single_address("ipv6", toaddr):
            self.check_forward_port("ipv6", port, protocol, toport, toaddr)
        else:
            self.check_forward_port("ipv4", port, protocol, toport, toaddr)
        return (portStr(port, "-"), protocol,
                portStr(toport, "-"), str(toaddr))

    def add_forward_port(self, policy, port, protocol, toport=None,
                         toaddr=None, timeout=0, sender=None,
                         use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_timeout(timeout)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        forward_id = self.__forward_port_id(port, protocol, toport, toaddr)
        if forward_id in _obj.settings["forward_ports"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s:%s:%s:%s' already in '%s'" % \
                                (port, protocol, toport, toaddr, _name))

        if not _obj.derived_from_zone:
            if "HOST" in _obj.settings["egress_zones"]:
                if toaddr:
                    raise FirewallError(errors.INVALID_FORWARD, "A 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'")
            elif _obj.settings["egress_zones"]:
                if not toaddr:
                    raise FirewallError(errors.INVALID_FORWARD, "'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zone")
                for zone in _obj.settings["egress_zones"]:
                    if zone == "ANY":
                        continue
                    if self._fw.zone.list_interfaces(zone):
                        raise FirewallError(errors.INVALID_ZONE, "'forward-port' cannot be used in a policy if an egress zone has assigned interfaces")

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._forward_port(True, _policy, transaction, port, protocol,
                               toport, toaddr)

        self.__register_forward_port(_obj, forward_id, timeout, sender)
        transaction.add_fail(self.__unregister_forward_port, _obj, forward_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __register_forward_port(self, _obj, forward_id, timeout, sender):
        _obj.settings["forward_ports"][forward_id] = \
            self.__gen_settings(timeout, sender)

    def remove_forward_port(self, policy, port, protocol, toport=None,
                            toaddr=None, use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        forward_id = self.__forward_port_id(port, protocol, toport, toaddr)
        if forward_id not in _obj.settings["forward_ports"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s:%s:%s:%s' not in '%s'" % \
                                (port, protocol, toport, toaddr, _name))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._forward_port(False, _policy, transaction, port, protocol,
                               toport, toaddr)

        transaction.add_post(self.__unregister_forward_port, _obj, forward_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __unregister_forward_port(self, _obj, forward_id):
        if forward_id in _obj.settings["forward_ports"]:
            del _obj.settings["forward_ports"][forward_id]

    def query_forward_port(self, policy, port, protocol, toport=None,
                           toaddr=None):
        forward_id = self.__forward_port_id(port, protocol, toport, toaddr)
        return forward_id in self.get_settings(policy)["forward_ports"]

    def list_forward_ports(self, policy):
        return list(self.get_settings(policy)["forward_ports"].keys())

    # ICMP BLOCK

    def check_icmp_block(self, icmp):
        self._fw.check_icmptype(icmp)

    def __icmp_block_id(self, icmp):
        self.check_icmp_block(icmp)
        return icmp

    def add_icmp_block(self, policy, icmp, timeout=0, sender=None,
                       use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_timeout(timeout)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        icmp_id = self.__icmp_block_id(icmp)
        if icmp_id in _obj.settings["icmp_blocks"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s' already in '%s'" % (icmp, _name))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._icmp_block(True, _policy, icmp, transaction)

        self.__register_icmp_block(_obj, icmp_id, timeout, sender)
        transaction.add_fail(self.__unregister_icmp_block, _obj, icmp_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __register_icmp_block(self, _obj, icmp_id, timeout, sender):
        _obj.settings["icmp_blocks"][icmp_id] = \
            self.__gen_settings(timeout, sender)

    def remove_icmp_block(self, policy, icmp, use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        icmp_id = self.__icmp_block_id(icmp)
        if icmp_id not in _obj.settings["icmp_blocks"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s' not in '%s'" % (icmp, _name))

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            self._icmp_block(False, _policy, icmp, transaction)

        transaction.add_post(self.__unregister_icmp_block, _obj, icmp_id)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __unregister_icmp_block(self, _obj, icmp_id):
        if icmp_id in _obj.settings["icmp_blocks"]:
            del _obj.settings["icmp_blocks"][icmp_id]

    def query_icmp_block(self, policy, icmp):
        return self.__icmp_block_id(icmp) in self.get_settings(policy)["icmp_blocks"]

    def list_icmp_blocks(self, policy):
        return self.get_settings(policy)["icmp_blocks"].keys()

    # ICMP BLOCK INVERSION

    def __icmp_block_inversion_id(self):
        return True

    def add_icmp_block_inversion(self, policy, sender=None,
                                 use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        icmp_block_inversion_id = self.__icmp_block_inversion_id()
        if icmp_block_inversion_id in _obj.settings["icmp_block_inversion"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(
                errors.ALREADY_ENABLED,
                "icmp-block-inversion already enabled in '%s'" % _name)

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            # undo icmp blocks
            for args in self.get_settings(_policy)["icmp_blocks"]:
                self._icmp_block(False, _policy, args, transaction)

            self._icmp_block_inversion(False, _policy, transaction)

        self.__register_icmp_block_inversion(_obj, icmp_block_inversion_id,
                                             sender)
        transaction.add_fail(self.__undo_icmp_block_inversion, _policy, _obj,
                             icmp_block_inversion_id)

        # redo icmp blocks
        if _obj.applied:
            for args in self.get_settings(_policy)["icmp_blocks"]:
                self._icmp_block(True, _policy, args, transaction)

            self._icmp_block_inversion(True, _policy, transaction)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __register_icmp_block_inversion(self, _obj, icmp_block_inversion_id,
                                        sender):
        _obj.settings["icmp_block_inversion"][icmp_block_inversion_id] = \
            self.__gen_settings(0, sender)

    def __undo_icmp_block_inversion(self, _policy, _obj, icmp_block_inversion_id):
        transaction = self.new_transaction()

        # undo icmp blocks
        if _obj.applied:
            for args in self.get_settings(_policy)["icmp_blocks"]:
                self._icmp_block(False, _policy, args, transaction)

        if icmp_block_inversion_id in _obj.settings["icmp_block_inversion"]:
            del _obj.settings["icmp_block_inversion"][icmp_block_inversion_id]

        # redo icmp blocks
        if _obj.applied:
            for args in self.get_settings(_policy)["icmp_blocks"]:
                self._icmp_block(True, _policy, args, transaction)

        transaction.execute(True)

    def remove_icmp_block_inversion(self, policy, use_transaction=None):
        _policy = self._fw.check_policy(policy)
        self._fw.check_panic()
        _obj = self._policies[_policy]

        icmp_block_inversion_id = self.__icmp_block_inversion_id()
        if icmp_block_inversion_id not in _obj.settings["icmp_block_inversion"]:
            _name = _obj.derived_from_zone if _obj.derived_from_zone else _policy
            raise FirewallError(
                errors.NOT_ENABLED,
                "icmp-block-inversion not enabled in '%s'" % _name)

        if use_transaction is None:
            transaction = self.new_transaction()
        else:
            transaction = use_transaction

        if _obj.applied:
            # undo icmp blocks
            for args in self.get_settings(_policy)["icmp_blocks"]:
                self._icmp_block(False, _policy, args, transaction)

            self._icmp_block_inversion(False, _policy, transaction)

        self.__unregister_icmp_block_inversion(_obj,
                                               icmp_block_inversion_id)
        transaction.add_fail(self.__register_icmp_block_inversion, _obj,
                             icmp_block_inversion_id, None)

        # redo icmp blocks
        if _obj.applied:
            for args in self.get_settings(_policy)["icmp_blocks"]:
                self._icmp_block(True, _policy, args, transaction)

            self._icmp_block_inversion(True, _policy, transaction)

        if use_transaction is None:
            transaction.execute(True)

        return _policy

    def __unregister_icmp_block_inversion(self, _obj, icmp_block_inversion_id):
        if icmp_block_inversion_id in _obj.settings["icmp_block_inversion"]:
            del _obj.settings["icmp_block_inversion"][icmp_block_inversion_id]

    def query_icmp_block_inversion(self, policy):
        return self.__icmp_block_inversion_id() in \
            self.get_settings(policy)["icmp_block_inversion"]

    def gen_chain_rules(self, policy, create, table, chain, transaction):
        obj = self._fw.policy.get_policy(policy)
        if obj.derived_from_zone:
            # For policies derived from zones, use only the first policy in the
            # list to track chain creation. The chain names are converted to
            # zone-based names as such they're "global" for all zone derived
            # policies.
            tracking_policy = self._fw.zone._zone_policies[obj.derived_from_zone][0]
        else:
            tracking_policy = policy

        if create:
            if tracking_policy in self._chains and  \
               (table, chain) in self._chains[tracking_policy]:
                return
        else:
            if tracking_policy not in self._chains or \
               (table, chain) not in self._chains[tracking_policy]:
                return

        for backend in self._fw.enabled_backends():
            if backend.policies_supported and \
               table in backend.get_available_tables():
                rules = backend.build_policy_chain_rules(create, policy, table, chain)
                transaction.add_rules(backend, rules)

        self._register_chains(tracking_policy, create, [(table, chain)])
        transaction.add_fail(self._register_chains, tracking_policy, not create, [(table, chain)])

    def _register_chains(self, policy, create, tables):
        for (table, chain) in tables:
            if create:
                self._chains.setdefault(policy, []).append((table, chain))
            else:
                self._chains[policy].remove((table, chain))
                if len(self._chains[policy]) == 0:
                    del self._chains[policy]

    # IPSETS

    def _ipset_family(self, name):
        if self._fw.ipset.get_type(name) == "hash:mac":
            return None
        return self._fw.ipset.get_family(name)

    def __ipset_type(self, name):
        return self._fw.ipset.get_type(name)

    def _ipset_match_flags(self, name, flag):
        return ",".join([flag] * self._fw.ipset.get_dimension(name))

    def _check_ipset_applied(self, name):
        return self._fw.ipset.check_applied(name)

    def _check_ipset_type_for_source(self, name):
        _type = self.__ipset_type(name)
        if _type not in SOURCE_IPSET_TYPES:
            raise FirewallError(
                errors.INVALID_IPSET,
                "ipset '%s' with type '%s' not usable as source" % \
                (name, _type))

    def _rule_prepare(self, enable, policy, rule, transaction, included_services=None):
        # First apply any services this service may include
        if type(rule.element) == Rich_Service:
            svc = self._fw.service.get_service(rule.element.name)
            if included_services is None:
                included_services = [rule.element.name]
            for include in svc.includes:
                if include in included_services:
                    continue
                self.check_service(include)
                included_services.append(include)
                _rule = copy.deepcopy(rule)
                _rule.element.name = include
                self._rule_prepare(enable, policy, _rule, transaction, included_services=included_services)

        ipvs = []
        if rule.family:
            ipvs = [ rule.family ]
        elif rule.element and (isinstance(rule.element, Rich_IcmpBlock) or isinstance(rule.element, Rich_IcmpType)):
            ict = self._fw.config.get_icmptype(rule.element.name)
            if ict.destination:
                ipvs = [ipv for ipv in ["ipv4", "ipv6"] if ipv in ict.destination]

        source_ipv = self._rule_source_ipv(rule.source)
        if source_ipv:
            if rule.family:
                # rule family is defined by user, no way to change it
                if rule.family != source_ipv:
                    raise FirewallError(errors.INVALID_RULE,
                                        "Source address family '%s' conflicts with rule family '%s'." % (source_ipv, rule.family))
            else:
                # use the source family as rule family
                ipvs = [ source_ipv ]

        if not ipvs:
            ipvs = ["ipv4", "ipv6"]

        # clamp ipvs to those that are actually enabled.
        ipvs = [ipv for ipv in ipvs if self._fw.is_ipv_enabled(ipv)]

        # add an element to object to allow backends to know what ipvs this applies to
        rule.ipvs = ipvs

        for backend in set([self._fw.get_backend_by_ipv(x) for x in ipvs]):
            # SERVICE
            if type(rule.element) == Rich_Service:
                svc = self._fw.service.get_service(rule.element.name)

                destinations = []
                if len(svc.destination) > 0:
                    if rule.destination:
                        # we can not use two destinations at the same time
                        raise FirewallError(errors.INVALID_RULE,
                                            "Destination conflict with service.")
                    for ipv in ipvs:
                        if ipv in svc.destination and backend.is_ipv_supported(ipv):
                            destinations.append(svc.destination[ipv])
                else:
                    # dummy for the following for loop
                    destinations.append(None)

                for destination in destinations:
                    if type(rule.action) == Rich_Accept:
                        # only load modules for accept action
                        helpers = self.get_helpers_for_service_modules(svc.modules,
                                                                       enable)
                        helpers += self.get_helpers_for_service_helpers(svc.helpers)
                        helpers = sorted(set(helpers), key=lambda x: x.name)

                        modules = [ ]
                        for helper in helpers:
                            module = helper.module
                            _module_short_name = get_nf_conntrack_short_name(module)
                            nat_module = module.replace("conntrack", "nat")
                            modules.append(nat_module)
                            if helper.family != "" and not backend.is_ipv_supported(helper.family):
                                # no support for family ipv, continue
                                continue
                            if len(helper.ports) < 1:
                                modules.append(module)
                            else:
                                for (port,proto) in helper.ports:
                                    rules = backend.build_policy_helper_ports_rules(
                                                    enable, policy, proto, port,
                                                    destination, helper.name, _module_short_name)
                                    transaction.add_rules(backend, rules)
                        transaction.add_modules(modules)

                    # create rules
                    for (port,proto) in svc.ports:
                        rules = backend.build_policy_ports_rules(
                                    enable, policy, proto, port, destination, rule)
                        transaction.add_rules(backend, rules)

                    for proto in svc.protocols:
                        rules = backend.build_policy_protocol_rules(
                                    enable, policy, proto, destination, rule)
                        transaction.add_rules(backend, rules)

                    # create rules
                    for (port,proto) in svc.source_ports:
                        rules = backend.build_policy_source_ports_rules(
                                    enable, policy, proto, port, destination, rule)
                        transaction.add_rules(backend, rules)

            # PORT
            elif type(rule.element) == Rich_Port:
                port = rule.element.port
                protocol = rule.element.protocol
                self.check_port(port, protocol)

                rules = backend.build_policy_ports_rules(
                            enable, policy, protocol, port, None, rule)
                transaction.add_rules(backend, rules)

            # PROTOCOL
            elif type(rule.element) == Rich_Protocol:
                protocol = rule.element.value
                self.check_protocol(protocol)

                rules = backend.build_policy_protocol_rules(
                            enable, policy, protocol, None, rule)
                transaction.add_rules(backend, rules)

            # MASQUERADE
            elif type(rule.element) == Rich_Masquerade:
                if enable:
                    for ipv in ipvs:
                        if backend.is_ipv_supported(ipv):
                            transaction.add_post(enable_ip_forwarding, ipv)

                rules = backend.build_policy_masquerade_rules(enable, policy, rule)
                transaction.add_rules(backend, rules)

            # FORWARD PORT
            elif type(rule.element) == Rich_ForwardPort:
                port = rule.element.port
                protocol = rule.element.protocol
                toport = rule.element.to_port
                toaddr = rule.element.to_address
                for ipv in ipvs:
                    if backend.is_ipv_supported(ipv):
                        self.check_forward_port(ipv, port, protocol, toport, toaddr)
                    if toaddr and enable:
                        transaction.add_post(enable_ip_forwarding, ipv)

                rules = backend.build_policy_forward_port_rules(
                                    enable, policy, port, protocol, toport,
                                    toaddr, rule)
                transaction.add_rules(backend, rules)

            # SOURCE PORT
            elif type(rule.element) == Rich_SourcePort:
                port = rule.element.port
                protocol = rule.element.protocol
                self.check_port(port, protocol)

                rules = backend.build_policy_source_ports_rules(
                            enable, policy, protocol, port, None, rule)
                transaction.add_rules(backend, rules)

            # ICMP BLOCK and ICMP TYPE
            elif type(rule.element) == Rich_IcmpBlock or \
                 type(rule.element) == Rich_IcmpType:
                ict = self._fw.config.get_icmptype(rule.element.name)

                if rule.family and ict.destination and \
                   rule.family not in ict.destination:
                    raise FirewallError(errors.INVALID_ICMPTYPE,
                                        "rich rule family '%s' conflicts with icmp type '%s'" % \
                                        (rule.family, rule.element.name))

                if type(rule.element) == Rich_IcmpBlock and \
                   rule.action and type(rule.action) == Rich_Accept:
                    # icmp block might have reject or drop action, but not accept
                    raise FirewallError(errors.INVALID_RULE,
                                        "IcmpBlock not usable with accept action")

                rules = backend.build_policy_icmp_block_rules(enable, policy, ict, rule)
                transaction.add_rules(backend, rules)

            elif rule.element is None:
                rules = backend.build_policy_rich_source_destination_rules(
                            enable, policy, rule)
                transaction.add_rules(backend, rules)

            # EVERYTHING ELSE
            else:
                raise FirewallError(errors.INVALID_RULE, "Unknown element %s" %
                                    type(rule.element))

    def _service(self, enable, policy, service, transaction, included_services=None):
        svc = self._fw.service.get_service(service)
        helpers = self.get_helpers_for_service_modules(svc.modules, enable)
        helpers += self.get_helpers_for_service_helpers(svc.helpers)
        helpers = sorted(set(helpers), key=lambda x: x.name)

        # First apply any services this service may include
        if included_services is None:
            included_services = [service]
        for include in svc.includes:
            if include in included_services:
                continue
            self.check_service(include)
            included_services.append(include)
            self._service(enable, policy, include, transaction, included_services=included_services)

        # build a list of (backend, destination). The destination may be ipv4,
        # ipv6 or None
        #
        backends_ipv = []
        for ipv in ["ipv4", "ipv6"]:
            if not self._fw.is_ipv_enabled(ipv):
                continue
            backend = self._fw.get_backend_by_ipv(ipv)
            if len(svc.destination) > 0:
                if ipv in svc.destination:
                    backends_ipv.append((backend, svc.destination[ipv]))
            else:
                if (backend, None) not in backends_ipv:
                    backends_ipv.append((backend, None))

        for (backend,destination) in backends_ipv:
            for helper in helpers:
                module = helper.module
                _module_short_name = get_nf_conntrack_short_name(module)
                nat_module = helper.module.replace("conntrack", "nat")
                transaction.add_module(nat_module)
                if helper.family != "" and not backend.is_ipv_supported(helper.family):
                    # no support for family ipv, continue
                    continue
                if len(helper.ports) < 1:
                    transaction.add_module(module)
                else:
                    for (port,proto) in helper.ports:
                        rules = backend.build_policy_helper_ports_rules(
                                        enable, policy, proto, port,
                                        destination, helper.name, _module_short_name)
                        transaction.add_rules(backend, rules)

            for (port,proto) in svc.ports:
                rules = backend.build_policy_ports_rules(enable, policy, proto,
                                                       port, destination)
                transaction.add_rules(backend, rules)

            for protocol in svc.protocols:
                rules = backend.build_policy_protocol_rules(
                                    enable, policy, protocol, destination)
                transaction.add_rules(backend, rules)

            for (port,proto) in svc.source_ports:
                rules = backend.build_policy_source_ports_rules(
                                    enable, policy, proto, port, destination)
                transaction.add_rules(backend, rules)

    def _port(self, enable, policy, port, protocol, transaction):
        for backend in self._fw.enabled_backends():
            if not backend.policies_supported:
                continue

            rules = backend.build_policy_ports_rules(enable, policy, protocol,
                                                   port)
            transaction.add_rules(backend, rules)

    def _protocol(self, enable, policy, protocol, transaction):
        for backend in self._fw.enabled_backends():
            if not backend.policies_supported:
                continue

            rules = backend.build_policy_protocol_rules(enable, policy, protocol)
            transaction.add_rules(backend, rules)

    def _source_port(self, enable, policy, port, protocol, transaction):
        for backend in self._fw.enabled_backends():
            if not backend.policies_supported:
                continue

            rules = backend.build_policy_source_ports_rules(enable, policy, protocol, port)
            transaction.add_rules(backend, rules)

    def _masquerade(self, enable, policy, transaction):
        ipv = "ipv4"
        transaction.add_post(enable_ip_forwarding, ipv)

        backend = self._fw.get_backend_by_ipv(ipv)
        rules = backend.build_policy_masquerade_rules(enable, policy)
        transaction.add_rules(backend, rules)

    def _forward_port(self, enable, policy, transaction, port, protocol,
                       toport=None, toaddr=None):
        if check_single_address("ipv6", toaddr):
            ipv = "ipv6"
        else:
            ipv = "ipv4"

        if toaddr and enable:
            transaction.add_post(enable_ip_forwarding, ipv)
        backend = self._fw.get_backend_by_ipv(ipv)
        rules = backend.build_policy_forward_port_rules(
                            enable, policy, port, protocol, toport,
                            toaddr)
        transaction.add_rules(backend, rules)

    def _icmp_block(self, enable, policy, icmp, transaction):
        ict = self._fw.config.get_icmptype(icmp)

        for backend in self._fw.enabled_backends():
            if not backend.policies_supported:
                continue
            skip_backend = False

            if ict.destination:
                for ipv in ["ipv4", "ipv6"]:
                    if ipv in ict.destination:
                        if not backend.is_ipv_supported(ipv):
                            skip_backend = True
                            break

            if skip_backend:
                continue

            rules = backend.build_policy_icmp_block_rules(enable, policy, ict)
            transaction.add_rules(backend, rules)

    def _icmp_block_inversion(self, enable, policy, transaction):
        target = self._policies[policy].target

        # Do not add general icmp accept rules into a trusted, block or drop
        # policy.
        if target in [ "DROP", "%%REJECT%%", "REJECT" ]:
            return
        if not self.query_icmp_block_inversion(policy) and target == "ACCEPT":
            # ibi target and policy target are ACCEPT, no need to add an extra
            # rule
            return

        for backend in self._fw.enabled_backends():
            if not backend.policies_supported:
                continue

            rules = backend.build_policy_icmp_block_inversion_rules(enable, policy)
            transaction.add_rules(backend, rules)

    def check_ingress_egress(self, policy, ingress_zones, egress_zones,
                                           ingress_interfaces, egress_interfaces,
                                           ingress_sources, egress_sources):
        for zone in ingress_zones:
            self.check_ingress_zone(zone)
        for zone in egress_zones:
            self.check_egress_zone(zone)

        if ("ANY" in ingress_zones or "HOST" in ingress_zones) and \
           len(ingress_zones) > 1:
            raise FirewallError(errors.INVALID_ZONE, "'ingress-zones' may only contain one of: many regular zones, ANY, or HOST")

        if ("ANY" in egress_zones or "HOST" in egress_zones) and \
           len(egress_zones) > 1:
            raise FirewallError(errors.INVALID_ZONE, "'egress-zones' may only contain one of: many regular zones, ANY, or HOST")

        if (egress_interfaces or egress_sources) and \
           not ingress_interfaces and not ingress_sources and \
           "HOST" not in ingress_zones and "ANY" not in ingress_zones:
            raise FirewallError(errors.INVALID_ZONE, "policy \"%s\" has no ingress" % (policy))

        if (ingress_interfaces or ingress_sources) and \
           not egress_interfaces and not egress_sources and \
           "HOST" not in egress_zones and "ANY" not in egress_zones:
            raise FirewallError(errors.INVALID_ZONE, "policy \"%s\" has no egress" % (policy))

    def check_ingress_egress_chain(self, policy, table, chain,
                                   ingress_zones, egress_zones,
                                   ingress_interfaces, egress_interfaces,
                                   ingress_sources, egress_sources):
        if chain == "PREROUTING":
            # raw,prerouting is used for conntrack helpers (services), so we
            # need to allow it if egress-zones contains an actual zone
            if table != "raw":
                if egress_interfaces:
                    raise FirewallError(errors.INVALID_ZONE, "policy \"%s\" egress-zones may not include a zone with added interfaces." % (policy))
        elif chain == "POSTROUTING":
            if "HOST" in ingress_zones:
                raise FirewallError(errors.INVALID_ZONE, "policy \"%s\" ingress-zones may not include HOST." % (policy))
            if "HOST" in egress_zones:
                raise FirewallError(errors.INVALID_ZONE, "policy \"%s\" egress-zones may not include HOST." % (policy))
            if ingress_interfaces:
                raise FirewallError(errors.INVALID_ZONE, "policy \"%s\" ingress-zones may not include a zone with added interfaces." % (policy))
        elif chain == "FORWARD":
            if "HOST" in ingress_zones:
                raise FirewallError(errors.INVALID_ZONE, "policy \"%s\" ingress-zones may not include HOST." % (policy))
            if "HOST" in egress_zones:
                raise FirewallError(errors.INVALID_ZONE, "policy \"%s\" egress-zones may not include HOST." % (policy))
        elif chain == "INPUT":
            if "HOST" not in egress_zones:
                raise FirewallError(errors.INVALID_ZONE, "policy \"%s\" egress-zones must include only HOST." % (policy))
        elif chain == "OUTPUT":
            if "HOST" not in ingress_zones:
                raise FirewallError(errors.INVALID_ZONE, "policy \"%s\" ingress-zones must include only HOST." % (policy))

    def _ingress_egress_zones_transaction(self, enable, policy):
        transaction = self.new_transaction()
        self._ingress_egress_zones(enable, policy, transaction)
        transaction.execute(True)

    def _ingress_egress_zones(self, enable, policy, transaction):
        obj = self._policies[policy]

        ingress_zones = obj.settings["ingress_zones"]
        egress_zones = obj.settings["egress_zones"]

        ingress_interfaces = set()
        egress_interfaces = set()
        ingress_sources = set()
        egress_sources = set()

        for zone in ingress_zones:
            if zone in ["ANY", "HOST"]:
                continue
            ingress_interfaces |= set(self._fw.zone.list_interfaces(zone))
            ingress_sources |= set(self._fw.zone.list_sources(zone))
        for zone in egress_zones:
            if zone in ["ANY", "HOST"]:
                continue
            egress_interfaces |= set(self._fw.zone.list_interfaces(zone))
            egress_sources |= set(self._fw.zone.list_sources(zone))

        self.check_ingress_egress(policy, ingress_zones, egress_zones,
                                          ingress_interfaces, egress_interfaces,
                                          ingress_sources, egress_sources)

        for backend in self._fw.enabled_backends():
            if not backend.policies_supported:
                continue

            for (table, chain) in self._get_table_chains_for_policy_dispatch(policy):
                self.check_ingress_egress_chain(policy, table, chain,
                                                ingress_zones, egress_zones,
                                                ingress_interfaces, egress_interfaces,
                                                ingress_sources, egress_sources)
                rules = backend.build_policy_ingress_egress_rules(enable, policy, table, chain,
                                                                  ingress_interfaces, egress_interfaces,
                                                                  ingress_sources, egress_sources)
                transaction.add_rules(backend, rules)

    def _get_table_chains_for_policy_dispatch(self, policy):
        """Create a list of (table, chain) needed for policy dispatch"""
        obj = self._policies[policy]
        if "ANY" in obj.settings["ingress_zones"] and "HOST" in obj.settings["egress_zones"]:
            # any --> HOST
            tc = [("filter", "INPUT"), ("nat", "PREROUTING"),
                  ("mangle", "PREROUTING")]
            # iptables backend needs to put conntrack helper rules in raw
            # prerouting.
            if not self._fw.nftables_enabled:
                tc.append(("raw", "PREROUTING"))
            return tc
        elif "HOST" in obj.settings["egress_zones"]:
            # zone --> HOST
            tc = [("filter", "INPUT")]
            # iptables backend needs to put conntrack helper rules in raw
            # prerouting.
            if not self._fw.nftables_enabled:
                tc.append(("raw", "PREROUTING"))
            return tc
        elif "HOST" in obj.settings["ingress_zones"]:
            # HOST --> zone/any
            return [("filter", "OUTPUT")]
        elif "ANY" in obj.settings["ingress_zones"] and "ANY" in obj.settings["egress_zones"]:
            # any --> any
            tc = [("filter", "FORWARD"), ("nat", "PREROUTING"),
                  ("nat", "POSTROUTING"), ("mangle", "PREROUTING")]
            # iptables backend needs to put conntrack helper rules in raw
            # prerouting.
            if not self._fw.nftables_enabled:
                tc.append(("raw", "PREROUTING"))
            return tc
        elif "ANY" in obj.settings["egress_zones"]:
            # zone --> any
            tc = [("filter", "FORWARD"), ("nat", "PREROUTING"),
                  ("mangle", "PREROUTING")]
            # iptables backend needs to put conntrack helper rules in raw
            # prerouting.
            if not self._fw.nftables_enabled:
                tc.append(("raw", "PREROUTING"))
            for zone in obj.settings["ingress_zones"]:
                if self._fw.zone.get_settings(zone)["interfaces"]:
                    break
            else:
                tc.append(("nat", "POSTROUTING"))
            return tc
        elif "ANY" in obj.settings["ingress_zones"]:
            # any --> zone
            tc = [("filter", "FORWARD"), ("nat", "POSTROUTING")]
            # iptables backend needs to put conntrack helper rules in raw
            # prerouting.
            if not self._fw.nftables_enabled:
                tc.append(("raw", "PREROUTING"))
            for zone in obj.settings["egress_zones"]:
                if self._fw.zone.get_settings(zone)["interfaces"]:
                    break
            else:
                tc.append(("nat", "PREROUTING"))
                tc.append(("mangle", "PREROUTING"))
            return tc
        else:
            # zone -> zone
            tc = [("filter", "FORWARD")]
            # iptables backend needs to put conntrack helper rules in raw
            # prerouting.
            if not self._fw.nftables_enabled:
                tc.append(("raw", "PREROUTING"))
            for zone in obj.settings["ingress_zones"]:
                if self._fw.zone.get_settings(zone)["interfaces"]:
                    break
            else:
                tc.append(("nat", "POSTROUTING"))
            for zone in obj.settings["egress_zones"]:
                if self._fw.zone.get_settings(zone)["interfaces"]:
                    break
            else:
                tc.append(("nat", "PREROUTING"))
                tc.append(("mangle", "PREROUTING"))
            return tc

    def _get_table_chains_for_zone_dispatch(self, policy):
        """Create a list of (table, chain) needed for zone dispatch"""
        obj = self._policies[policy]
        if "HOST" in obj.settings["egress_zones"]:
            # zone --> Host
            tc = [("filter", "INPUT")]
            # iptables backend needs to put conntrack helper rules in raw
            # prerouting.
            if not self._fw.nftables_enabled:
                tc.append(("raw", "PREROUTING"))
            return tc
        elif "ANY" in obj.settings["egress_zones"]:
            # zone --> any
            return [("filter", "FORWARD_IN"), ("nat", "PREROUTING"),
                    ("mangle", "PREROUTING")]
        elif "ANY" in obj.settings["ingress_zones"]:
            # any --> zone
            return [("filter", "FORWARD_OUT"), ("nat", "POSTROUTING")]
        else:
            return FirewallError("Invalid policy: %s" % (policy))

    def policy_base_chain_name(self, policy, table, policy_prefix, isSNAT=False):
        obj = self._fw.policy.get_policy(policy)
        if obj.derived_from_zone:
            suffix = obj.derived_from_zone
        else:
            suffix = policy_prefix + policy

        if "HOST" in obj.settings["egress_zones"]:
            # zone/any --> Host
            if table == "filter":
                return "IN_" + suffix
            if table == "raw":
                # NOTE: nftables doesn't actually use this. Only iptables
                return "PRE_" + suffix
            if not obj.derived_from_zone:
                if table in ["mangle", "nat"]:
                    return "PRE_" + suffix
        elif "HOST" in obj.settings["ingress_zones"]:
            # HOST --> zone/any
            if not obj.derived_from_zone:
                if table == "filter":
                    return "OUT_" + suffix
        elif "ANY" in obj.settings["egress_zones"]:
            # zone/any --> any
            if table == "filter":
                if obj.derived_from_zone:
                    return "FWDI_" + suffix
                else:
                    return "FWD_" + suffix
            elif table == "nat":
                if isSNAT:
                    return "POST_" + suffix
                else:
                    return "PRE_" + suffix
            elif table in ["mangle", "raw"]:
                return "PRE_" + suffix
        elif "ANY" in obj.settings["ingress_zones"]:
            # any --> zone
            if table == "filter":
                if obj.derived_from_zone:
                    return "FWDO_" + suffix
                else:
                    return "FWD_" + suffix
            elif table == "nat":
                if isSNAT:
                    return "POST_" + suffix
                else:
                    return "PRE_" + suffix
            elif table in ["mangle", "raw"]:
                if not obj.derived_from_zone:
                    return "PRE_" + suffix
        elif not obj.derived_from_zone:
            # zone --> zone
            if table == "filter":
                return "FWD_" + suffix
            elif table == "nat":
                if isSNAT:
                    return "POST_" + suffix
                else:
                    return "PRE_" + suffix
            elif table in ["mangle", "raw"]:
                return "PRE_" + suffix
        return FirewallError("Can't convert policy to chain name: %s, %s, %s" % (policy, table, isSNAT))
core/fw_helper.py000064400000003451150351351730010027 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2015-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""helper backend"""

__all__ = [ "FirewallHelper" ]

from firewall import errors
from firewall.errors import FirewallError

class FirewallHelper(object):
    def __init__(self, fw):
        self._fw = fw
        self._helpers = { }

    def __repr__(self):
        return '%s(%r)' % (self.__class__, self._helpers)

    # helpers

    def cleanup(self):
        self._helpers.clear()

    def check_helper(self, name):
        if name not in self.get_helpers():
            raise FirewallError(errors.INVALID_HELPER, name)

    def query_helper(self, name):
        return name in self.get_helpers()

    def get_helpers(self):
        return sorted(self._helpers.keys())

    def has_helpers(self):
        return len(self._helpers) > 0

    def get_helper(self, name):
        self.check_helper(name)
        return self._helpers[name]

    def add_helper(self, obj):
        self._helpers[obj.name] = obj

    def remove_helper(self, name):
        if name not in self._helpers:
            raise FirewallError(errors.INVALID_HELPER, name)
        del self._helpers[name]
core/fw_ipset.py000064400000022712150351351730007675 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2015-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""ipset backend"""

__all__ = [ "FirewallIPSet" ]

from firewall.core.logger import log
from firewall.core.ipset import remove_default_create_options as rm_def_cr_opts, \
                                normalize_ipset_entry, check_entry_overlaps_existing, \
                                check_for_overlapping_entries
from firewall.core.io.ipset import IPSet
from firewall import errors
from firewall.errors import FirewallError

class FirewallIPSet(object):
    def __init__(self, fw):
        self._fw = fw
        self._ipsets = { }

    def __repr__(self):
        return '%s(%r)' % (self.__class__, self._ipsets)

    # ipsets

    def cleanup(self):
        self._ipsets.clear()

    def check_ipset(self, name):
        if name not in self.get_ipsets():
            raise FirewallError(errors.INVALID_IPSET, name)

    def query_ipset(self, name):
        return name in self.get_ipsets()

    def get_ipsets(self):
        return sorted(self._ipsets.keys())

    def has_ipsets(self):
        return len(self._ipsets) > 0

    def get_ipset(self, name, applied=False):
        self.check_ipset(name)
        obj = self._ipsets[name]
        if applied:
            self.check_applied_obj(obj)
        return obj

    def backends(self):
        backends = []
        if self._fw.nftables_enabled:
            backends.append(self._fw.nftables_backend)
        if self._fw.ipset_enabled:
            backends.append(self._fw.ipset_backend)
        return backends

    def add_ipset(self, obj):
        if obj.type not in self._fw.ipset_supported_types:
            raise FirewallError(errors.INVALID_TYPE,
                                "'%s' is not supported by ipset." % obj.type)
        self._ipsets[obj.name] = obj

    def remove_ipset(self, name, keep=False):
        obj = self._ipsets[name]
        if obj.applied and not keep:
            try:
                for backend in self.backends():
                    backend.set_destroy(name)
            except Exception as msg:
                raise FirewallError(errors.COMMAND_FAILED, msg)
        else:
            log.debug1("Keeping ipset '%s' because of timeout option", name)
        del self._ipsets[name]

    def apply_ipset(self, name):
        obj = self._ipsets[name]

        for backend in self.backends():
            if backend.name == "ipset":
                active = backend.set_get_active_terse()

                if name in active and ("timeout" not in obj.options or \
                                       obj.options["timeout"] == "0" or \
                                       obj.type != active[name][0] or \
                                       rm_def_cr_opts(obj.options) != \
                                       active[name][1]):
                    try:
                        backend.set_destroy(name)
                    except Exception as msg:
                        raise FirewallError(errors.COMMAND_FAILED, msg)

            if self._fw._individual_calls:
                try:
                    backend.set_create(obj.name, obj.type, obj.options)
                except Exception as msg:
                    raise FirewallError(errors.COMMAND_FAILED, msg)
                else:
                    obj.applied = True
                    if "timeout" in obj.options and \
                       obj.options["timeout"] != "0":
                        # no entries visible for ipsets with timeout
                        continue

                try:
                    backend.set_flush(obj.name)
                except Exception as msg:
                    raise FirewallError(errors.COMMAND_FAILED, msg)

                for entry in obj.entries:
                    try:
                        backend.set_add(obj.name, entry)
                    except Exception as msg:
                        raise FirewallError(errors.COMMAND_FAILED, msg)
            else:
                try:
                    backend.set_restore(obj.name, obj.type,
                                                   obj.entries, obj.options,
                                                   None)
                except Exception as msg:
                    raise FirewallError(errors.COMMAND_FAILED, msg)
                else:
                    obj.applied = True

    def apply_ipsets(self):
        for name in self.get_ipsets():
            obj = self._ipsets[name]
            obj.applied = False

            log.debug1("Applying ipset '%s'" % name)
            self.apply_ipset(name)

    def flush(self):
        for backend in self.backends():
            # nftables sets are part of the normal firewall ruleset.
            if backend.name == "nftables":
                continue
            for ipset in self.get_ipsets():
                try:
                    self.check_applied(ipset)
                    backend.set_destroy(ipset)
                except FirewallError as msg:
                    if msg.code != errors.NOT_APPLIED:
                        raise msg

    # TYPE

    def get_type(self, name, applied=True):
        return self.get_ipset(name, applied=applied).type

    # DIMENSION
    def get_dimension(self, name):
        return len(self.get_ipset(name, applied=True).type.split(","))

    def check_applied(self, name):
        obj = self.get_ipset(name)
        self.check_applied_obj(obj)

    def check_applied_obj(self, obj):
        if not obj.applied:
            raise FirewallError(
                errors.NOT_APPLIED, obj.name)

    # OPTIONS

    def get_family(self, name, applied=True):
        obj = self.get_ipset(name, applied=applied)
        if "family" in obj.options:
            if obj.options["family"] == "inet6":
                return "ipv6"
        return "ipv4"

    # ENTRIES

    def add_entry(self, name, entry):
        obj = self.get_ipset(name, applied=True)
        entry = normalize_ipset_entry(entry)

        IPSet.check_entry(entry, obj.options, obj.type)
        if entry in obj.entries:
            raise FirewallError(errors.ALREADY_ENABLED,
                                "'%s' already is in '%s'" % (entry, name))
        check_entry_overlaps_existing(entry, obj.entries)

        try:
            for backend in self.backends():
                backend.set_add(obj.name, entry)
        except Exception as msg:
            raise FirewallError(errors.COMMAND_FAILED, msg)
        else:
            if "timeout" not in obj.options or obj.options["timeout"] == "0":
                # no entries visible for ipsets with timeout
                obj.entries.append(entry)

    def remove_entry(self, name, entry):
        obj = self.get_ipset(name, applied=True)
        entry = normalize_ipset_entry(entry)

        # no entry check for removal
        if entry not in obj.entries:
            raise FirewallError(errors.NOT_ENABLED,
                                "'%s' not in '%s'" % (entry, name))
        try:
            for backend in self.backends():
                backend.set_delete(obj.name, entry)
        except Exception as msg:
            raise FirewallError(errors.COMMAND_FAILED, msg)
        else:
            if "timeout" not in obj.options or obj.options["timeout"] == "0":
                # no entries visible for ipsets with timeout
                obj.entries.remove(entry)

    def query_entry(self, name, entry):
        obj = self.get_ipset(name, applied=True)
        entry = normalize_ipset_entry(entry)
        if "timeout" in obj.options and obj.options["timeout"] != "0":
            # no entries visible for ipsets with timeout
            raise FirewallError(errors.IPSET_WITH_TIMEOUT, name)

        return entry in obj.entries

    def get_entries(self, name):
        obj = self.get_ipset(name, applied=True)
        return obj.entries

    def set_entries(self, name, entries):
        obj = self.get_ipset(name, applied=True)

        check_for_overlapping_entries(entries)

        for entry in entries:
            IPSet.check_entry(entry, obj.options, obj.type)
        if "timeout" not in obj.options or obj.options["timeout"] == "0":
            # no entries visible for ipsets with timeout
            obj.entries = entries

        try:
            for backend in self.backends():
                backend.set_flush(obj.name)
        except Exception as msg:
            raise FirewallError(errors.COMMAND_FAILED, msg)
        else:
            obj.applied = True

        try:
            for backend in self.backends():
                if self._fw._individual_calls:
                    for entry in obj.entries:
                        backend.set_add(obj.name, entry)
                else:
                    backend.set_restore(obj.name, obj.type, obj.entries,
                                                   obj.options, None)
        except Exception as msg:
            raise FirewallError(errors.COMMAND_FAILED, msg)
        else:
            obj.applied = True

        return
core/base.py000064400000004066150351351730006771 0ustar00# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@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/>.
#

"""Base firewall settings"""

DEFAULT_ZONE_TARGET = "{chain}_{zone}"
DEFAULT_POLICY_TARGET = "CONTINUE"
DEFAULT_POLICY_PRIORITY = -1

ZONE_TARGETS = [ "ACCEPT", "%%REJECT%%", "DROP", DEFAULT_ZONE_TARGET,
                 "default" ]

POLICY_TARGETS = [ "ACCEPT", "REJECT", "DROP", "CONTINUE" ]

SHORTCUTS = {
    "PREROUTING": "PRE",
    "POSTROUTING": "POST",
    "INPUT": "IN",
    "FORWARD_IN": "FWDI",
    "FORWARD_OUT": "FWDO",
    "OUTPUT": "OUT",
}

REJECT_TYPES = {
    "ipv4": [ "icmp-host-prohibited", "host-prohib", "icmp-net-unreachable",
              "net-unreach", "icmp-host-unreachable", "host-unreach",
              "icmp-port-unreachable", "port-unreach", "icmp-proto-unreachable",
              "proto-unreach", "icmp-net-prohibited", "net-prohib", "tcp-reset",
              "tcp-rst", "icmp-admin-prohibited", "admin-prohib" ],
    "ipv6": [ "icmp6-adm-prohibited", "adm-prohibited", "icmp6-no-route",
              "no-route", "icmp6-addr-unreachable", "addr-unreach",
              "icmp6-port-unreachable", "port-unreach", "tcp-reset" ]
}

# ipset types that can be used as a source in zones
# The match-set option will be src or src,src according to the
# dimension of the ipset.
SOURCE_IPSET_TYPES = [
    "hash:ip", "hash:ip,port", "hash:ip,mark",
    "hash:net", "hash:net,port", "hash:net,iface",
    "hash:mac"
]