Mini Shell
import json
import logging
import subprocess
from ipaddress import summarize_address_range, IPv4Address
from defence360agent.subsys.panels.cpanel import cPanel
from defence360agent.utils import run
WHMAPI = "/usr/sbin/whmapi1"
logger = logging.getLogger(__name__)
async def is_running():
try:
rc, *_ = await run(
["/usr/local/cpanel/scripts/restartsrv_cphulkd", "--status"]
)
return rc == 0
except FileNotFoundError:
return False
def cphulk_parse_ip(range_str, comment):
parsed_ips = []
ips = range_str.split("-")
if len(ips) == 1:
return [(ips[0], comment)]
try:
parsed_ips = [
(str(cidr), comment)
for cidr in summarize_address_range(
IPv4Address(ips[0]), IPv4Address(ips[1])
)
]
except ValueError as e:
logger.warning("Got invalid IP error: %s", str(e))
finally:
return parsed_ips
def ips_from_list(list_name):
"""
Obtain white/black lists from cphulk using cpanel api
# whmapi1 read_cphulk_records list_name=black --output=json
:param list_name: name of the list to obtain from
:return: list of ips and networks
"""
list_name = list_name.lower()
ips = []
if not cPanel.is_installed():
return ips
logger.info("Loading from chpulk %s list", list_name)
try:
try:
cp = subprocess.run(
[
WHMAPI,
"read_cphulk_records",
"--output=json",
"list_name=" + list_name,
],
stdout=subprocess.PIPE,
check=True,
timeout=20,
)
except OSError:
logger.info("whmapi not found, skipping import from cphulk")
return []
try:
output = json.loads(cp.stdout.decode())
if not output["metadata"]["result"]:
logger.warning(
"Got error from whmapi1: %s", output["metadata"]["reason"]
)
else:
for rng, comment in output["data"]["ips_in_list"].items():
ips.extend(cphulk_parse_ip(rng, comment))
except (json.JSONDecodeError, KeyError):
logger.error("Broken output from whmapi1: %s", cp.stdout)
except Exception:
logger.exception("Failed to obtain ip list from cphulk")
return ips