def _check_config(self, config, item): if item == "services" and self.fw_config: existing_services = self.fw_config.get_services() for service in config: if not service in existing_services: raise FirewallError(INVALID_SERVICE, service) elif item == "ports": for port in config: check_port(port[0]) check_protocol(port[1]) elif item == "icmp_blocks" and self.fw_config: existing_icmptypes = self.fw_config.get_icmptypes() for icmptype in config: if not icmptype in existing_icmptypes: raise FirewallError(INVALID_ICMPTYPE, icmptype) elif item == "forward_ports": for fwd_port in config: check_port(fwd_port[0]) check_protocol(fwd_port[1]) if not fwd_port[2] and not fwd_port[3]: raise FirewallError(INVALID_FORWARD, fwd_port) if fwd_port[2]: check_port(fwd_port[2]) if fwd_port[3]: if not checkIP(fwd_port[3]): raise FirewallError(INVALID_ADDR, fwd_port[3])
def common_check_config(obj, config, item, all_config): 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))
def _check_config(self, config, item): if item == "services" and self.fw_config: existing_services = self.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 self.fw_config: existing_icmptypes = self.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 == "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) 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) elif item == "rules_str": for rule in config: rich.Rich_Rule(rule_str=rule)
def _check_config(self, config, item): if item == "services" and self.fw_config: existing_services = self.fw_config.get_services() for service in config: if not service 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 self.fw_config: existing_icmptypes = self.fw_config.get_icmptypes() for icmptype in config: if not icmptype 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]): 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 == "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) 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) elif item == "rules_str": for rule in config: Rich_Rule(rule_str=rule)
def _check_config(self, config, item): if item == "services" and self.fw_config: existing_services = self.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 self.fw_config: existing_icmptypes = self.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 == "target": if config not in POLICY_TARGETS: raise FirewallError(errors.INVALID_TARGET, config) elif item == "rules_str": for rule in config: rich.Rich_Rule(rule_str=rule) elif item in ["ingress-zone", "egress-zone"] and self.fw_config: existing_zones = self.fw_config.get_zones() for zone in config: if zone not in existing_zones: raise FirewallError(errors.INVALID_SERVICE, "'%s' not among existing zones" % zone)
def check_entry(entry, options, ipset_type): family = "ipv4" if "family" in options: if options["family"] == "inet6": family = "ipv6" if ipset_type == "hash:ip": if "-" in entry: splits = entry.split("-") if len(splits) != 2: raise FirewallError( errors.INVALID_ENTRY, "entry '%s' does not match ipset type '%s'" % \ (entry, ipset_type)) for split in splits: if (family == "ipv4" and not checkIP(split)) or \ (family == "ipv6" and not checkIP6(split)): raise FirewallError( errors.INVALID_ENTRY, "entry '%s' does not match ipset type '%s'" % \ (entry, ipset_type)) else: if (family == "ipv4" and not checkIPnMask(entry)) or \ (family == "ipv6" and not checkIP6nMask(entry)): raise FirewallError( errors.INVALID_ENTRY, "entry '%s' does not match ipset type '%s'" % \ (entry, ipset_type)) elif ipset_type == "hash:net": if (family == "ipv4" and not checkIPnMask(entry)) or \ (family == "ipv6" and not checkIP6nMask(entry)): raise FirewallError( errors.INVALID_ENTRY, "entry '%s' does not match ipset type '%s'" % \ (entry, ipset_type)) elif ipset_type == "hash:mac": # ipset does not allow to add 00:00:00:00:00:00 if not check_mac(entry) or entry == "00:00:00:00:00:00": raise FirewallError( errors.INVALID_ENTRY, "entry '%s' does not match ipset type '%s'" % \ (entry, ipset_type)) else: raise FirewallError(errors.INVALID_IPSET, "ipset type '%s' not usable" % ipset_type)
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 == "tcp-mss-clamp": 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 _value = "pmtu" if "value" in attrs: _value = attrs["value"] obj._rule.element = rich.Rich_Tcp_Mss_Clamp(_value) else: log.warning("Invalid rule: tcp-mss-clamp '%s' outside of rule", 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 = None if "prefix" in attrs: prefix = attrs["prefix"] if not prefix or len(prefix) > 127: log.warning('Invalid rule: Invalid log prefix') obj._rule_error = True return True obj._rule.log = rich.Rich_Log(prefix, level) obj._limit_ok = obj._rule.log elif name == "nflog": 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 group = None if "group" in attrs: group = attrs["group"] if not checkUINT16(group): log.warning('Invalid rule: Invalid nflog group value') obj._rule_error = True return True prefix = None if "prefix" in attrs: prefix = attrs["prefix"] if not prefix or len(prefix) > 127: log.warning('Invalid rule: Invalid nflog prefix') obj._rule_error = True return True threshold = None if "queue-size" in attrs: threshold = attrs["queue-size"] if not checkUINT16(threshold): log.warning('Invalid rule: Invalid nflog queue-size') obj._rule_error = True return True obj._rule.log = rich.Rich_NFLog(group, prefix, threshold) 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) else: return False return True
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 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 == "short": pass elif name == "description": pass elif name == "service": if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_Service(attrs["name"]) return if attrs["name"] not in self.item.services: self.item.services.append(attrs["name"]) else: log.warning("Service '%s' already set, ignoring.", attrs["name"]) elif name == "port": if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_Port(attrs["port"], attrs["protocol"]) return check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) entry = (portStr(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"]) elif name == "protocol": if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_Protocol(attrs["value"]) else: 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 == "icmp-block": if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_IcmpBlock(attrs["name"]) return if attrs["name"] not in self.item.icmp_blocks: self.item.icmp_blocks.append(attrs["name"]) else: log.warning("icmp-block '%s' already set, ignoring.", attrs["name"]) elif name == "icmp-type": if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_IcmpType(attrs["name"]) return else: log.warning("Invalid rule: icmp-block '%s' outside of rule", attrs["name"]) elif name == "masquerade": if "enabled" in attrs and \ attrs["enabled"].lower() in [ "no", "false" ] : log.warning("Ignoring deprecated attribute enabled='%s'", attrs["enabled"]) return if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_Masquerade() else: if self.item.masquerade: log.warning("Masquerade already set, ignoring.") else: self.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 self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_ForwardPort( attrs["port"], attrs["protocol"], to_port, to_addr) return 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 self.item.forward_ports: self.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 self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_SourcePort( attrs["port"], attrs["protocol"]) return check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) entry = (portStr(attrs["port"], "-"), attrs["protocol"]) if entry not in self.item.source_ports: self.item.source_ports.append(entry) else: log.warning("Source port '%s/%s' already set, ignoring.", attrs["port"], attrs["protocol"]) 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 == "destination": if not self._rule: log.warning('Invalid rule: Destination outside of rule') self._rule_error = True return if self._rule.destination: log.warning( "Invalid rule: More than one destination in rule '%s', ignoring.", str(self._rule)) return invert = False if "invert" in attrs and \ attrs["invert"].lower() in [ "yes", "true" ]: invert = True self._rule.destination = rich.Rich_Destination( attrs["address"], invert) elif name in ["accept", "reject", "drop", "mark"]: if not self._rule: log.warning('Invalid rule: Action outside of rule') self._rule_error = True return if self._rule.action: log.warning('Invalid rule: More than one action') self._rule_error = True return if name == "accept": self._rule.action = rich.Rich_Accept() elif name == "reject": _type = None if "type" in attrs: _type = attrs["type"] self._rule.action = rich.Rich_Reject(_type) elif name == "drop": self._rule.action = rich.Rich_Drop() elif name == "mark": _set = attrs["set"] self._rule.action = rich.Rich_Mark(_set) self._limit_ok = self._rule.action elif name == "log": if not self._rule: log.warning('Invalid rule: Log outside of rule') return if self._rule.log: log.warning('Invalid rule: More than one log') return 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') self._rule_error = True return prefix = attrs["prefix"] if "prefix" in attrs else None self._rule.log = rich.Rich_Log(prefix, level) self._limit_ok = self._rule.log elif name == "audit": if not self._rule: log.warning('Invalid rule: Audit outside of rule') return if self._rule.audit: log.warning( "Invalid rule: More than one audit in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.audit = rich.Rich_Audit() self._limit_ok = self._rule.audit elif name == "rule": family = None if "family" in attrs: family = attrs["family"] if family not in ["ipv4", "ipv6"]: log.warning('Invalid rule: Rule family "%s" invalid', attrs["family"]) self._rule_error = True return self._rule = rich.Rich_Rule(family) elif name == "limit": if not self._limit_ok: log.warning( 'Invalid rule: Limit outside of action, log and audit') self._rule_error = True return if self._limit_ok.limit: log.warning( "Invalid rule: More than one limit in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return value = attrs["value"] self._limit_ok.limit = rich.Rich_Limit(value) 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 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 startElement(self, name, attrs): IO_Object_ContentHandler.startElement(self, name) if self._rule_error: return self.item.parser_check_element_attrs(name, attrs) if 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(INVALID_TARGET, target) if target != "" and target != DEFAULT_ZONE_TARGET: self.item.target = target elif name == "short": pass elif name == "description": pass elif name == "service": if self._rule: if self._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = Rich_Service(attrs["name"]) return if attrs["name"] not in self.item.services: self.item.services.append(attrs["name"]) else: log.warning("Service '%s' already set, ignoring.", attrs["name"]) elif name == "port": if self._rule: if self._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = Rich_Port(attrs["port"], attrs["protocol"]) return check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) entry = (portStr(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"]) elif name == "protocol": if self._rule: if self._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = Rich_Protocol(attrs["value"]) else: 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 == "icmp-block": if self._rule: if self._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = Rich_IcmpBlock(attrs["name"]) return if attrs["name"] not in self.item.icmp_blocks: self.item.icmp_blocks.append(attrs["name"]) else: log.warning("icmp-block '%s' already set, ignoring.", attrs["name"]) elif name == "masquerade": if "enabled" in attrs: log.warning("Ignoring deprecated attribute enabled='%s'", attrs["enabled"]) if self._rule: if self._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = Rich_Masquerade() else: if self.item.masquerade: log.warning("Masquerade already set, ignoring.") else: self.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 self._rule: if self._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = Rich_ForwardPort(attrs["port"], attrs["protocol"], to_port, to_addr) return check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) if to_port: check_port(to_port) if to_addr: if not checkIP(to_addr): raise FirewallError(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 self.item.forward_ports: self.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 == "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 attrs["name"] 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_Source(addr, mac, ipset, invert=invert) return # zone bound to source if "address" not in attrs and not "ipset" 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(INVALID_ADDR, source) 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 == "destination": if not self._rule: log.warning('Invalid rule: Destination outside of rule') self._rule_error = True return if self._rule.destination: log.warning("Invalid rule: More than one destination in rule '%s', ignoring.", str(self._rule)) return invert = False if "invert" in attrs and \ attrs["invert"].lower() in [ "yes", "true" ]: invert = True self._rule.destination = Rich_Destination(attrs["address"], invert) elif name in [ "accept", "reject", "drop", "mark" ]: if not self._rule: log.warning('Invalid rule: Action outside of rule') self._rule_error = True return if self._rule.action: log.warning('Invalid rule: More than one action') self._rule_error = True return if name == "accept": self._rule.action = Rich_Accept() elif name == "reject": _type = None if "type" in attrs: _type = attrs["type"] self._rule.action = Rich_Reject(_type) elif name == "drop": self._rule.action = Rich_Drop() elif name == "mark": _set = attrs["set"] self._rule.action = Rich_Mark(_set) self._limit_ok = self._rule.action elif name == "log": if not self._rule: log.warning('Invalid rule: Log outside of rule') return if self._rule.log: log.warning('Invalid rule: More than one log') return 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') self._rule_error = True return prefix = attrs["prefix"] if "prefix" in attrs else None self._rule.log = Rich_Log(prefix, level) self._limit_ok = self._rule.log elif name == "audit": if not self._rule: log.warning('Invalid rule: Audit outside of rule') return if self._rule.audit: log.warning("Invalid rule: More than one audit in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.audit = Rich_Audit() self._limit_ok = self._rule.audit elif name == "rule": family = None if "family" in attrs: family = attrs["family"] if family not in [ "ipv4", "ipv6" ]: log.warning('Invalid rule: Rule family "%s" invalid', attrs["family"]) self._rule_error = True return self._rule = Rich_Rule(family) elif name == "limit": if not self._limit_ok: log.warning('Invalid rule: Limit outside of action, log and audit') self._rule_error = True return if self._limit_ok.limit: log.warning("Invalid rule: More than one limit in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return value = attrs["value"] self._limit_ok.limit = Rich_Limit(value) else: log.warning("Unknown XML element '%s'", name) return
def common_check_config(obj, config, item, all_config, all_io_objects): obj_type = "Policy" if isinstance(obj, Policy) else "Zone" if item == "services" and "services" in all_io_objects: existing_services = all_io_objects["services"] for service in config: if service not in existing_services: raise FirewallError(errors.INVALID_SERVICE, "{} '{}': '{}' not among existing services".format( obj_type, obj.name, 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 "icmptypes" in all_io_objects: existing_icmptypes = all_io_objects["icmptypes"] for icmptype in config: if icmptype not in existing_icmptypes: ex = FirewallError(errors.INVALID_ICMPTYPE, "{} '{}': '{}' not among existing ICMP types".format( obj_type, obj.name, icmptype)) if icmptype in all_io_objects.get("icmptypes_unsupported", {}): log.debug1("{} (unsupported)".format(ex)) else: raise ex 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, "{} '{}': '{}' is missing to-port AND to-addr ".format( obj_type, obj.name, 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 '{}' is not a valid address".format( obj_type, obj.name, 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_rich.element and "icmptypes" in all_io_objects and \ (isinstance(obj_rich.element, rich.Rich_IcmpBlock) or isinstance(obj_rich.element, rich.Rich_IcmpType)): existing_icmptypes = all_io_objects["icmptypes"] if obj_rich.element.name not in existing_icmptypes: ex = FirewallError(errors.INVALID_ICMPTYPE, "{} '{}': '{}' not among existing ICMP types".format( obj_type, obj.name, obj_rich.element.name)) if obj_rich.element.name in all_io_objects.get("icmptypes_unsupported", {}): log.debug1("{} (unsupported)".format(ex)) else: raise ex elif obj_rich.family: ict = all_io_objects["icmptypes"][obj_rich.element.name] if ict.destination and obj_rich.family not in ict.destination: ex = FirewallError(errors.INVALID_ICMPTYPE, "{} '{}': rich rule family '{}' conflicts with icmp type '{}'".format( obj_type, obj.name, obj_rich.family, obj_rich.element.name)) ict_unsupported = all_io_objects.get("icmptypes_unsupported", {}).get(obj_rich.element.name) if ict_unsupported and ict_unsupported.destination and \ obj_rich.family in ict_unsupported.destination: log.debug1("{} (unsupported)".format(ex)) else: raise ex
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 name == "policy": if "version" in attrs: self.item.version = attrs["version"] if "priority" in attrs: self.item.priority = int(attrs["priority"]) target = attrs["target"] if target not in POLICY_TARGETS: raise FirewallError(errors.INVALID_TARGET, target) elif name == "short": pass elif name == "description": pass elif name == "service": if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_Service(attrs["name"]) return if attrs["name"] not in self.item.services: self.item.services.append(attrs["name"]) else: log.warning("Service '%s' already set, ignoring.", attrs["name"]) 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 == "port": if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_Port(attrs["port"], attrs["protocol"]) return check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) entry = (portStr(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"]) elif name == "protocol": if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_Protocol(attrs["value"]) else: 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 == "icmp-block": if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_IcmpBlock(attrs["name"]) return if attrs["name"] not in self.item.icmp_blocks: self.item.icmp_blocks.append(attrs["name"]) else: log.warning("icmp-block '%s' already set, ignoring.", attrs["name"]) elif name == "icmp-type": if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_IcmpType(attrs["name"]) return else: log.warning("Invalid rule: icmp-block '%s' outside of rule", attrs["name"]) elif name == "masquerade": if self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_Masquerade() else: if self.item.masquerade: log.warning("Masquerade already set, ignoring.") else: self.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 self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_ForwardPort( attrs["port"], attrs["protocol"], to_port, to_addr) return 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 self.item.forward_ports: self.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 self._rule: if self._rule.element: log.warning( "Invalid rule: More than one element in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.element = rich.Rich_SourcePort( attrs["port"], attrs["protocol"]) return check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) entry = (portStr(attrs["port"], "-"), attrs["protocol"]) if entry not in self.item.source_ports: self.item.source_ports.append(entry) else: log.warning("Source port '%s/%s' already set, ignoring.", attrs["port"], attrs["protocol"]) elif name == "destination": if not self._rule: log.warning('Invalid rule: Destination outside of rule') self._rule_error = True return if self._rule.destination: log.warning( "Invalid rule: More than one destination in rule '%s', ignoring.", str(self._rule)) return invert = False if "invert" in attrs and \ attrs["invert"].lower() in [ "yes", "true" ]: invert = True self._rule.destination = rich.Rich_Destination( attrs["address"], invert) elif name in ["accept", "reject", "drop", "mark"]: if not self._rule: log.warning('Invalid rule: Action outside of rule') self._rule_error = True return if self._rule.action: log.warning('Invalid rule: More than one action') self._rule_error = True return if name == "accept": self._rule.action = rich.Rich_Accept() elif name == "reject": _type = None if "type" in attrs: _type = attrs["type"] self._rule.action = rich.Rich_Reject(_type) elif name == "drop": self._rule.action = rich.Rich_Drop() elif name == "mark": _set = attrs["set"] self._rule.action = rich.Rich_Mark(_set) self._limit_ok = self._rule.action elif name == "log": if not self._rule: log.warning('Invalid rule: Log outside of rule') return if self._rule.log: log.warning('Invalid rule: More than one log') return 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') self._rule_error = True return prefix = attrs["prefix"] if "prefix" in attrs else None self._rule.log = rich.Rich_Log(prefix, level) self._limit_ok = self._rule.log elif name == "audit": if not self._rule: log.warning('Invalid rule: Audit outside of rule') return if self._rule.audit: log.warning( "Invalid rule: More than one audit in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return self._rule.audit = rich.Rich_Audit() self._limit_ok = self._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"]) self._rule_error = True return if "priority" in attrs: priority = int(attrs["priority"]) self._rule = rich.Rich_Rule(family=family, priority=priority) elif name == "limit": if not self._limit_ok: log.warning( 'Invalid rule: Limit outside of action, log and audit') self._rule_error = True return if self._limit_ok.limit: log.warning( "Invalid rule: More than one limit in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return value = attrs["value"] self._limit_ok.limit = rich.Rich_Limit(value) else: log.warning("Unknown XML element '%s'", name) return
def check_ip(self, ip): if not functions.checkIP(ip): raise FirewallError(INVALID_ADDR, ip)
def check_ip(self, ip): if not functions.checkIP(ip): raise FirewallError(errors.INVALID_ADDR, ip)