ok

Mini Shell

Direktori : /opt/imunify360/venv/lib/python3.11/site-packages/im360/subsys/panels/
Upload File :
Current File : //opt/imunify360/venv/lib/python3.11/site-packages/im360/subsys/panels/update_hooks.py

import logging
import shutil
from pathlib import Path

from defence360agent.subsys import web_server
from defence360agent.subsys.panels.base import (
    ModsecVendorsError,
    PanelException,
)
from defence360agent.utils import (
    atomic_rewrite,
    file_hash,
    log_error_and_ignore,
)
from im360 import files
from im360.contracts.config import Modsec
from im360.subsys import modsec_app_version_detector, waf_rules_configurator
from im360.subsys.panels.base import use_modsec_lock
from imav.malwarelib.subsys.malware import HackerTrapHitsSaver

from .hosting_panel import HostingPanel

logger = logging.getLogger(__name__)

WP_REDIRECT_CONF_PATTERN = "*_Disable_WP_Redirect.conf"
DISABLED_REDIRECT_CONF_CONTENT = "SecRuleRemoveById 33355 33357"


@use_modsec_lock
async def update_vendors(_, is_updated):
    if is_updated:
        hp = HostingPanel()
        if hp.is_installed():
            await hp.apply_modsec_files_update()
            # rules contains empty ip-record.db, so after
            # updating rules, we should also update ip-record.db
            await _update_iprecord(_, is_updated)
            await HackerTrapHitsSaver.init()
            await _update_account_compromise_prevention_rule_state()
            await _update_app_based_rules()


@use_modsec_lock
async def update_iprecord(_, is_updated):
    return await _update_iprecord(_, is_updated)


async def _update_iprecord(_, is_updated):
    if not is_updated:
        return

    def _warn(e):
        logger.warning("Can't update ip-record.db, reason: %s" % str(e))

    hp = HostingPanel()
    try:
        vendor = await hp.get_i360_vendor_name()
        ip_record = await hp.build_vendor_file_path(vendor, "ip-record.db")
    except (ModsecVendorsError, PanelException, ValueError) as e:
        _warn(e)
        return
    src = (
        Path(files.Index.files_path(files.IP_RECORD))
        / "ip-record"
        / "ip-record.db"
    )
    if src.exists():
        try:
            if file_hash(src) != file_hash(ip_record):
                shutil.copy(src, ip_record)
                await web_server.graceful_restart()
        except Exception as e:
            _warn(e)
            return
    else:
        _warn("source file is missing")
        return


def _get_account_prevention_state(path: Path):
    content = path.read_text().strip()
    if not content:
        return True
    elif content == DISABLED_REDIRECT_CONF_CONTENT:
        return False
    else:
        logger.warning("Invalid content in %s: %s", path, content)
        return None


@use_modsec_lock
async def update_account_compromise_prevention_rule_state():
    return await _update_account_compromise_prevention_rule_state()


@log_error_and_ignore()
async def _update_account_compromise_prevention_rule_state():
    is_prevention_enabled = Modsec.CMS_ACCOUNT_COMPROMISE_PREVENTION
    hp = HostingPanel()
    try:
        vendor = await hp.get_i360_vendor_name()
    except (ModsecVendorsError, PanelException) as e:
        logger.warning(str(e))
        return
    try:
        vendor_path = await hp.build_vendor_file_path(vendor, "")
        wp_redirect_conf_path = next(
            vendor_path.glob(WP_REDIRECT_CONF_PATTERN)
        )
    except (ModsecVendorsError, StopIteration):
        logger.exception("Can't get %s file", WP_REDIRECT_CONF_PATTERN)
        return
    current_state = _get_account_prevention_state(wp_redirect_conf_path)
    if current_state != is_prevention_enabled:
        content = (
            "" if is_prevention_enabled else DISABLED_REDIRECT_CONF_CONTENT
        )
        atomic_rewrite(str(wp_redirect_conf_path), content, backup=False)
        # to apply changes
        await web_server.graceful_restart()


async def _update_app_based_rules():
    if Modsec.APP_SPECIFIC_RULESET:
        try:
            await waf_rules_configurator.update_waf_rules_config()
        except (
            waf_rules_configurator.NotSupportedWebserverError,
            modsec_app_version_detector.DatabaseNotFoundError,
        ) as e:
            logger.warning("App based rules not updated: %s", e)

Zerion Mini Shell 1.0