diff --git a/debian/control b/debian/control index 0707374..09f7a94 100644 --- a/debian/control +++ b/debian/control @@ -8,5 +8,5 @@ Homepage: http://www.liderahenk.org.tr Package: ahenk Architecture: any -Depends:python3 (>= 3), cython, libidn11, libidn11-dev, python3-dev, python3-pip, libffi-dev, libssl-dev, python3-paramiko, python3-cpuinfo, python3-psutil (>= 4), libpam-script, python3-sleekxmpp, python3-easygui +Depends:python3 (>= 3), cython, libidn11, libidn11-dev, python3-dev, python3-pip, python3-watchdog, libffi-dev, libssl-dev, python3-paramiko, python3-cpuinfo, python3-psutil (>= 4), libpam-script, python3-sleekxmpp, python3-easygui Description: Lider Ahenk is an open source project which provides solutions to manage, monitor and audit unlimited number of different systems and users on a network. diff --git a/opt/ahenk/ahenkd.py b/opt/ahenk/ahenkd.py index 44b825f..1431524 100755 --- a/opt/ahenk/ahenkd.py +++ b/opt/ahenk/ahenkd.py @@ -124,13 +124,9 @@ class AhenkDeamon(BaseDaemon): try: while registration.is_registered() is False: - # while Scope.getInstance().getRegistration().is_registered() is False: max_attemp_number -= 1 logger.debug('[AhenkDeamon] Ahenk is not registered. Attempting for registration') - # TODO 'Could not reach Registration response from Lider. Be sure Lider is running and it is connected to XMPP server!' - registration.registration_request() - # Scope.getInstance().getRegistration().registration_request() if max_attemp_number < 0: logger.warning('[AhenkDeamon] Number of Attempting for registration is over') self.registration_failed() @@ -258,16 +254,21 @@ class AhenkDeamon(BaseDaemon): def run_command_from_fifo(self, num, stack): - json_data = json.loads(Commander().get_event()) + scope = Scope().getInstance() + plugin_manager = scope.getPluginManager() + message_manager = scope.getMessageManager() + messenger = scope.getMessenger() + conf_manager = scope.getConfigurationManager() + db_service = scope.getDbService() + execute_manager = scope.getExecutionManager() + + try: + json_data = json.loads(Commander().get_event()) + except Exception as e: + self.logger.error('[AhenkDeamon] A problem occurred while loading json. Check json format! Error Message: {0}'.format(str(e))) + return if json_data is not None: - scope = Scope().getInstance() - plugin_manager = scope.getPluginManager() - message_manager = scope.getMessageManager() - messenger = scope.getMessenger() - conf_manager = scope.getConfigurationManager() - db_service = scope.getDbService() - execute_manager = scope.getExecutionManager() self.logger.debug('[AhenkDeamon] Signal handled') self.logger.debug('[AhenkDeamon] Signal is :{}'.format(str(json_data['event']))) @@ -351,8 +352,8 @@ class AhenkDeamon(BaseDaemon): plugin_manager.process_mode('safe', username) elif 'send' == str(json_data['event']): - self.logger.info('[AhenkDeamon] Sending message over ahenkd command. Response Message: {}'.format(str(json_data['message']))) - message = str(json.dumps(json_data['message'])) + self.logger.info('[AhenkDeamon] Sending message over ahenkd command. Response Message: {}'.format(json.dumps(json_data['message']))) + message = json.dumps(json_data['message']) messenger.send_direct_message(message) elif 'load' == str(json_data['event']): diff --git a/opt/ahenk/base/command/commander.py b/opt/ahenk/base/command/commander.py index ed5f438..eb45b57 100644 --- a/opt/ahenk/base/command/commander.py +++ b/opt/ahenk/base/command/commander.py @@ -4,6 +4,7 @@ import json import os import queue as Queue import threading +import ast from base.command.fifo import Fifo from base.model.enum.ContentType import ContentType @@ -71,7 +72,7 @@ class Commander(object): response['type'] = MessageType.TASK_STATUS.value response['taskId'] = params[3] if params[4] == '-m': - response['contentType'] = ContentType.TEXT_PLAIN.value + response['contentType'] = ContentType.APPLICATION_JSON.value response['responseData'] = params[5] elif params[4] == '-f': if os.path.exists(str(params[5])): @@ -101,7 +102,7 @@ class Commander(object): response['commandExecutionId'] = params[5] if params[6] == '-m': - response['contentType'] = ContentType.TEXT_PLAIN.value + response['contentType'] = ContentType.APPLICATION_JSON.value response['responseData'] = params[7] elif params[6] == '-f': if os.path.exists(str(params[7])): @@ -125,13 +126,12 @@ class Commander(object): else: print('Wrong or missing parameter. Usage: send -p -c -m|-f | -e|-s|-w') return None - print('RESPONSE=' + str(response).replace("'", '"')) - data['message'] = json.loads(str(response).replace("'", '"')) + + data['message'] = ast.literal_eval(str(response)) else: print('Wrong or missing parameter. Usage : %s start|stop|restart|status|clean|send') return None - else: if params[1] == 'clean': @@ -196,7 +196,7 @@ class Commander(object): if os.path.exists(db_path): os.remove(db_path) - #TODO remove pid file + # TODO remove pid file config.set('CONNECTION', 'uid', '') diff --git a/opt/ahenk/base/plugin/Plugin.py b/opt/ahenk/base/plugin/Plugin.py index 0787e51..987e06c 100644 --- a/opt/ahenk/base/plugin/Plugin.py +++ b/opt/ahenk/base/plugin/Plugin.py @@ -72,7 +72,7 @@ class Plugin(threading.Thread): if obj_name == "TASK": self.logger.debug('[Plugin] Executing task') command = Scope.getInstance().getPluginManager().find_command(self.getName(), item_obj.get_command_cls_id().lower()) - self.context.put('task_id', item_obj.get_command_cls_id().lower()) + self.context.put('task_id', item_obj.get_id()) task_data = item_obj.get_parameter_map() self.logger.debug('[Plugin] Handling task') diff --git a/opt/ahenk/base/plugin/plugin_install_listener.py b/opt/ahenk/base/plugin/plugin_install_listener.py index a1c1c5a..48e9212 100644 --- a/opt/ahenk/base/plugin/plugin_install_listener.py +++ b/opt/ahenk/base/plugin/plugin_install_listener.py @@ -2,44 +2,39 @@ import os import signal import time -# from watchdog.events import FileSystemEventHandler -# from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +from watchdog.observers import Observer from base.command.commander import Commander from base.system.system import System -""" + class FileEventHandler(FileSystemEventHandler): def __init__(self, plugin_path): self.path = plugin_path def process(self, event): - if event.event_type == 'created': - result = Commander().set_event([None, 'load', '-p', event.src_path.replace(self.path, '')]) - if result is True: - if System.Ahenk.is_running() is True: + + if event.src_path != self.path[:-1]: + if event.event_type in ('created', 'modified', 'moved'): + plu_path = event.src_path + if event.event_type == 'moved': + plu_path = event.dest_path + result = Commander().set_event([None, 'load', '-p', plu_path.replace(self.path, '')]) + if result is True and System.Ahenk.is_running() is True: + os.kill(int(System.Ahenk.get_pid_number()), signal.SIGALRM) + elif event.event_type == 'deleted': + result = Commander().set_event([None, 'remove', '-p', event.src_path.replace(self.path, '')]) + if result is True and System.Ahenk.is_running() is True: os.kill(int(System.Ahenk.get_pid_number()), signal.SIGALRM) - elif event.event_type == 'deleted': - # TODO - print('plugin removed') - def on_created(self, event): + def on_any_event(self, event): if event.is_directory: self.process(event) - def on_deleted(self, event): - if event.is_directory: - self.process(event) - def on_modified(self,event): - print("MODIFIED-"+str(event.src_path)) - -""" class PluginInstallListener: - def listen(self, path): - pass - """ observer = Observer() event_handler = FileEventHandler(path) observer.schedule(event_handler, path, recursive=False) @@ -50,4 +45,3 @@ class PluginInstallListener: except KeyboardInterrupt: observer.stop() observer.join() - """ diff --git a/opt/ahenk/base/plugin/plugin_manager.py b/opt/ahenk/base/plugin/plugin_manager.py index 55b0afc..a9a70c5 100644 --- a/opt/ahenk/base/plugin/plugin_manager.py +++ b/opt/ahenk/base/plugin/plugin_manager.py @@ -4,7 +4,8 @@ # Author: Volkan Şahin import imp import os -import threading +from multiprocessing import Process + from base.Scope import Scope from base.model.PluginBean import PluginBean from base.model.modes.init_mode import InitMode @@ -14,6 +15,8 @@ from base.model.modes.safe_mode import SafeMode from base.model.modes.shutdown_mode import ShutdownMode from base.plugin.Plugin import Plugin from base.plugin.PluginQueue import PluginQueue +from base.plugin.plugin_install_listener import PluginInstallListener +from base.system.system import System # TODO create base abstract class @@ -31,7 +34,7 @@ class PluginManager(object): self.plugins = [] self.pluginQueueDict = dict() - # self.listener = self.install_listener() + self.listener = self.install_listener() self.delayed_profiles = {} self.delayed_tasks = {} @@ -177,18 +180,18 @@ class PluginManager(object): if ahenk_profiles is not None: self.logger.info('[PluginManager] Working on Ahenk profiles...') for agent_profile in ahenk_profiles: + same_plugin_profile = None + for usr_profile in user_profiles: + if usr_profile.plugin.name == agent_profile.plugin.name: + same_plugin_profile = usr_profile - if agent_profile.overridable.lower() != 'true': - temp_list = [] - for usr_profile in user_profiles: - if usr_profile.plugin.name != agent_profile.plugin.name: - temp_list.append(usr_profile) - else: - self.logger.debug('[PluginManager] User profile of {0} plugin will not executed because of profile override rules.'.format(agent_profile.plugin.name)) - user_profiles = temp_list - else: - self.logger.debug('[PluginManager] Agent profile of {0} plugin will not executed because of profile override rules.'.format(agent_profile.plugin.name)) - continue + if same_plugin_profile is not None: + if agent_profile.overridable.lower() == 'true': + self.logger.debug('[PluginManager] Agent profile of {0} plugin will not executed because of profile override rules.'.format(agent_profile.plugin.name)) + continue + else: + self.logger.warning('[PluginManager] User profile of {0} plugin will not executed because of profile override rules.'.format(agent_profile.plugin.name)) + user_profiles.remove(same_plugin_profile) agent_profile.set_username(None) self.process_profile(agent_profile) @@ -261,13 +264,11 @@ class PluginManager(object): self.logger.warning('[PluginManager] {0} not found in {1} plugin'.format((mode + '.py'), plugin_name)) return None - """ def install_listener(self): listener = PluginInstallListener() thread = Process(target=listener.listen, args=(System.Ahenk.plugins_path(),)) thread.start() return thread - """ def is_plugin_loaded(self, plugin_name): try: