def querySourcePort(self, port, protocol, sender=None): # pylint: disable=W0613 port = dbus_to_python(port, str) protocol = dbus_to_python(protocol, str) log.debug1("%s.querySourcePort('%s', '%s')", self._log_prefix, port, protocol) for (_port, _protocol) in self.getSettings()[14]: if portInPortRange(port, _port) and protocol == _protocol: return True return False
def queryPort(self, port, protocol, sender=None): # pylint: disable=W0613 port = dbus_to_python(port, str) protocol = dbus_to_python(protocol, str) log.debug1("%s.queryPort('%s', '%s')", self._log_prefix, port, protocol) if (port, protocol) in self.getSettings()[6]: return True else: # It might be a single port query that is inside a range for (_port, _protocol) in self.getSettings()[6]: if portInPortRange(port, _port) and protocol == _protocol: return True return False
def addPort(self, port, protocol, sender=None): port = dbus_to_python(port, str) protocol = dbus_to_python(protocol, str) log.debug1("%s.addPort('%s', '%s')", self._log_prefix, port, protocol) self.parent.accessCheck(sender) settings = list(self.getSettings()) existing_port_ids = list( filter(lambda x: x[1] == protocol, settings[6])) for port_id in existing_port_ids: if portInPortRange(port, port_id[0]): raise FirewallError(errors.ALREADY_ENABLED, "%s:%s" % (port, protocol)) added_ranges, removed_ranges = coalescePortRange( port, [_port for (_port, _protocol) in existing_port_ids]) for range in removed_ranges: settings[6].remove((portStr(range, "-"), protocol)) for range in added_ranges: settings[6].append((portStr(range, "-"), protocol)) self.update(settings)
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"]) # coalesce and warn about overlapping ranges new_port_id = (portStr(attrs["port"], "-"), attrs["protocol"]) existing_port_ids = list(filter(lambda x: x[1] == attrs["protocol"], obj.item.ports)) for port_id in existing_port_ids: if portInPortRange(new_port_id[0], port_id[0]): # the range is wholly contained already, so just warn _name = obj.item.derived_from_zone if isinstance(obj.item, Policy) else obj.item.name log.warning(FirewallError(errors.ALREADY_ENABLED, "'%s:%s' already in '%s'" % (new_port_id[0], attrs["protocol"], _name))) break # for else: # the range can be coalesced into the existing set added_ranges, removed_ranges = coalescePortRange(new_port_id[0], [_port for (_port, _protocol) in existing_port_ids]) for _range in removed_ranges: entry = (portStr(_range, "-"), attrs["protocol"]) obj.item.ports.remove(entry) for _range in added_ranges: entry = (portStr(_range, "-"), attrs["protocol"]) obj.item.ports.append(entry) 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"]) # coalesce and warn about overlapping ranges new_port_id = (portStr(attrs["port"], "-"), attrs["protocol"]) existing_port_ids = list(filter(lambda x: x[1] == attrs["protocol"], obj.item.source_ports)) for port_id in existing_port_ids: if portInPortRange(new_port_id[0], port_id[0]): # the range is wholly contained already, so just warn _name = obj.item.derived_from_zone if isinstance(obj.item, Policy) else obj.item.name log.warning(FirewallError(errors.ALREADY_ENABLED, "'%s:%s' already in '%s'" % (new_port_id[0], attrs["protocol"], _name))) break # for else: # the range can be coalesced into the existing set added_ranges, removed_ranges = coalescePortRange(new_port_id[0], [_port for (_port, _protocol) in existing_port_ids]) for _range in removed_ranges: entry = (portStr(_range, "-"), attrs["protocol"]) obj.item.source_ports.remove(entry) for _range in added_ranges: entry = (portStr(_range, "-"), attrs["protocol"]) obj.item.source_ports.append(entry) 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