????
Your IP : 3.144.33.74
import ipaddress
import logging
from pathlib import Path
from typing import List, Literal, Union
logger = logging.getLogger(__name__)
PROTOS = (TCP, UDP, ALL) = ("tcp", "udp", "all")
class IpPortDenyModeError(Exception):
pass
Proto = Literal["tcp", "udp", "all"]
PortNetworkMap = dict[Proto, dict[int, List[str]]]
class WhitelistPortIPsDenyMode:
_LIST_PATH = "/etc/imunify360/whitelist/ports"
@classmethod
def load(cls) -> PortNetworkMap:
"""Read port:networks from the file"""
port_to_networks = {TCP: {}, UDP: {}}
for path in Path(cls._LIST_PATH).glob("*.txt"):
port_to_networks = cls._load_file(
path.absolute(), port_to_networks
)
return port_to_networks
@classmethod
def _load_file(
cls, path: Path, port_to_networks: PortNetworkMap
) -> PortNetworkMap:
for line_num, line in enumerate(path.open().readlines()):
item = line.partition("#")[0].strip()
if not item:
continue
network_list = []
valid = True
port, semicolon, tail = item.partition(":")
protos: List[Proto] = [TCP, UDP]
proto, _, networks = tail.partition(":")
proto: Proto = proto.strip().lower()
if proto in PROTOS:
if proto != ALL:
protos = [proto]
else:
networks = tail
if not semicolon:
valid = False
try:
port = int(port)
except ValueError:
valid = False
else:
for network in networks.split(","):
network = network.strip()
if network:
try:
ipaddress.ip_network(network)
network_list.append(network)
except ValueError:
valid = False
for proto in protos:
if network_list:
existing_ports = port_to_networks[proto].setdefault(
port, []
)
existing_ports.extend(network_list)
port_to_networks[proto][port] = sorted(
list(set(existing_ports))
)
if not valid:
logger.error(
"Wrong IP/Subnet format in %s:%s. Use CIDR format.",
path,
line_num,
)
return port_to_networks
@classmethod
def count(
cls,
proto: Union[
Literal["tcp", "udp", "all"], List[Literal["tcp", "udp"]]
],
) -> int:
match proto:
case _ if isinstance(proto, list) and all(
p in ["tcp", "udp"] for p in proto
):
protos = proto
case "tcp" | "udp":
protos = [proto]
case "all":
protos = ["tcp", "udp"]
case _:
raise ValueError("Invalid input")
proto_to_ports = cls.load()
return sum(
sum(len(networks) for networks in proto_to_ports[p].values())
for p in protos
)