Failed to save the file to the "xx" directory.

Failed to save the file to the "ll" directory.

Failed to save the file to the "mm" directory.

Failed to save the file to the "wp" directory.

403WebShell
403Webshell
Server IP : 66.29.132.124  /  Your IP : 3.149.240.101
Web Server : LiteSpeed
System : Linux business141.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64
User : wavevlvu ( 1524)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /usr/lib/python3.6/site-packages/firewall/core/io/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/lib/python3.6/site-packages/firewall/core/io/ipset.py
# -*- 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

Youez - 2016 - github.com/yon3zu
LinuXploit