""" This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program.  If not, see . Copyright © 2019 Cloud Linux Software Inc. This software is also available under ImunifyAV commercial license, see """ from enum import Enum class MalwareScanType: """The type of a scan represents how and why it is executed""" #: .. deprecated:: no longer used MALWARE_RESPONSE = "malware-response" #: A scan of arbitrary path or path pattern started by admin or user. ON_DEMAND = "on-demand" #: A batch of files scanned by resident mode AI-BOLIT. #: #: FIXME this scan type is also used as a default in #: :meth:`.Scanner._process_scan_task` #: Afaik, because of this, rescans triggered by ignore list removal, #: have this `type`. I'm not sure if there are more. REALTIME = "realtime" #: Used in :class:`.MalwareHistory` to indicate a manual action on a file, #: not directly caused by any scan. #: #: .. deprecated:: - FIXME this is not really a scan type... MANUAL = "manual" #: Similar to :attr:`MalwareScanType.USER`, but started from our cron job. #: #: See the `MALWARE_SCAN_SCHEDULE` config option for more info. #: Background scans are reported to ClickHouse even if there was #: no malware found. BACKGROUND = "background" #: Correlation server asked to rescan some files. RESCAN = "rescan" #: Rescan triggered by the agent when file is modified after scanning RESCAN_OUTDATED = "rescan-outdated" #: ModSec rule triggered a scan on file upload. #: #: .. deprecated:: 4.4.0 #: was used for ModSec upload scans before resident mode AI-BOLIT #: (DEF-9201) MODSEC = "modsec" #: A scan of one user home directory. USER = "user" #: An attempt to find a clean version of a file in backups. RESTORE_FROM_BACKUP = "restore_from_backup" AIBOLIT_SCAN_INTENSITY_KEY = { MalwareScanType.ON_DEMAND: "aibolit-on_demand", MalwareScanType.BACKGROUND: "aibolit-background", MalwareScanType.USER: "aibolit-user", MalwareScanType.RESCAN: "aibolit-rescan", MalwareScanType.RESCAN_OUTDATED: "aibolit-rescan", MalwareScanType.REALTIME: "aibolit-realtime", MalwareScanType.RESTORE_FROM_BACKUP: "aibolit-restore_from_backup", } APP_VERSION_DETECTOR_INTENSITY_KEY = "app_version_detector" HSDB_MAKER_INTENSITY_KEY = "aibolit-hsdb_maker" RESTORE_ORIGINAL_INTENSITY_KEY = "aibolit-restore_original" PHP_PATH = "/opt/alt/php-internal/usr/bin/php" SUCCESSFUL_EVENTS = ( DELETED, FOUND, ADDED_TO_IGNORE, DELETED_FROM_IGNORE, SUBMITTED_FOR_ANALYSIS, CLEANUP_DONE, CLEANUP_REMOVED, RESTORED_ORIGINAL, # FIXME: not used. Should we save this event in history? RESTORE_FROM_BACKUP_STARTED, RESTORED_FROM_BACKUP, ) = ( "deleted", "found", "added_to_ignore", "deleted_from_ignore", "submitted_for_analysis", "cleanup_done", "cleanup_removed", "restored_original", "restore_from_backup_started", "restored_from_backup", ) FAILED_EVENTS = ( # FIXME: not used FAILED_TO_DELETE, # FIXME: not used FAILED_TO_RESTORE_FROM_BACKUP, FAILED_TO_IGNORE, FAILED_TO_DELETE_FROM_IGNORE, FAILED_TO_CLEANUP, FAILED_TO_RESTORE_ORIGINAL, UNABLE_TO_CLEANUP, FAILED_TO_STORE_ORIGINAL, REQUIRES_MYIMUNIFY_PROTECTION, ) = ( "failed_to_delete", "failed_to_restore_from_backup", "failed_to_ignore", "failed_to_delete_from_ignore", "failed_to_cleanup", "failed_to_restore_original", "unable_to_cleanup", "failed_to_store_original", "requires_myimunify_protection", ) class MalwareEvent: def __init__(self, title): self.title = title @property def successful(self) -> bool: return self.title in SUCCESSFUL_EVENTS @property def malware_eliminated(self) -> bool: """Malware file was deleted or clean copy was restored""" return self.title in (DELETED, RESTORED_FROM_BACKUP) class MalwareEventPostponed: def __init__(self, message, cause, initiator, post_action, action): self.message = message self.cause = cause self.initiator = initiator self.post_action = post_action self.action = action class Hash: TYPES = WHITE, BLACK = "white", "black" IS_IGNORED = {BLACK: False, WHITE: True} class MalwareHitStatus: """ The current state of a resource (a file or a db), defined by the latest scans and actions. """ #: The resource is currently malicious or suspicious. FOUND = "found" #: *Db only*. #: The resource is added to the cleanup queue. CLEANUP_PENDING = "cleanup_pending" #: *Files*. #: Attempting to backup the file. #: #: *DBs*. #: MDS cleanup process was started. CLEANUP_STARTED = "cleanup_started" #: The resource is successfuly cleaned from malware. CLEANUP_DONE = "cleanup_done" #: *File only*. #: The file content (or the whole file, based on #: settings) is removed. CLEANUP_REMOVED = "cleanup_removed" #: *File only*. #: The resource requires MyImunify protection for the cleanup CLEANUP_REQUIRES_MYIMUNIFY_PROTECTION = ( "cleanup_requires_myimunify_protection" ) #: *Db only*. #: The resource is added to the restore queue. CLEANUP_RESTORE_PENDING = "cleanup_restore_pending" #: *Db only*. #: MDS restore process has started. CLEANUP_RESTORE_STARTED = "cleanup_restore_started" #: *File only*. #: Similar to :attr:`CLEANUP_STARTED`, the async restoration process has #: started, but the file is not yet :attr:`RESTORED_FROM_BACKUP`. RESTORE_FROM_BACKUP_STARTED = "restore_from_backup_started" #: *File only*. #: A clean version of the file was found in backups and successfully #: restored. RESTORED_FROM_BACKUP = "restored_from_backup" # TODO: should we add # CLEANUP_RESTORE_PENDING, CLEANUP_RESTORE_STARTED here? CLEANUP = (CLEANUP_PENDING, CLEANUP_STARTED, CLEANUP_DONE, CLEANUP_REMOVED) RESTORABLE = (CLEANUP_DONE, CLEANUP_REMOVED) class QueuedScanState(Enum): stopped = "stopped" running = "running" queued = "queued" class MalwareScanResourceType(Enum): FILE = "file" DB = "db" class ExitDetachedScanType: """How/why detached scan ended.""" #: It was stopped by a user. STOPPED = "stopped" #: It was aborted for other reasons. ABORTED = "aborted" NOTIFY, CLEANUP, CLEANUP_ON_SCHEDULE = ( "notify", "cleanup", "cleanup_on_schedule", )