ACIL FM
Dark
Refresh
Current DIR:
/opt/imunify360/venv/lib/python3.11/site-packages/defence360agent/contracts
/
opt
imunify360
venv
lib
python3.11
site-packages
defence360agent
contracts
Upload
Zip Selected
Delete Selected
Pilih semua
Nama
Ukuran
Permission
Aksi
__pycache__
-
chmod
Open
Rename
Delete
config.py
42.01 MB
chmod
View
DL
Edit
Rename
Delete
config_provider.py
9.36 MB
chmod
View
DL
Edit
Rename
Delete
eula.py
1.47 MB
chmod
View
DL
Edit
Rename
Delete
hooks.py
6.13 MB
chmod
View
DL
Edit
Rename
Delete
hook_events.py
1.51 MB
chmod
View
DL
Edit
Rename
Delete
license.py
21.27 MB
chmod
View
DL
Edit
Rename
Delete
messages.py
12 MB
chmod
View
DL
Edit
Rename
Delete
myimunify_id.py
4.4 MB
chmod
View
DL
Edit
Rename
Delete
permissions.py
6.01 MB
chmod
View
DL
Edit
Rename
Delete
plugins.py
8.1 MB
chmod
View
DL
Edit
Rename
Delete
sentry.py
2.97 MB
chmod
View
DL
Edit
Rename
Delete
__init__.py
0 B
chmod
View
DL
Edit
Rename
Delete
Edit file: /opt/imunify360/venv/lib/python3.11/site-packages/defence360agent/contracts/plugins.py
import asyncio import inspect import logging import subprocess from abc import ABC, ABCMeta, abstractmethod from contextlib import suppress from functools import lru_cache, wraps from defence360agent.contracts.messages import Message, MessageType from defence360agent.utils import Scope logger = logging.getLogger(__name__) class BasePlugin(object): SCOPE = Scope.AV_IM360 SHUTDOWN_PRIORITY = 100 # lower means shuts down first AVAILABLE_ON_FREEMIUM = True _subclasses = [] def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) cls._subclasses.append(cls) @classmethod def get_active_plugins(cls): # consider all non-abstract subclasses are active return [ plugin for plugin in cls._subclasses if not inspect.isabstract(plugin) ] async def shutdown(self): """Shutdown plugin's subsystems, cancel running tasks, clean iptables (if plugin is protector). It should be safe to assume that it is called after corresponding create_source if applicable. It is called only from the shutdown task that runs at most once, meaning shutdown() is never called twice. """ pass def __repr__(self): return "%s.%s" % (self.__class__.__module__, self.__class__.__name__) class MessageSource(BasePlugin, ABC): @abstractmethod def create_source(self, loop, sink): """This method is a coroutine.""" class Sensor(MessageSource, ABC): """ Sensor is alias to MessageSource. """ def create_source(self, loop, sink): """This method is a coroutine.""" return self.create_sensor(loop, sink) @abstractmethod def create_sensor(self, loop, sink): """This method is a coroutine.""" class LogStreamReader(Sensor, metaclass=ABCMeta): source_file = None # Limit of bytes consumed from stream # while trying to read one line (128 kB) _LIMIT = 2**17 _cmd = None async def create_sensor(self, loop, sink): self._loop = loop self._sink = sink self._cmd = None if not self.source_file: return self._cmd = ( "/usr/bin/tail", # follow beyond the end of the file "--follow=name", "-n0", # keep trying to open a file if it is inaccessible "--retry", self.source_file, ) self._child_process = await asyncio.create_subprocess_exec( *self._cmd, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, bufsize=0, limit=self._LIMIT ) loop.create_task( self._infinite_read_and_proceed(self._child_process.stdout) ) async def shutdown(self): if self._cmd is not None: cmd, self._cmd = self._cmd, None logger.debug("Terminating child process [%s]", cmd) # child process dies from the same signal when agent # is run from console (not as --daemon) with suppress(ProcessLookupError): self._child_process.kill() rc = await self._child_process.wait() logger.debug( "Terminated child process [%s] with code [%d]", cmd, rc ) @abstractmethod async def _infinite_read_and_proceed(self, stream_reader): raise NotImplementedError class BaseMessageProcessor: @lru_cache(maxsize=1) def _message_processors(self): rv = [] for attr_str in dir(self): if attr_str.startswith("_"): continue # skip non-public attributes func = getattr(self, attr_str) if callable(func) and hasattr( func, "_decorated_for_process_message" ): rv.append(func) return rv async def process_message(self, message): logger.debug("Dispatching %r through %r...", message, self) for coro in self._message_processors(): result = await coro(message) if isinstance(result, Message): return result class MessageSink(BasePlugin, BaseMessageProcessor, ABC): class ProcessingOrder: # e.g. check is valid ipv4 PRE_PROCESS_MESSAGE = 10 # lfd plugin should process lfd alerts before other ignore plugins LFD = 18 # e.g. for ignore_alert_with_whitelisted_ip IGNORE_MESSAGE = 20 # Should be before check ip in graylist UNBLOCK_FROM_SUBNET = 30 # Check ip in the graylist already CHECK_IP_IN_GRAYLIST = 40 # Append ttl to alert GRAYLIST_TIMEOUT = 50 # Store graylist to db GRAYLIST_DB_FIXUP = 55 # this should run before IPSET_PROTECTOR IMPORT_EXPORT_WBLIST = 60 # make ml prediction before lazy_init ML_PREDICTION = 70 # the default DEFAULT = 80 IPSET_PROTECTOR = DEFAULT WEBSHIELD_PROTECTOR = 81 # should be run after ManageGrayList(DEFAULT) WHITELIST_UNBLOCKED = 90 # Synclist timestamp update SYNCLIST_UPDATE = 100 # post action POST_ACTION = 120 # event hook processing EVENT_HOOK = 150 # iContact ICONTACT_SENT = 200 # e.g. Accumulate POST_PROCESS_MESSAGE = 999 # alias for DEFAULT PROCESSING_ORDER = ProcessingOrder.DEFAULT @abstractmethod async def create_sink(self, loop): pass def expect(*message_type, async_lock=None, **expect_fields): """ @expect decorator for MessageSink.dosmth(message) async methods. MessageSink method will be called by MessageSink.process_message() if message_type and expect_fields match the message ones. @expect's can be stacked together and decision whether to call decorated coro is made by evaluating stacked @expect's with logical OR: @expect(MessageType.SensorAlert) # -- OR -- @expect(MessageType.SensorIncident, plugin_id='ossec') def protect(message): ... """ def decorate(coro): if getattr(coro, "__name__", "").startswith("_"): raise TypeError("{coro} is not public".format(coro=coro)) @wraps(coro) async def decorated(self, message): def match(): return isinstance(message, message_type) and all( message.get(k) == v for k, v in expect_fields.items() ) def is_stacked(coro): return hasattr(coro, "_decorated_for_process_message") def terminal(coro): if is_stacked(coro): return terminal(coro._decorated_for_process_message) return coro # process stacked decorators with logical OR if match(): if async_lock is True: await message.acquire() try: result = await terminal(coro)(self, message) except Exception as exc: if ( isinstance(message, MessageType.Lockable) and message.locked() ): message.release() raise exc else: if ( async_lock is False and isinstance(message, MessageType.Lockable) and message.locked() ): message.release() return result if is_stacked(coro): # Give next decorator a chance: logical OR return await coro(self, message) return None decorated._decorated_for_process_message = coro return decorated return decorate _plugin_registry = set() def thisguy(plugincls): """Register class as a plugin. >>> @thisguy >>> class ConcreteSink (MessageSink): >>> ... """ _plugin_registry.add(plugincls) return plugincls def theseguys(): """Enumerate classobj for registered plugins.""" return _plugin_registry
Simpan
Batal
Isi Zip:
Unzip
Create
Buat Folder
Buat File
Terminal / Execute
Run
Chmod Bulk
All File
All Folder
All File dan Folder
Apply