Blame src/firewall/core/io/zone.py

Packit Service 84cb3c
# -*- coding: utf-8 -*-
Packit Service 84cb3c
#
Packit Service 84cb3c
# Copyright (C) 2011-2016 Red Hat, Inc.
Packit Service 84cb3c
#
Packit Service 84cb3c
# Authors:
Packit Service 84cb3c
# Thomas Woerner <twoerner@redhat.com>
Packit Service 84cb3c
#
Packit Service 84cb3c
# This program is free software; you can redistribute it and/or modify
Packit Service 84cb3c
# it under the terms of the GNU General Public License as published by
Packit Service 84cb3c
# the Free Software Foundation; either version 2 of the License, or
Packit Service 84cb3c
# (at your option) any later version.
Packit Service 84cb3c
#
Packit Service 84cb3c
# This program is distributed in the hope that it will be useful,
Packit Service 84cb3c
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 84cb3c
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 84cb3c
# GNU General Public License for more details.
Packit Service 84cb3c
#
Packit Service 84cb3c
# You should have received a copy of the GNU General Public License
Packit Service 84cb3c
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit Service 84cb3c
#
Packit Service 84cb3c
Packit Service 84cb3c
__all__ = [ "Zone", "zone_reader", "zone_writer" ]
Packit Service 84cb3c
Packit Service 84cb3c
import xml.sax as sax
Packit Service 84cb3c
import os
Packit Service 84cb3c
import io
Packit Service 84cb3c
import shutil
Packit Service 84cb3c
Packit Service 84cb3c
from firewall import config
Packit Service 84cb3c
from firewall.functions import checkIP, checkIP6, checkIPnMask, checkIP6nMask, checkInterface, uniqify, max_zone_name_len, u2b_if_py2, check_mac, portStr
Packit Service 84cb3c
from firewall.core.base import DEFAULT_ZONE_TARGET, ZONE_TARGETS
Packit Service 84cb3c
from firewall.core.io.io_object import PY2, IO_Object, \
Packit Service 84cb3c
    IO_Object_ContentHandler, IO_Object_XMLGenerator, check_port, \
Packit Service 84cb3c
    check_tcpudp, check_protocol
Packit Service 84cb3c
from firewall.core import rich
Packit Service 84cb3c
from firewall.core.logger import log
Packit Service 84cb3c
from firewall import errors
Packit Service 84cb3c
from firewall.errors import FirewallError
Packit Service 84cb3c
Packit Service 84cb3c
class Zone(IO_Object):
Packit Service 84cb3c
    """ Zone class """
Packit Service 84cb3c
Packit Service 84cb3c
    IMPORT_EXPORT_STRUCTURE = (
Packit Service 84cb3c
        ( "version",  "" ),                            # s
Packit Service 84cb3c
        ( "short", "" ),                               # s
Packit Service 84cb3c
        ( "description", "" ),                         # s
Packit Service 84cb3c
        ( "UNUSED", False ),                           # b
Packit Service 84cb3c
        ( "target", "" ),                              # s
Packit Service 84cb3c
        ( "services", [ "", ], ),                      # as
Packit Service 84cb3c
        ( "ports", [ ( "", "" ), ], ),                 # a(ss)
Packit Service 84cb3c
        ( "icmp_blocks", [ "", ], ),                   # as
Packit Service 84cb3c
        ( "masquerade", False ),                       # b
Packit Service 84cb3c
        ( "forward_ports", [ ( "", "", "", "" ), ], ), # a(ssss)
Packit Service 84cb3c
        ( "interfaces", [ "" ] ),                      # as
Packit Service 84cb3c
        ( "sources", [ "" ] ),                         # as
Packit Service 84cb3c
        ( "rules_str", [ "" ] ),                       # as
Packit Service 84cb3c
        ( "protocols", [ "", ], ),                     # as
Packit Service 84cb3c
        ( "source_ports", [ ( "", "" ), ], ),          # a(ss)
Packit Service 84cb3c
        ( "icmp_block_inversion", False ),             # b
Packit Service 84cb3c
        )
Packit Service 84cb3c
    DBUS_SIGNATURE = '(sssbsasa(ss)asba(ssss)asasasasa(ss)b)'
Packit Service 84cb3c
    ADDITIONAL_ALNUM_CHARS = [ "_", "-", "/" ]
Packit Service 84cb3c
    PARSER_REQUIRED_ELEMENT_ATTRS = {
Packit Service 84cb3c
        "short": None,
Packit Service 84cb3c
        "description": None,
Packit Service 84cb3c
        "zone": None,
Packit Service 84cb3c
        "service": [ "name" ],
Packit Service 84cb3c
        "port": [ "port", "protocol" ],
Packit Service 84cb3c
        "icmp-block": [ "name" ],
Packit Service 84cb3c
        "icmp-type": [ "name" ],
Packit Service 84cb3c
        "forward-port": [ "port", "protocol" ],
Packit Service 84cb3c
        "interface": [ "name" ],
Packit Service 84cb3c
        "rule": None,
Packit Service 84cb3c
        "source": None,
Packit Service 84cb3c
        "destination": [ "address" ],
Packit Service 84cb3c
        "protocol": [ "value" ],
Packit Service 84cb3c
        "source-port": [ "port", "protocol" ],
Packit Service 84cb3c
        "log":  None,
Packit Service 84cb3c
        "audit": None,
Packit Service 84cb3c
        "accept": None,
Packit Service 84cb3c
        "reject": None,
Packit Service 84cb3c
        "drop": None,
Packit Service 84cb3c
        "mark": [ "set" ],
Packit Service 84cb3c
        "limit": [ "value" ],
Packit Service 84cb3c
        "icmp-block-inversion": None,
Packit Service 84cb3c
        }
Packit Service 84cb3c
    PARSER_OPTIONAL_ELEMENT_ATTRS = {
Packit Service 84cb3c
        "zone": [ "name", "immutable", "target", "version" ],
Packit Service 84cb3c
        "masquerade": [ "enabled" ],
Packit Service 84cb3c
        "forward-port": [ "to-port", "to-addr" ],
Packit Service 84cb3c
        "rule": [ "family", "priority" ],
Packit Service 84cb3c
        "source": [ "address", "mac", "invert", "family", "ipset" ],
Packit Service 84cb3c
        "destination": [ "invert" ],
Packit Service 84cb3c
        "log": [ "prefix", "level" ],
Packit Service 84cb3c
        "reject": [ "type" ],
Packit Service 84cb3c
        }
Packit Service 84cb3c
Packit Service 84cb3c
    @staticmethod
Packit Service 84cb3c
    def index_of(element):
Packit Service 84cb3c
        for i, (el, dummy) in enumerate(Zone.IMPORT_EXPORT_STRUCTURE):
Packit Service 84cb3c
            if el == element:
Packit Service 84cb3c
                return i
Packit Service 84cb3c
        raise FirewallError(errors.UNKNOWN_ERROR, "index_of()")
Packit Service 84cb3c
Packit Service 84cb3c
    def __init__(self):
Packit Service 84cb3c
        super(Zone, self).__init__()
Packit Service 84cb3c
        self.version = ""
Packit Service 84cb3c
        self.short = ""
Packit Service 84cb3c
        self.description = ""
Packit Service 84cb3c
        self.UNUSED = False
Packit Service 84cb3c
        self.target = DEFAULT_ZONE_TARGET
Packit Service 84cb3c
        self.services = [ ]
Packit Service 84cb3c
        self.ports = [ ]
Packit Service 84cb3c
        self.protocols = [ ]
Packit Service 84cb3c
        self.icmp_blocks = [ ]
Packit Service 84cb3c
        self.masquerade = False
Packit Service 84cb3c
        self.forward_ports = [ ]
Packit Service 84cb3c
        self.source_ports = [ ]
Packit Service 84cb3c
        self.interfaces = [ ]
Packit Service 84cb3c
        self.sources = [ ]
Packit Service 84cb3c
        self.fw_config = None # to be able to check services and a icmp_blocks
Packit Service 84cb3c
        self.rules = [ ]
Packit Service 84cb3c
        self.icmp_block_inversion = False
Packit Service 84cb3c
        self.combined = False
Packit Service 84cb3c
        self.applied = False
Packit Service 84cb3c
Packit Service 84cb3c
    def cleanup(self):
Packit Service 84cb3c
        self.version = ""
Packit Service 84cb3c
        self.short = ""
Packit Service 84cb3c
        self.description = ""
Packit Service 84cb3c
        self.UNUSED = False
Packit Service 84cb3c
        self.target = DEFAULT_ZONE_TARGET
Packit Service 84cb3c
        del self.services[:]
Packit Service 84cb3c
        del self.ports[:]
Packit Service 84cb3c
        del self.protocols[:]
Packit Service 84cb3c
        del self.icmp_blocks[:]
Packit Service 84cb3c
        self.masquerade = False
Packit Service 84cb3c
        del self.forward_ports[:]
Packit Service 84cb3c
        del self.source_ports[:]
Packit Service 84cb3c
        del self.interfaces[:]
Packit Service 84cb3c
        del self.sources[:]
Packit Service 84cb3c
        self.fw_config = None # to be able to check services and a icmp_blocks
Packit Service 84cb3c
        del self.rules[:]
Packit Service 84cb3c
        self.icmp_block_inversion = False
Packit Service 84cb3c
        self.combined = False
Packit Service 84cb3c
        self.applied = False
Packit Service 84cb3c
Packit Service 84cb3c
    def encode_strings(self):
Packit Service 84cb3c
        """ HACK. I haven't been able to make sax parser return
Packit Service 84cb3c
            strings encoded (because of python 2) instead of in unicode.
Packit Service 84cb3c
            Get rid of it once we throw out python 2 support."""
Packit Service 84cb3c
        self.version = u2b_if_py2(self.version)
Packit Service 84cb3c
        self.short = u2b_if_py2(self.short)
Packit Service 84cb3c
        self.description = u2b_if_py2(self.description)
Packit Service 84cb3c
        self.target = u2b_if_py2(self.target)
Packit Service 84cb3c
        self.services = [u2b_if_py2(s) for s in self.services]
Packit Service 84cb3c
        self.ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr) in self.ports]
Packit Service 84cb3c
        self.protocols = [u2b_if_py2(pr) for pr in self.protocols]
Packit Service 84cb3c
        self.icmp_blocks = [u2b_if_py2(i) for i in self.icmp_blocks]
Packit Service 84cb3c
        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]
Packit Service 84cb3c
        self.source_ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr)
Packit Service 84cb3c
                             in self.source_ports]
Packit Service 84cb3c
        self.interfaces = [u2b_if_py2(i) for i in self.interfaces]
Packit Service 84cb3c
        self.sources = [u2b_if_py2(s) for s in self.sources]
Packit Service 84cb3c
        self.rules = [u2b_if_py2(s) for s in self.rules]
Packit Service 84cb3c
Packit Service 84cb3c
    def __getattr__(self, name):
Packit Service 84cb3c
        if name == "rules_str":
Packit Service 84cb3c
            rules_str = [str(rule) for rule in self.rules]
Packit Service 84cb3c
            return rules_str
Packit Service 84cb3c
        else:
Packit Service 84cb3c
            return getattr(super(Zone, self), name)
Packit Service 84cb3c
Packit Service 84cb3c
    def __setattr__(self, name, value):
Packit Service 84cb3c
        if name == "rules_str":
Packit Service 84cb3c
            self.rules = [rich.Rich_Rule(rule_str=s) for s in value]
Packit Service 84cb3c
        else:
Packit Service 84cb3c
            super(Zone, self).__setattr__(name, value)
Packit Service 84cb3c
Packit Service 84cb3c
    def _check_config(self, config, item):
Packit Service 84cb3c
        if item == "services" and self.fw_config:
Packit Service 84cb3c
            existing_services = self.fw_config.get_services()
Packit Service 84cb3c
            for service in config:
Packit Service 84cb3c
                if service not in existing_services:
Packit Service 84cb3c
                    raise FirewallError(errors.INVALID_SERVICE,
Packit Service 84cb3c
                                        "'%s' not among existing services" % \
Packit Service 84cb3c
                                        service)
Packit Service 84cb3c
        elif item == "ports":
Packit Service 84cb3c
            for port in config:
Packit Service 84cb3c
                check_port(port[0])
Packit Service 84cb3c
                check_tcpudp(port[1])
Packit Service 84cb3c
        elif item == "protocols":
Packit Service 84cb3c
            for proto in config:
Packit Service 84cb3c
                check_protocol(proto)
Packit Service 84cb3c
        elif item == "icmp_blocks" and self.fw_config:
Packit Service 84cb3c
            existing_icmptypes = self.fw_config.get_icmptypes()
Packit Service 84cb3c
            for icmptype in config:
Packit Service 84cb3c
                if icmptype not in existing_icmptypes:
Packit Service 84cb3c
                    raise FirewallError(errors.INVALID_ICMPTYPE,
Packit Service 84cb3c
                                        "'%s' not among existing icmp types" % \
Packit Service 84cb3c
                                        icmptype)
Packit Service 84cb3c
        elif item == "forward_ports":
Packit Service 84cb3c
            for fwd_port in config:
Packit Service 84cb3c
                check_port(fwd_port[0])
Packit Service 84cb3c
                check_tcpudp(fwd_port[1])
Packit Service 84cb3c
                if not fwd_port[2] and not fwd_port[3]:
Packit Service 84cb3c
                    raise FirewallError(
Packit Service 84cb3c
                        errors.INVALID_FORWARD,
Packit Service 84cb3c
                        "'%s' is missing to-port AND to-addr " % fwd_port)
Packit Service 84cb3c
                if fwd_port[2]:
Packit Service 84cb3c
                    check_port(fwd_port[2])
Packit Service 84cb3c
                if fwd_port[3]:
Packit Service 84cb3c
                    if not checkIP(fwd_port[3]) and not checkIP6(fwd_port[3]):
Packit Service 84cb3c
                        raise FirewallError(
Packit Service 84cb3c
                            errors.INVALID_ADDR,
Packit Service 84cb3c
                            "to-addr '%s' is not a valid address" % fwd_port[3])
Packit Service 84cb3c
        elif item == "source_ports":
Packit Service 84cb3c
            for port in config:
Packit Service 84cb3c
                check_port(port[0])
Packit Service 84cb3c
                check_tcpudp(port[1])
Packit Service 84cb3c
        elif item == "target":
Packit Service 84cb3c
            if config not in ZONE_TARGETS:
Packit Service 84cb3c
                raise FirewallError(errors.INVALID_TARGET, config)
Packit Service 84cb3c
        elif item == "interfaces":
Packit Service 84cb3c
            for interface in config:
Packit Service 84cb3c
                if not checkInterface(interface):
Packit Service 84cb3c
                    raise FirewallError(errors.INVALID_INTERFACE, interface)
Packit Service 84cb3c
        elif item == "sources":
Packit Service 84cb3c
            for source in config:
Packit Service 84cb3c
                if not checkIPnMask(source) and not checkIP6nMask(source) and \
Packit Service 84cb3c
                   not check_mac(source) and not source.startswith("ipset:"):
Packit Service 84cb3c
                    raise FirewallError(errors.INVALID_ADDR, source)
Packit Service 84cb3c
        elif item == "rules_str":
Packit Service 84cb3c
            for rule in config:
Packit Service 84cb3c
                rich.Rich_Rule(rule_str=rule)
Packit Service 84cb3c
Packit Service 84cb3c
    def check_name(self, name):
Packit Service 84cb3c
        super(Zone, self).check_name(name)
Packit Service 84cb3c
        if name.startswith('/'):
Packit Service 84cb3c
            raise FirewallError(errors.INVALID_NAME,
Packit Service 84cb3c
                                "'%s' can't start with '/'" % name)
Packit Service 84cb3c
        elif name.endswith('/'):
Packit Service 84cb3c
            raise FirewallError(errors.INVALID_NAME,
Packit Service 84cb3c
                                "'%s' can't end with '/'" % name)
Packit Service 84cb3c
        elif name.count('/') > 1:
Packit Service 84cb3c
            raise FirewallError(errors.INVALID_NAME,
Packit Service 84cb3c
                                "more than one '/' in '%s'" % name)
Packit Service 84cb3c
        else:
Packit Service 84cb3c
            if "/" in name:
Packit Service 84cb3c
                checked_name = name[:name.find('/')]
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                checked_name = name
Packit Service 84cb3c
            if len(checked_name) > max_zone_name_len():
Packit Service 84cb3c
                raise FirewallError(errors.INVALID_NAME,
Packit Service 84cb3c
                                    "Zone of '%s' has %d chars, max is %d %s" % (
Packit Service 84cb3c
                                    name, len(checked_name),
Packit Service 84cb3c
                                    max_zone_name_len(),
Packit Service 84cb3c
                                    self.combined))
Packit Service 84cb3c
Packit Service 84cb3c
    def combine(self, zone):
Packit Service 84cb3c
        self.combined = True
Packit Service 84cb3c
        self.filename = None
Packit Service 84cb3c
        self.version = ""
Packit Service 84cb3c
        self.short = ""
Packit Service 84cb3c
        self.description = ""
Packit Service 84cb3c
Packit Service 84cb3c
        for interface in zone.interfaces:
Packit Service 84cb3c
            if interface not in self.interfaces:
Packit Service 84cb3c
                self.interfaces.append(interface)
Packit Service 84cb3c
        for source in zone.sources:
Packit Service 84cb3c
            if source not in self.sources:
Packit Service 84cb3c
                self.sources.append(source)
Packit Service 84cb3c
        for service in zone.services:
Packit Service 84cb3c
            if service not in self.services:
Packit Service 84cb3c
                self.services.append(service)
Packit Service 84cb3c
        for port in zone.ports:
Packit Service 84cb3c
            if port not in self.ports:
Packit Service 84cb3c
                self.ports.append(port)
Packit Service 84cb3c
        for proto in zone.protocols:
Packit Service 84cb3c
            if proto not in self.protocols:
Packit Service 84cb3c
                self.protocols.append(proto)
Packit Service 84cb3c
        for icmp in zone.icmp_blocks:
Packit Service 84cb3c
            if icmp not in self.icmp_blocks:
Packit Service 84cb3c
                self.icmp_blocks.append(icmp)
Packit Service 84cb3c
        if zone.masquerade:
Packit Service 84cb3c
            self.masquerade = True
Packit Service 84cb3c
        for forward in zone.forward_ports:
Packit Service 84cb3c
            if forward not in self.forward_ports:
Packit Service 84cb3c
                self.forward_ports.append(forward)
Packit Service 84cb3c
        for port in zone.source_ports:
Packit Service 84cb3c
            if port not in self.source_ports:
Packit Service 84cb3c
                self.source_ports.append(port)
Packit Service 84cb3c
        for rule in zone.rules:
Packit Service 84cb3c
            self.rules.append(rule)
Packit Service 84cb3c
        if zone.icmp_block_inversion:
Packit Service 84cb3c
            self.icmp_block_inversion = True
Packit Service 84cb3c
Packit Service 84cb3c
# PARSER
Packit Service 84cb3c
Packit Service 84cb3c
class zone_ContentHandler(IO_Object_ContentHandler):
Packit Service 84cb3c
    def __init__(self, item):
Packit Service 84cb3c
        IO_Object_ContentHandler.__init__(self, item)
Packit Service 84cb3c
        self._rule = None
Packit Service 84cb3c
        self._rule_error = False
Packit Service 84cb3c
        self._limit_ok = None
Packit Service 84cb3c
Packit Service 84cb3c
    def startElement(self, name, attrs):
Packit Service 84cb3c
        IO_Object_ContentHandler.startElement(self, name, attrs)
Packit Service 84cb3c
        if self._rule_error:
Packit Service 84cb3c
            return
Packit Service 84cb3c
Packit Service 84cb3c
        self.item.parser_check_element_attrs(name, attrs)
Packit Service 84cb3c
Packit Service 84cb3c
        if name == "zone":
Packit Service 84cb3c
            if "name" in attrs:
Packit Service 84cb3c
                log.warning("Ignoring deprecated attribute name='%s'",
Packit Service 84cb3c
                            attrs["name"])
Packit Service 84cb3c
            if "version" in attrs:
Packit Service 84cb3c
                self.item.version = attrs["version"]
Packit Service 84cb3c
            if "immutable" in attrs:
Packit Service 84cb3c
                log.warning("Ignoring deprecated attribute immutable='%s'",
Packit Service 84cb3c
                            attrs["immutable"])
Packit Service 84cb3c
            if "target" in attrs:
Packit Service 84cb3c
                target = attrs["target"]
Packit Service 84cb3c
                if target not in ZONE_TARGETS:
Packit Service 84cb3c
                    raise FirewallError(errors.INVALID_TARGET, target)
Packit Service 84cb3c
                if target != "" and target != DEFAULT_ZONE_TARGET:
Packit Service 84cb3c
                    self.item.target = target
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "short":
Packit Service 84cb3c
            pass
Packit Service 84cb3c
        elif name == "description":
Packit Service 84cb3c
            pass
Packit Service 84cb3c
        elif name == "service":
Packit Service 84cb3c
            if self._rule:
Packit Service 84cb3c
                if self._rule.element:
Packit Service 84cb3c
                    log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
Packit Service 84cb3c
                                str(self._rule))
Packit Service 84cb3c
                    self._rule_error = True
Packit Service 84cb3c
                    return
Packit Service 84cb3c
                self._rule.element = rich.Rich_Service(attrs["name"])
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if attrs["name"] not in self.item.services:
Packit Service 84cb3c
                self.item.services.append(attrs["name"])
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                log.warning("Service '%s' already set, ignoring.",
Packit Service 84cb3c
                            attrs["name"])
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "port":
Packit Service 84cb3c
            if self._rule:
Packit Service 84cb3c
                if self._rule.element:
Packit Service 84cb3c
                    log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
Packit Service 84cb3c
                                str(self._rule))
Packit Service 84cb3c
                    self._rule_error = True
Packit Service 84cb3c
                    return
Packit Service 84cb3c
                self._rule.element = rich.Rich_Port(attrs["port"],
Packit Service 84cb3c
                                                    attrs["protocol"])
Packit Service 84cb3c
                return
Packit Service 84cb3c
            check_port(attrs["port"])
Packit Service 84cb3c
            check_tcpudp(attrs["protocol"])
Packit Service 84cb3c
            entry = (portStr(attrs["port"], "-"), attrs["protocol"])
Packit Service 84cb3c
            if entry not in self.item.ports:
Packit Service 84cb3c
                self.item.ports.append(entry)
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                log.warning("Port '%s/%s' already set, ignoring.",
Packit Service 84cb3c
                            attrs["port"], attrs["protocol"])
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "protocol":
Packit Service 84cb3c
            if self._rule:
Packit Service 84cb3c
                if self._rule.element:
Packit Service 84cb3c
                    log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
Packit Service 84cb3c
                                str(self._rule))
Packit Service 84cb3c
                    self._rule_error = True
Packit Service 84cb3c
                    return
Packit Service 84cb3c
                self._rule.element = rich.Rich_Protocol(attrs["value"])
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                check_protocol(attrs["value"])
Packit Service 84cb3c
                if attrs["value"] not in self.item.protocols:
Packit Service 84cb3c
                    self.item.protocols.append(attrs["value"])
Packit Service 84cb3c
                else:
Packit Service 84cb3c
                    log.warning("Protocol '%s' already set, ignoring.",
Packit Service 84cb3c
                                attrs["value"])
Packit Service 84cb3c
        elif name == "icmp-block":
Packit Service 84cb3c
            if self._rule:
Packit Service 84cb3c
                if self._rule.element:
Packit Service 84cb3c
                    log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
Packit Service 84cb3c
                                str(self._rule))
Packit Service 84cb3c
                    self._rule_error = True
Packit Service 84cb3c
                    return
Packit Service 84cb3c
                self._rule.element = rich.Rich_IcmpBlock(attrs["name"])
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if attrs["name"] not in self.item.icmp_blocks:
Packit Service 84cb3c
                self.item.icmp_blocks.append(attrs["name"])
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                log.warning("icmp-block '%s' already set, ignoring.",
Packit Service 84cb3c
                            attrs["name"])
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "icmp-type":
Packit Service 84cb3c
            if self._rule:
Packit Service 84cb3c
                if self._rule.element:
Packit Service 84cb3c
                    log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
Packit Service 84cb3c
                                str(self._rule))
Packit Service 84cb3c
                    self._rule_error = True
Packit Service 84cb3c
                    return
Packit Service 84cb3c
                self._rule.element = rich.Rich_IcmpType(attrs["name"])
Packit Service 84cb3c
                return
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                log.warning("Invalid rule: icmp-block '%s' outside of rule",
Packit Service 84cb3c
                            attrs["name"])
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "masquerade":
Packit Service 84cb3c
            if "enabled" in attrs and \
Packit Service 84cb3c
               attrs["enabled"].lower() in [ "no", "false" ] :
Packit Service 84cb3c
                log.warning("Ignoring deprecated attribute enabled='%s'",
Packit Service 84cb3c
                            attrs["enabled"])
Packit Service 84cb3c
                return
Packit Service 84cb3c
Packit Service 84cb3c
            if self._rule:
Packit Service 84cb3c
                if self._rule.element:
Packit Service 84cb3c
                    log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
Packit Service 84cb3c
                                str(self._rule))
Packit Service 84cb3c
                    self._rule_error = True
Packit Service 84cb3c
                    return
Packit Service 84cb3c
                self._rule.element = rich.Rich_Masquerade()
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                if self.item.masquerade:
Packit Service 84cb3c
                    log.warning("Masquerade already set, ignoring.")
Packit Service 84cb3c
                else:
Packit Service 84cb3c
                    self.item.masquerade = True
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "forward-port":
Packit Service 84cb3c
            to_port = ""
Packit Service 84cb3c
            if "to-port" in attrs:
Packit Service 84cb3c
                to_port = attrs["to-port"]
Packit Service 84cb3c
            to_addr = ""
Packit Service 84cb3c
            if "to-addr" in attrs:
Packit Service 84cb3c
                to_addr = attrs["to-addr"]
Packit Service 84cb3c
Packit Service 84cb3c
            if self._rule:
Packit Service 84cb3c
                if self._rule.element:
Packit Service 84cb3c
                    log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
Packit Service 84cb3c
                                str(self._rule))
Packit Service 84cb3c
                    self._rule_error = True
Packit Service 84cb3c
                    return
Packit Service 84cb3c
                self._rule.element = rich.Rich_ForwardPort(attrs["port"],
Packit Service 84cb3c
                                                           attrs["protocol"],
Packit Service 84cb3c
                                                           to_port, to_addr)
Packit Service 84cb3c
                return
Packit Service 84cb3c
Packit Service 84cb3c
            check_port(attrs["port"])
Packit Service 84cb3c
            check_tcpudp(attrs["protocol"])
Packit Service 84cb3c
            if to_port:
Packit Service 84cb3c
                check_port(to_port)
Packit Service 84cb3c
            if to_addr:
Packit Service 84cb3c
                if not checkIP(to_addr) and not checkIP6(to_addr):
Packit Service 84cb3c
                    raise FirewallError(errors.INVALID_ADDR,
Packit Service 84cb3c
                                        "to-addr '%s' is not a valid address" \
Packit Service 84cb3c
                                        % to_addr)
Packit Service 84cb3c
            entry = (portStr(attrs["port"], "-"), attrs["protocol"],
Packit Service 84cb3c
                     portStr(to_port, "-"), str(to_addr))
Packit Service 84cb3c
            if entry not in self.item.forward_ports:
Packit Service 84cb3c
                self.item.forward_ports.append(entry)
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                log.warning("Forward port %s/%s%s%s already set, ignoring.",
Packit Service 84cb3c
                            attrs["port"], attrs["protocol"],
Packit Service 84cb3c
                            " >%s" % to_port if to_port else "",
Packit Service 84cb3c
                            " @%s" % to_addr if to_addr else "")
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "source-port":
Packit Service 84cb3c
            if self._rule:
Packit Service 84cb3c
                if self._rule.element:
Packit Service 84cb3c
                    log.warning("Invalid rule: More than one element in rule '%s', ignoring.",
Packit Service 84cb3c
                                str(self._rule))
Packit Service 84cb3c
                    self._rule_error = True
Packit Service 84cb3c
                    return
Packit Service 84cb3c
                self._rule.element = rich.Rich_SourcePort(attrs["port"],
Packit Service 84cb3c
                                                          attrs["protocol"])
Packit Service 84cb3c
                return
Packit Service 84cb3c
            check_port(attrs["port"])
Packit Service 84cb3c
            check_tcpudp(attrs["protocol"])
Packit Service 84cb3c
            entry = (portStr(attrs["port"], "-"), attrs["protocol"])
Packit Service 84cb3c
            if entry not in self.item.source_ports:
Packit Service 84cb3c
                self.item.source_ports.append(entry)
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                log.warning("Source port '%s/%s' already set, ignoring.",
Packit Service 84cb3c
                            attrs["port"], attrs["protocol"])
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "interface":
Packit Service 84cb3c
            if self._rule:
Packit Service 84cb3c
                log.warning('Invalid rule: interface use in rule.')
Packit Service 84cb3c
                self._rule_error = True
Packit Service 84cb3c
                return
Packit Service 84cb3c
            # zone bound to interface
Packit Service 84cb3c
            if "name" not in attrs:
Packit Service 84cb3c
                log.warning('Invalid interface: Name missing.')
Packit Service 84cb3c
                self._rule_error = True
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if attrs["name"] not in self.item.interfaces:
Packit Service 84cb3c
                self.item.interfaces.append(attrs["name"])
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                log.warning("Interface '%s' already set, ignoring.",
Packit Service 84cb3c
                            attrs["name"])
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "source":
Packit Service 84cb3c
            if self._rule:
Packit Service 84cb3c
                if self._rule.source:
Packit Service 84cb3c
                    log.warning("Invalid rule: More than one source in rule '%s', ignoring.",
Packit Service 84cb3c
                                str(self._rule))
Packit Service 84cb3c
                    self._rule_error = True
Packit Service 84cb3c
                    return
Packit Service 84cb3c
                invert = False
Packit Service 84cb3c
                if "invert" in attrs and \
Packit Service 84cb3c
                        attrs["invert"].lower() in [ "yes", "true" ]:
Packit Service 84cb3c
                    invert = True
Packit Service 84cb3c
                addr = mac = ipset = None
Packit Service 84cb3c
                if "address" in attrs:
Packit Service 84cb3c
                    addr = attrs["address"]
Packit Service 84cb3c
                if "mac" in attrs:
Packit Service 84cb3c
                    mac = attrs["mac"]
Packit Service 84cb3c
                if "ipset" in attrs:
Packit Service 84cb3c
                    ipset = attrs["ipset"]
Packit Service 84cb3c
                self._rule.source = rich.Rich_Source(addr, mac, ipset,
Packit Service 84cb3c
                                                     invert=invert)
Packit Service 84cb3c
                return
Packit Service 84cb3c
            # zone bound to source
Packit Service 84cb3c
            if "address" not in attrs and "ipset" not in attrs:
Packit Service 84cb3c
                log.warning('Invalid source: No address no ipset.')
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if "address" in attrs and "ipset" in attrs:
Packit Service 84cb3c
                log.warning('Invalid source: Address and ipset.')
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if "family" in attrs:
Packit Service 84cb3c
                log.warning("Ignoring deprecated attribute family='%s'",
Packit Service 84cb3c
                            attrs["family"])
Packit Service 84cb3c
            if "invert" in attrs:
Packit Service 84cb3c
                log.warning('Invalid source: Invertion not allowed here.')
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if "address" in attrs:
Packit Service 84cb3c
                if not checkIPnMask(attrs["address"]) and \
Packit Service 84cb3c
                   not checkIP6nMask(attrs["address"]) and \
Packit Service 84cb3c
                   not check_mac(attrs["address"]):
Packit Service 84cb3c
                    raise FirewallError(errors.INVALID_ADDR, attrs["address"])
Packit Service 84cb3c
            if "ipset" in attrs:
Packit Service 84cb3c
                entry = "ipset:%s" % attrs["ipset"]
Packit Service 84cb3c
                if entry not in self.item.sources:
Packit Service 84cb3c
                    self.item.sources.append(entry)
Packit Service 84cb3c
                else:
Packit Service 84cb3c
                    log.warning("Source '%s' already set, ignoring.",
Packit Service 84cb3c
                                attrs["address"])
Packit Service 84cb3c
            if "address" in attrs:
Packit Service 84cb3c
                entry = attrs["address"]
Packit Service 84cb3c
                if entry not in self.item.sources:
Packit Service 84cb3c
                    self.item.sources.append(entry)
Packit Service 84cb3c
                else:
Packit Service 84cb3c
                    log.warning("Source '%s' already set, ignoring.",
Packit Service 84cb3c
                                attrs["address"])
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "destination":
Packit Service 84cb3c
            if not self._rule:
Packit Service 84cb3c
                log.warning('Invalid rule: Destination outside of rule')
Packit Service 84cb3c
                self._rule_error = True
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if self._rule.destination:
Packit Service 84cb3c
                log.warning("Invalid rule: More than one destination in rule '%s', ignoring.",
Packit Service 84cb3c
                            str(self._rule))
Packit Service 84cb3c
                return
Packit Service 84cb3c
            invert = False
Packit Service 84cb3c
            if "invert" in attrs and \
Packit Service 84cb3c
                    attrs["invert"].lower() in [ "yes", "true" ]:
Packit Service 84cb3c
                invert = True
Packit Service 84cb3c
            self._rule.destination = rich.Rich_Destination(attrs["address"],
Packit Service 84cb3c
                                                           invert)
Packit Service 84cb3c
Packit Service 84cb3c
        elif name in [ "accept", "reject", "drop", "mark" ]:
Packit Service 84cb3c
            if not self._rule:
Packit Service 84cb3c
                log.warning('Invalid rule: Action outside of rule')
Packit Service 84cb3c
                self._rule_error = True
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if self._rule.action:
Packit Service 84cb3c
                log.warning('Invalid rule: More than one action')
Packit Service 84cb3c
                self._rule_error = True
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if name == "accept":
Packit Service 84cb3c
                self._rule.action = rich.Rich_Accept()
Packit Service 84cb3c
            elif name == "reject":
Packit Service 84cb3c
                _type = None
Packit Service 84cb3c
                if "type" in attrs:
Packit Service 84cb3c
                    _type = attrs["type"]
Packit Service 84cb3c
                self._rule.action = rich.Rich_Reject(_type)
Packit Service 84cb3c
            elif name == "drop":
Packit Service 84cb3c
                self._rule.action = rich.Rich_Drop()
Packit Service 84cb3c
            elif name == "mark":
Packit Service 84cb3c
                _set = attrs["set"]
Packit Service 84cb3c
                self._rule.action = rich.Rich_Mark(_set)
Packit Service 84cb3c
            self._limit_ok = self._rule.action
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "log":
Packit Service 84cb3c
            if not self._rule:
Packit Service 84cb3c
                log.warning('Invalid rule: Log outside of rule')
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if self._rule.log:
Packit Service 84cb3c
                log.warning('Invalid rule: More than one log')
Packit Service 84cb3c
                return
Packit Service 84cb3c
            level = None
Packit Service 84cb3c
            if "level" in attrs:
Packit Service 84cb3c
                level = attrs["level"]
Packit Service 84cb3c
                if level not in [ "emerg", "alert", "crit", "error",
Packit Service 84cb3c
                                  "warning", "notice", "info", "debug" ]:
Packit Service 84cb3c
                    log.warning('Invalid rule: Invalid log level')
Packit Service 84cb3c
                    self._rule_error = True
Packit Service 84cb3c
                    return
Packit Service 84cb3c
            prefix = attrs["prefix"] if "prefix" in attrs else None
Packit Service 84cb3c
            self._rule.log = rich.Rich_Log(prefix, level)
Packit Service 84cb3c
            self._limit_ok = self._rule.log
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "audit":
Packit Service 84cb3c
            if not self._rule:
Packit Service 84cb3c
                log.warning('Invalid rule: Audit outside of rule')
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if self._rule.audit:
Packit Service 84cb3c
                log.warning("Invalid rule: More than one audit in rule '%s', ignoring.",
Packit Service 84cb3c
                            str(self._rule))
Packit Service 84cb3c
                self._rule_error = True
Packit Service 84cb3c
                return
Packit Service 84cb3c
            self._rule.audit = rich.Rich_Audit()
Packit Service 84cb3c
            self._limit_ok = self._rule.audit
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "rule":
Packit Service 84cb3c
            family = None
Packit Service 84cb3c
            priority = 0
Packit Service 84cb3c
            if "family" in attrs:
Packit Service 84cb3c
                family = attrs["family"]
Packit Service 84cb3c
                if family not in [ "ipv4", "ipv6" ]:
Packit Service 84cb3c
                    log.warning('Invalid rule: Rule family "%s" invalid',
Packit Service 84cb3c
                                attrs["family"])
Packit Service 84cb3c
                    self._rule_error = True
Packit Service 84cb3c
                    return
Packit Service 84cb3c
            if "priority" in attrs:
Packit Service 84cb3c
                priority = int(attrs["priority"])
Packit Service 84cb3c
            self._rule = rich.Rich_Rule(family=family, priority=priority)
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "limit":
Packit Service 84cb3c
            if not self._limit_ok:
Packit Service 84cb3c
                log.warning('Invalid rule: Limit outside of action, log and audit')
Packit Service 84cb3c
                self._rule_error = True
Packit Service 84cb3c
                return
Packit Service 84cb3c
            if self._limit_ok.limit:
Packit Service 84cb3c
                log.warning("Invalid rule: More than one limit in rule '%s', ignoring.",
Packit Service 84cb3c
                            str(self._rule))
Packit Service 84cb3c
                self._rule_error = True
Packit Service 84cb3c
                return
Packit Service 84cb3c
            value = attrs["value"]
Packit Service 84cb3c
            self._limit_ok.limit = rich.Rich_Limit(value)
Packit Service 84cb3c
Packit Service 84cb3c
        elif name == "icmp-block-inversion":
Packit Service 84cb3c
            if self.item.icmp_block_inversion:
Packit Service 84cb3c
                log.warning("Icmp-Block-Inversion already set, ignoring.")
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                self.item.icmp_block_inversion = True
Packit Service 84cb3c
Packit Service 84cb3c
        else:
Packit Service 84cb3c
            log.warning("Unknown XML element '%s'", name)
Packit Service 84cb3c
            return
Packit Service 84cb3c
Packit Service 84cb3c
    def endElement(self, name):
Packit Service 84cb3c
        IO_Object_ContentHandler.endElement(self, name)
Packit Service 84cb3c
Packit Service 84cb3c
        if name == "rule":
Packit Service 84cb3c
            if not self._rule_error:
Packit Service 84cb3c
                try:
Packit Service 84cb3c
                    self._rule.check()
Packit Service 84cb3c
                except Exception as e:
Packit Service 84cb3c
                    log.warning("%s: %s", e, str(self._rule))
Packit Service 84cb3c
                else:
Packit Service 84cb3c
                    if str(self._rule) not in \
Packit Service 84cb3c
                       [ str(x) for x in self.item.rules ]:
Packit Service 84cb3c
                        self.item.rules.append(self._rule)
Packit Service 84cb3c
                    else:
Packit Service 84cb3c
                        log.warning("Rule '%s' already set, ignoring.",
Packit Service 84cb3c
                                    str(self._rule))
Packit Service 84cb3c
            self._rule = None
Packit Service 84cb3c
            self._rule_error = False
Packit Service 84cb3c
        elif name in [ "accept", "reject", "drop", "mark", "log", "audit" ]:
Packit Service 84cb3c
            self._limit_ok = None
Packit Service 84cb3c
Packit Service 84cb3c
def zone_reader(filename, path, no_check_name=False):
Packit Service 84cb3c
    zone = Zone()
Packit Service 84cb3c
    if not filename.endswith(".xml"):
Packit Service 84cb3c
        raise FirewallError(errors.INVALID_NAME,
Packit Service 84cb3c
                            "'%s' is missing .xml suffix" % filename)
Packit Service 84cb3c
    zone.name = filename[:-4]
Packit Service 84cb3c
    if not no_check_name:
Packit Service 84cb3c
        zone.check_name(zone.name)
Packit Service 84cb3c
    zone.filename = filename
Packit Service 84cb3c
    zone.path = path
Packit Service 84cb3c
    zone.builtin = False if path.startswith(config.ETC_FIREWALLD) else True
Packit Service 84cb3c
    zone.default = zone.builtin
Packit Service 84cb3c
    handler = zone_ContentHandler(zone)
Packit Service 84cb3c
    parser = sax.make_parser()
Packit Service 84cb3c
    parser.setContentHandler(handler)
Packit Service 84cb3c
    name = "%s/%s" % (path, filename)
Packit Service 84cb3c
    with open(name, "rb") as f:
Packit Service 84cb3c
        source = sax.InputSource(None)
Packit Service 84cb3c
        source.setByteStream(f)
Packit Service 84cb3c
        try:
Packit Service 84cb3c
            parser.parse(source)
Packit Service 84cb3c
        except sax.SAXParseException as msg:
Packit Service 84cb3c
            raise FirewallError(errors.INVALID_ZONE,
Packit Service 84cb3c
                                "not a valid zone file: %s" % \
Packit Service 84cb3c
                                msg.getException())
Packit Service 84cb3c
    del handler
Packit Service 84cb3c
    del parser
Packit Service 84cb3c
    if PY2:
Packit Service 84cb3c
        zone.encode_strings()
Packit Service 84cb3c
    return zone
Packit Service 84cb3c
Packit Service 84cb3c
def zone_writer(zone, path=None):
Packit Service 84cb3c
    _path = path if path else zone.path
Packit Service 84cb3c
Packit Service 84cb3c
    if zone.filename:
Packit Service 84cb3c
        name = "%s/%s" % (_path, zone.filename)
Packit Service 84cb3c
    else:
Packit Service 84cb3c
        name = "%s/%s.xml" % (_path, zone.name)
Packit Service 84cb3c
Packit Service 84cb3c
    if os.path.exists(name):
Packit Service 84cb3c
        try:
Packit Service 84cb3c
            shutil.copy2(name, "%s.old" % name)
Packit Service 84cb3c
        except Exception as msg:
Packit Service 84cb3c
            log.error("Backup of file '%s' failed: %s", name, msg)
Packit Service 84cb3c
Packit Service 84cb3c
    dirpath = os.path.dirname(name)
Packit Service 84cb3c
    if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath):
Packit Service 84cb3c
        if not os.path.exists(config.ETC_FIREWALLD):
Packit Service 84cb3c
            os.mkdir(config.ETC_FIREWALLD, 0o750)
Packit Service 84cb3c
        os.mkdir(dirpath, 0o750)
Packit Service 84cb3c
Packit Service 84cb3c
    f = io.open(name, mode='wt', encoding='UTF-8')
Packit Service 84cb3c
    handler = IO_Object_XMLGenerator(f)
Packit Service 84cb3c
    handler.startDocument()
Packit Service 84cb3c
Packit Service 84cb3c
    # start zone element
Packit Service 84cb3c
    attrs = {}
Packit Service 84cb3c
    if zone.version and zone.version != "":
Packit Service 84cb3c
        attrs["version"] = zone.version
Packit Service 84cb3c
    if zone.target != DEFAULT_ZONE_TARGET:
Packit Service 84cb3c
        attrs["target"] = zone.target
Packit Service 84cb3c
    handler.startElement("zone", attrs)
Packit Service 84cb3c
    handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # short
Packit Service 84cb3c
    if zone.short and zone.short != "":
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.startElement("short", { })
Packit Service 84cb3c
        handler.characters(zone.short)
Packit Service 84cb3c
        handler.endElement("short")
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # description
Packit Service 84cb3c
    if zone.description and zone.description != "":
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.startElement("description", { })
Packit Service 84cb3c
        handler.characters(zone.description)
Packit Service 84cb3c
        handler.endElement("description")
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # interfaces
Packit Service 84cb3c
    for interface in uniqify(zone.interfaces):
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.simpleElement("interface", { "name": interface })
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # source
Packit Service 84cb3c
    for source in uniqify(zone.sources):
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        if "ipset:" in source:
Packit Service 84cb3c
            handler.simpleElement("source", { "ipset": source[6:] })
Packit Service 84cb3c
        else:
Packit Service 84cb3c
            handler.simpleElement("source", { "address": source })
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # services
Packit Service 84cb3c
    for service in uniqify(zone.services):
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.simpleElement("service", { "name": service })
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # ports
Packit Service 84cb3c
    for port in uniqify(zone.ports):
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.simpleElement("port", { "port": port[0], "protocol": port[1] })
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # protocols
Packit Service 84cb3c
    for protocol in uniqify(zone.protocols):
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.simpleElement("protocol", { "value": protocol })
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # icmp-block-inversion
Packit Service 84cb3c
    if zone.icmp_block_inversion:
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.simpleElement("icmp-block-inversion", { })
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # icmp-blocks
Packit Service 84cb3c
    for icmp in uniqify(zone.icmp_blocks):
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.simpleElement("icmp-block", { "name": icmp })
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # masquerade
Packit Service 84cb3c
    if zone.masquerade:
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.simpleElement("masquerade", { })
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # forward-ports
Packit Service 84cb3c
    for forward in uniqify(zone.forward_ports):
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        attrs = { "port": forward[0], "protocol": forward[1] }
Packit Service 84cb3c
        if forward[2] and forward[2] != "" :
Packit Service 84cb3c
            attrs["to-port"] = forward[2]
Packit Service 84cb3c
        if forward[3] and forward[3] != "" :
Packit Service 84cb3c
            attrs["to-addr"] = forward[3]
Packit Service 84cb3c
        handler.simpleElement("forward-port", attrs)
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # source-ports
Packit Service 84cb3c
    for port in uniqify(zone.source_ports):
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.simpleElement("source-port", { "port": port[0],
Packit Service 84cb3c
                                               "protocol": port[1] })
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # rules
Packit Service 84cb3c
    for rule in zone.rules:
Packit Service 84cb3c
        attrs = { }
Packit Service 84cb3c
        if rule.family:
Packit Service 84cb3c
            attrs["family"] = rule.family
Packit Service 84cb3c
        if rule.priority != 0:
Packit Service 84cb3c
            attrs["priority"] = str(rule.priority)
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.startElement("rule", attrs)
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
        # source
Packit Service 84cb3c
        if rule.source:
Packit Service 84cb3c
            attrs = { }
Packit Service 84cb3c
            if rule.source.addr:
Packit Service 84cb3c
                attrs["address"] = rule.source.addr
Packit Service 84cb3c
            if rule.source.mac:
Packit Service 84cb3c
                attrs["mac"] = rule.source.mac
Packit Service 84cb3c
            if rule.source.ipset:
Packit Service 84cb3c
                attrs["ipset"] = rule.source.ipset
Packit Service 84cb3c
            if rule.source.invert:
Packit Service 84cb3c
                attrs["invert"] = "True"
Packit Service 84cb3c
            handler.ignorableWhitespace("    ")
Packit Service 84cb3c
            handler.simpleElement("source", attrs)
Packit Service 84cb3c
            handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
        # destination
Packit Service 84cb3c
        if rule.destination:
Packit Service 84cb3c
            attrs = { "address": rule.destination.addr }
Packit Service 84cb3c
            if rule.destination.invert:
Packit Service 84cb3c
                attrs["invert"] = "True"
Packit Service 84cb3c
            handler.ignorableWhitespace("    ")
Packit Service 84cb3c
            handler.simpleElement("destination", attrs)
Packit Service 84cb3c
            handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
        # element
Packit Service 84cb3c
        if rule.element:
Packit Service 84cb3c
            element = ""
Packit Service 84cb3c
            attrs = { }
Packit Service 84cb3c
Packit Service 84cb3c
            if type(rule.element) == rich.Rich_Service:
Packit Service 84cb3c
                element = "service"
Packit Service 84cb3c
                attrs["name"] = rule.element.name
Packit Service 84cb3c
            elif type(rule.element) == rich.Rich_Port:
Packit Service 84cb3c
                element = "port"
Packit Service 84cb3c
                attrs["port"] = rule.element.port
Packit Service 84cb3c
                attrs["protocol"] = rule.element.protocol
Packit Service 84cb3c
            elif type(rule.element) == rich.Rich_Protocol:
Packit Service 84cb3c
                element = "protocol"
Packit Service 84cb3c
                attrs["value"] = rule.element.value
Packit Service 84cb3c
            elif type(rule.element) == rich.Rich_Masquerade:
Packit Service 84cb3c
                element = "masquerade"
Packit Service 84cb3c
            elif type(rule.element) == rich.Rich_IcmpBlock:
Packit Service 84cb3c
                element = "icmp-block"
Packit Service 84cb3c
                attrs["name"] = rule.element.name
Packit Service 84cb3c
            elif type(rule.element) == rich.Rich_IcmpType:
Packit Service 84cb3c
                element = "icmp-type"
Packit Service 84cb3c
                attrs["name"] = rule.element.name
Packit Service 84cb3c
            elif type(rule.element) == rich.Rich_ForwardPort:
Packit Service 84cb3c
                element = "forward-port"
Packit Service 84cb3c
                attrs["port"] = rule.element.port
Packit Service 84cb3c
                attrs["protocol"] = rule.element.protocol
Packit Service 84cb3c
                if rule.element.to_port != "":
Packit Service 84cb3c
                    attrs["to-port"] = rule.element.to_port
Packit Service 84cb3c
                if rule.element.to_address != "":
Packit Service 84cb3c
                    attrs["to-addr"] = rule.element.to_address
Packit Service 84cb3c
            elif type(rule.element) == rich.Rich_SourcePort:
Packit Service 84cb3c
                element = "source-port"
Packit Service 84cb3c
                attrs["port"] = rule.element.port
Packit Service 84cb3c
                attrs["protocol"] = rule.element.protocol
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                raise FirewallError(
Packit Service 84cb3c
                    errors.INVALID_OBJECT,
Packit Service 84cb3c
                    "Unknown element '%s' in zone_writer" % type(rule.element))
Packit Service 84cb3c
Packit Service 84cb3c
            handler.ignorableWhitespace("    ")
Packit Service 84cb3c
            handler.simpleElement(element, attrs)
Packit Service 84cb3c
            handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
        # rule.element
Packit Service 84cb3c
Packit Service 84cb3c
        # log
Packit Service 84cb3c
        if rule.log:
Packit Service 84cb3c
            attrs = { }
Packit Service 84cb3c
            if rule.log.prefix:
Packit Service 84cb3c
                attrs["prefix"] = rule.log.prefix
Packit Service 84cb3c
            if rule.log.level:
Packit Service 84cb3c
                attrs["level"] = rule.log.level
Packit Service 84cb3c
            if rule.log.limit:
Packit Service 84cb3c
                handler.ignorableWhitespace("    ")
Packit Service 84cb3c
                handler.startElement("log", attrs)
Packit Service 84cb3c
                handler.ignorableWhitespace("\n      ")
Packit Service 84cb3c
                handler.simpleElement("limit",
Packit Service 84cb3c
                                      { "value": rule.log.limit.value })
Packit Service 84cb3c
                handler.ignorableWhitespace("\n    ")
Packit Service 84cb3c
                handler.endElement("log")
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                handler.ignorableWhitespace("    ")
Packit Service 84cb3c
                handler.simpleElement("log", attrs)
Packit Service 84cb3c
            handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
        # audit
Packit Service 84cb3c
        if rule.audit:
Packit Service 84cb3c
            attrs = {}
Packit Service 84cb3c
            if rule.audit.limit:
Packit Service 84cb3c
                handler.ignorableWhitespace("    ")
Packit Service 84cb3c
                handler.startElement("audit", { })
Packit Service 84cb3c
                handler.ignorableWhitespace("\n      ")
Packit Service 84cb3c
                handler.simpleElement("limit",
Packit Service 84cb3c
                                      { "value": rule.audit.limit.value })
Packit Service 84cb3c
                handler.ignorableWhitespace("\n    ")
Packit Service 84cb3c
                handler.endElement("audit")
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                handler.ignorableWhitespace("    ")
Packit Service 84cb3c
                handler.simpleElement("audit", attrs)
Packit Service 84cb3c
            handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
        # action
Packit Service 84cb3c
        if rule.action:
Packit Service 84cb3c
            action = ""
Packit Service 84cb3c
            attrs = { }
Packit Service 84cb3c
            if type(rule.action) == rich.Rich_Accept:
Packit Service 84cb3c
                action = "accept"
Packit Service 84cb3c
            elif type(rule.action) == rich.Rich_Reject:
Packit Service 84cb3c
                action = "reject"
Packit Service 84cb3c
                if rule.action.type:
Packit Service 84cb3c
                    attrs["type"] = rule.action.type
Packit Service 84cb3c
            elif type(rule.action) == rich.Rich_Drop:
Packit Service 84cb3c
                action = "drop"
Packit Service 84cb3c
            elif type(rule.action) == rich.Rich_Mark:
Packit Service 84cb3c
                action = "mark"
Packit Service 84cb3c
                attrs["set"] = rule.action.set
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                log.warning("Unknown action '%s'", type(rule.action))
Packit Service 84cb3c
            if rule.action.limit:
Packit Service 84cb3c
                handler.ignorableWhitespace("    ")
Packit Service 84cb3c
                handler.startElement(action, attrs)
Packit Service 84cb3c
                handler.ignorableWhitespace("\n      ")
Packit Service 84cb3c
                handler.simpleElement("limit",
Packit Service 84cb3c
                                      { "value": rule.action.limit.value })
Packit Service 84cb3c
                handler.ignorableWhitespace("\n    ")
Packit Service 84cb3c
                handler.endElement(action)
Packit Service 84cb3c
            else:
Packit Service 84cb3c
                handler.ignorableWhitespace("    ")
Packit Service 84cb3c
                handler.simpleElement(action, attrs)
Packit Service 84cb3c
            handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
        handler.ignorableWhitespace("  ")
Packit Service 84cb3c
        handler.endElement("rule")
Packit Service 84cb3c
        handler.ignorableWhitespace("\n")
Packit Service 84cb3c
Packit Service 84cb3c
    # end zone element
Packit Service 84cb3c
    handler.endElement("zone")
Packit Service 84cb3c
    handler.ignorableWhitespace("\n")
Packit Service 84cb3c
    handler.endDocument()
Packit Service 84cb3c
    f.close()
Packit Service 84cb3c
    del handler