def create_message(command: str = '', custom: bool = False, arguments: list = None) -> str: """Create the message that will be sent. Parameters ---------- command : str Command running in the agent. If this value starts with !, then it refers to a script name instead of a command name. custom : bool Whether the specified command is a custom command or not. arguments : list Command arguments. Raises ------ WazuhError(1650) If the command is not specified. WazuhError(1652) If the command is not custom and the command is not one of the available commands. Returns ------- str Message that will be sent to the socket. """ if not command: raise WazuhError(1650) commands = get_commands() if not custom and command not in commands: raise WazuhError(1652) msg_queue = "!{}".format(command) if custom else command msg_queue += " " + " ".join(shell_escape(str(x)) for x in arguments) if arguments else " - -" return msg_queue
def remove_role_rule(role_id, rule_ids): """Remove a relationship between a role and one or more rules. :param role_id: The new role_id :param rule_ids: List of rule ids :return Result of operation """ result = AffectedItemsWazuhResult( none_msg=f'No security rule was unlinked from role {role_id[0]}', some_msg= f'Some security rules were not unlinked from role {role_id[0]}', all_msg=f'All security rules were unlinked from role {role_id[0]}') success = False with RolesRulesManager() as rrm: for rule_id in rule_ids: role_rule = rrm.remove_rule_in_role(role_id=int(role_id[0]), rule_id=int(rule_id)) if role_rule == SecurityError.INVALID: result.add_failed_item(id_=rule_id, error=WazuhError(4024)) elif role_rule == SecurityError.ROLE_NOT_EXIST: result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4002)) elif role_rule == SecurityError.RULE_NOT_EXIST: result.add_failed_item(id_=rule_id, error=WazuhError(4022)) elif role_rule == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4008)) else: success = True result.total_affected_items += 1 if success: with RolesManager() as rm: result.affected_items.append( rm.get_role_id(role_id=role_id[0])) # Invalidate users with auth_context invalid_run_as_tokens() result.affected_items.sort(key=str) return result
def remove_role_policy(role_id, policy_ids): """Removes a relationship between a role and a policy :param role_id: The new role_id :param policy_ids: List of policies ids :return Result of operation """ result = AffectedItemsWazuhResult( none_msg=f'No policy was unlinked from role {role_id[0]}', some_msg=f'Some policies were not unlinked from role {role_id[0]}', all_msg=f'All policies were unlinked from role {role_id[0]}') success = False with RolesPoliciesManager() as rpm: for policy_id in policy_ids: policy_id = int(policy_id) role_policy = rpm.remove_policy_in_role(role_id=role_id[0], policy_id=policy_id) if role_policy == SecurityError.INVALID: result.add_failed_item(id_=policy_id, error=WazuhError(4010)) elif role_policy == SecurityError.ROLE_NOT_EXIST: result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4002)) elif role_policy == SecurityError.POLICY_NOT_EXIST: result.add_failed_item(id_=policy_id, error=WazuhError(4007)) elif role_policy == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4008)) else: success = True result.total_affected_items += 1 if success: with RolesManager() as rm: result.affected_items.append( rm.get_role_id(role_id=role_id[0])) role = rm.get_role_id(role_id=role_id[0]) invalid_roles_tokens(roles=[role['id']]) result.affected_items.sort(key=str) return result
def add_policy(name=None, policy=None): """Creates a policy in the system :param name: The new policy name :param policy: The new policy :return Policy information """ result = AffectedItemsWazuhResult( none_msg='Policy was not created', all_msg='Policy was successfully created') sanitize_rbac_policy(policy) with PoliciesManager() as pm: status = pm.add_policy(name=name, policy=policy) if status == SecurityError.ALREADY_EXIST: result.add_failed_item(id_=name, error=WazuhError(4009)) elif status == SecurityError.INVALID: result.add_failed_item(id_=name, error=WazuhError(4006)) else: result.affected_items.append(pm.get_policy(name=name)) result.total_affected_items += 1 return result
def get_agent_conf_multigroup(multigroup_id=None, offset=0, limit=common.database_limit, filename=None): """ Returns agent.conf as dictionary. :return: agent.conf as dictionary. """ # Check if a multigroup_id is provided and it exists if multigroup_id and not os_path.exists( os_path.join(common.multi_groups_path, multigroup_id)) or not multigroup_id: raise WazuhError(1710, extra_message=multigroup_id if multigroup_id else "No multigroup provided") agent_conf_name = filename if filename else 'agent.conf' agent_conf = os_path.join(common.multi_groups_path, multigroup_id, agent_conf_name) if not os_path.exists(agent_conf): raise WazuhError(1006, extra_message=os_path.join("WAZUH_PATH", "var", "multigroups", agent_conf)) try: # Read XML xml_data = load_wazuh_xml(agent_conf) # Parse XML to JSON data = _agentconf2json(xml_data) except Exception: raise WazuhError(1101) return { 'totalItems': len(data), 'items': cut_array(data, offset=offset, limit=limit) }
def remove_users(user_ids): """Remove a specified list of users Parameters ---------- user_ids : list List of IDs Returns ------- Status message """ result = AffectedItemsWazuhResult( none_msg='No user was deleted', some_msg='Some users were not deleted', all_msg='Users were successfully deleted') with AuthenticationManager() as auth: for user_id in user_ids: user_id = int(user_id) current_user = auth.get_user(common.current_user.get()) if not isinstance(current_user, bool) and user_id == int( current_user['id']) and user_id > max_id_reserved: result.add_failed_item(id_=user_id, error=WazuhError(5008)) continue user = auth.get_user_id(user_id) query = auth.delete_user(user_id) if not query: result.add_failed_item(id_=user_id, error=WazuhError(5001)) elif query == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=user_id, error=WazuhError(5004)) elif query == SecurityError.RELATIONSHIP_ERROR: result.add_failed_item(id_=user_id, error=WazuhError(4025)) elif user: invalid_users_tokens(users=[user_id]) result.affected_items.append(user) result.total_affected_items += 1 result.affected_items.sort(key=str) return result
def get_agent_conf(group_id=None, offset=0, limit=common.database_limit, filename='agent.conf', return_format=None): """ Returns agent.conf as dictionary. :return: agent.conf as dictionary. """ if not os_path.exists(os_path.join(common.shared_path, group_id)): raise WazuhResourceNotFound(1710, group_id) agent_conf = os_path.join(common.shared_path, group_id if group_id is not None else '', filename) if not os_path.exists(agent_conf): raise WazuhError(1006, agent_conf) try: # Read RAW file if filename == 'agent.conf' and return_format and 'xml' == return_format.lower( ): with open(agent_conf, 'r') as xml_data: data = xml_data.read() return data # Parse XML to JSON else: # Read XML xml_data = load_wazuh_xml(agent_conf) data = _agentconf2json(xml_data) except Exception as e: raise WazuhError(1101, str(e)) return { 'total_affected_items': len(data), 'affected_items': cut_array(data, offset=offset, limit=limit) }
def get_requirement(requirement=None, offset=0, limit=common.database_limit, sort_by=None, sort_ascending=True, search_text=None, complementary_search=False, search_in_fields=None): """Get the requirements used in the rules :param offset: First item to return. :param limit: Maximum number of items to return. :param sort_by: Fields to sort the items by :param sort_ascending: Sort in ascending (true) or descending (false) order :param search_text: Text to search :param complementary_search: Find items without the text to search :param search_in_fields: Fields to search in :param requirement: Requirement to get :return: Dictionary: {'items': array of items, 'totalItems': Number of items (without applying the limit)} """ result = AffectedItemsWazuhResult(none_msg='No rule was shown', all_msg='Selected rules were shown') if requirement not in RULE_REQUIREMENTS: result.add_failed_item( id_=requirement, error=WazuhError( 1205, extra_message=requirement, extra_remediation=f'Valid ones are {RULE_REQUIREMENTS}')) return result req = list({ req for rule in get_rules(limit=None).affected_items for req in rule[requirement] }) data = process_array(req, search_text=search_text, search_in_fields=search_in_fields, complementary_search=complementary_search, sort_by=sort_by, sort_ascending=sort_ascending, offset=offset, limit=limit) result.affected_items = data['items'] result.total_affected_items = data['totalItems'] return result
async def forward(node_name: Tuple) -> [wresults.AbstractWazuhResult, exception.WazuhException]: """Forward a request to a node. Parameters ---------- node_name : tuple Node to forward a request to. Returns ------- wresults.AbstractWazuhResult or exception.WazuhException """ node_name, agent_list = node_name if agent_list: self.f_kwargs['agent_id' if 'agent_id' in self.f_kwargs else 'agent_list'] = agent_list if node_name == 'unknown' or node_name == '' or node_name == self.node_info['node']: # The request will be executed locally if the the node to forward to is unknown, empty or the master # itself result = await self.distribute_function() else: if 'tmp_file' in self.f_kwargs: await self.send_tmp_file(node_name) client = self.get_client() try: result = json.loads(await client.execute(b'dapi_forward', "{} {}".format(node_name, json.dumps(self.to_dict(), cls=c_common.WazuhJSONEncoder) ).encode(), self.wait_for_complete), object_hook=c_common.as_wazuh_object) except WazuhClusterError as e: if e.code == 3022: result = e else: raise e # Convert a non existing node into a WazuhError exception if isinstance(result, WazuhClusterError) and result.code == 3022: common.rbac.set(self.rbac_permissions) try: await get_nodes_info(client, filter_node=[node_name]) except WazuhError as e: if e.code == 4000: result = e dikt = result.to_dict() # Add node ID to error message dikt['ids'] = {node_name} result = WazuhError.from_dict(dikt) return result if isinstance(result, (wresults.AbstractWazuhResult, exception.WazuhException)) \ else wresults.WazuhResult(result)
def create_user(username: str = None, password: str = None, allow_run_as: bool = False): """Create a new user Parameters ---------- username : str Name for the new user password : str Password for the new user allow_run_as : bool Enable authorization context login method for the new user Returns ------- result : AffectedItemsWazuhResult Status message """ if len(password) > 64 or len(password) < 8: raise WazuhError(5009) elif not _user_password.match(password): raise WazuhError(5007) result = AffectedItemsWazuhResult(none_msg='User could not be created', all_msg='User was successfully created') with AuthenticationManager() as auth: if auth.add_user(username, password, allow_run_as=allow_run_as): operation = auth.get_user(username) if operation: result.affected_items.append(operation) result.total_affected_items = 1 else: result.add_failed_item(id_=username, error=WazuhError(5000)) else: result.add_failed_item(id_=username, error=WazuhError(5000)) return result
def remove_user_role(user_id, role_ids): """Create a relationship between a user and a role :param user_id: User id :param role_ids: List of role ids :return User-Roles information """ username = get_username(user_id=user_id) if username == 'unknown': raise WazuhResourceNotFound(5001) result = AffectedItemsWazuhResult( none_msg=f'No role was unlinked from user {username}', some_msg=f'Some roles were not unlinked from user {username}', all_msg=f'All roles were unlinked from user {username}') success = False with UserRolesManager() as urm: for role_id in role_ids: user_role = urm.remove_role_in_user(user_id=int(user_id[0]), role_id=role_id) if user_role == SecurityError.INVALID: result.add_failed_item(id_=int(role_id), error=WazuhError(4016)) elif user_role == SecurityError.ROLE_NOT_EXIST: result.add_failed_item(id_=int(role_id), error=WazuhError(4002)) elif user_role == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=int(user_id[0]), error=WazuhError(4008)) else: success = True result.total_affected_items += 1 if success: with AuthenticationManager() as auth: result.affected_items.append(auth.get_user_id(int(user_id[0]))) result.affected_items.sort(key=str) invalid_users_tokens(users=user_id) return result
def delete_groups(group_list=None): """Delete a list of groups and remove it from every agent assignments. :param group_list: List of Group names. :return: AffectedItemsWazuhResult. """ result = AffectedItemsWazuhResult(all_msg='All selected groups were deleted', some_msg='Some groups were not deleted', none_msg='No group was deleted') affected_agents = set() system_groups = get_groups() for group_id in group_list: try: # Check if group exists if group_id not in system_groups: raise WazuhResourceNotFound(1710) if group_id == 'default': raise WazuhError(1712) agent_list = list(map(operator.itemgetter('id'), WazuhDBQueryMultigroups(group_id=group_id, limit=None).run()['items'])) try: affected_agents_result = remove_agents_from_group(agent_list=agent_list, group_list=[group_id]) if affected_agents_result.total_failed_items != 0: raise WazuhError(4015) except WazuhError: raise WazuhError(4015) Agent.delete_single_group(group_id) result.affected_items.append(group_id) affected_agents.update(affected_agents_result.affected_items) except WazuhException as e: result.add_failed_item(id_=group_id, error=e) result['affected_agents'] = sorted(affected_agents, key=int) result.affected_items.sort() result.total_affected_items = len(result.affected_items) return result
def write_ossec_conf(new_conf: str): """ Replace the current wazuh configuration (ossec.conf) with the provided configuration. Parameters ---------- new_conf: str The new configuration to be applied. """ try: with open(common.ossec_conf, 'w') as f: f.writelines(new_conf) except Exception: raise WazuhError(1126)
def process_policy(self, policy): """Receives an unprocessed policy and transforms it into a specific format for treatment in the decorator. :param policy: Policy of the user """ resource_regex = \ r'^(\*)|' \ r'(([a-zA-Z0-9_.]+:[a-zA-Z0-9_.]+:[a-zA-Z0-9_.*/-]+\&)+' \ r'([a-zA-Z0-9_.]+:[a-zA-Z0-9_.]+:[a-zA-Z0-9_.*/-]+))|' \ r'([a-zA-Z0-9_.]+:[a-zA-Z0-9_.]+:[a-zA-Z0-9_.*/-]+)$' for action in policy['actions']: if action not in self.odict.keys(): self.odict[action] = dict() for resource in policy['resources']: if not re.match(resource_regex, resource): raise WazuhError(4500) resource_type = PreProcessor.is_combination(resource) if len(resource_type[1]) > 2: raise WazuhError(4500, extra_remediation="The maximum length for permission combinations is two") resource = resource_type[1] if resource != '*' else ['*:*:*'] self.remove_previous_elements(resource, action) self.odict[action]['&'.join(resource)] = policy['effect']
def get_cluster_items(): try: here = os.path.abspath(os.path.dirname(__file__)) with open(os.path.join(common.ossec_path, here, 'cluster.json')) as f: cluster_items = json.load(f) list( map( lambda x: setitem(x, 'permissions', int(x['permissions'], base=0)), filter(lambda x: 'permissions' in x, cluster_items['files'].values()))) return cluster_items except Exception as e: raise WazuhError(3005, str(e))
def group_exists(group_id): """Checks if the group exists :param group_id: Group ID. :return: True if group exists, False otherwise """ # Input Validation of group_id if not InputValidator().group(group_id): raise WazuhError(1722) if path.exists(path.join(common.shared_path, group_id)): return True else: return False
def update_user(user_id: str = None, password: str = None, allow_run_as: bool = None): """Update a specified user Parameters ---------- user_id : list User ID password : str Password for the new user allow_run_as : bool Enable authorization context login method for the new user Returns ------- Status message """ if password is None and allow_run_as is None: raise WazuhError(4001) if password: if len(password) > 64 or len(password) < 8: raise WazuhError(5009) elif not _user_password.match(password): raise WazuhError(5007) result = AffectedItemsWazuhResult(all_msg='User was successfully updated', none_msg='User could not be updated') with AuthenticationManager() as auth: query = auth.update_user(int(user_id[0]), password, allow_run_as) if query is False: result.add_failed_item(id_=int(user_id[0]), error=WazuhError(5001)) else: result.affected_items.append(auth.get_user_id(int(user_id[0]))) result.total_affected_items += 1 invalid_users_tokens(users=user_id) return result
def update_policy(policy_id=None, name=None, policy=None): """Updates a policy in the system :param policy_id: Policy id to be update :param name: The new policy name :param policy: The new policy :return Policy information """ if name is None and policy is None: raise WazuhError(4001) result = AffectedItemsWazuhResult( none_msg='Policy was not updated', all_msg='Policy was successfully updated') policy is not None and sanitize_rbac_policy(policy) with PoliciesManager() as pm: status = pm.update_policy(policy_id=policy_id[0], name=name, policy=policy) if status == SecurityError.ALREADY_EXIST: result.add_failed_item(id_=int(policy_id[0]), error=WazuhError(4013)) elif status == SecurityError.INVALID: result.add_failed_item(id_=int(policy_id[0]), error=WazuhError(4006)) elif status == SecurityError.POLICY_NOT_EXIST: result.add_failed_item(id_=int(policy_id[0]), error=WazuhError(4007)) elif status == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=int(policy_id[0]), error=WazuhError(4008)) else: updated = pm.get_policy_id(int(policy_id[0])) result.affected_items.append(updated) result.total_affected_items += 1 invalid_roles_tokens(roles=updated['roles']) return result
def remove_agent_from_group(group_list=None, agent_list=None): """Removes an agent assignment from a specified group. :param group_list: List of Group names. :param agent_list: List of Agent IDs. :return: Confirmation message. """ group_id = group_list[0] agent_id = agent_list[0] # Check if agent and group exist and it is not 000 if agent_id not in get_agents_info(): raise WazuhError(1701) if agent_id == '000': raise WazuhError(1703) if group_id not in get_groups(): raise WazuhError(1710) return WazuhResult({ 'message': Agent.unset_single_group_agent(agent_id=agent_id, group_id=group_id, force=True) })
def create_user(username: str = None, password: str = None): """Create a new user :param username: Name for the new user :param password: Password for the new user :return: Status message """ if not _user_password.match(password): raise WazuhError(5007) result = AffectedItemsWazuhResult(none_msg='User could not be created', all_msg='User created correctly') with AuthenticationManager() as auth: if auth.add_user(username, password): operation = auth.get_user(username) if operation: result.affected_items.append(operation) result.total_affected_items = 1 else: result.add_failed_item(id_=username, error=WazuhError(5000)) else: result.add_failed_item(id_=username, error=WazuhError(5000)) return result
def run_command(agent_list: list = None, command: str = '', arguments: list = None, custom: bool = False, alert: dict = None) -> AffectedItemsWazuhResult: """Run AR command in a specific agent. Parameters ---------- agent_list : list Agents list that will run the AR command. command : str Command running in the agents. If this value starts with !, then it refers to a script name instead of a command name. custom : bool Whether the specified command is a custom command or not. arguments : list Command arguments. alert : dict Alert information depending on the AR executed. Returns ------- AffectedItemsWazuhResult. """ result = AffectedItemsWazuhResult( all_msg='AR command was sent to all agents', some_msg='AR command was not sent to some agents', none_msg='AR command was not sent to any agent') if agent_list: wq = WazuhQueue(common.ARQUEUE) system_agents = get_agents_info() for agent_id in agent_list: try: if agent_id not in system_agents: raise WazuhResourceNotFound(1701) if agent_id == "000": raise WazuhError(1703) active_response.send_ar_message(agent_id, wq, command, arguments, custom, alert) result.affected_items.append(agent_id) result.total_affected_items += 1 except WazuhException as e: result.add_failed_item(id_=agent_id, error=e) result.affected_items.sort(key=int) wq.close() return result
def get_agents_sync_group(agent_list=None): """Get agents configuration sync status. :param agent_list: List of agents ID's. :return AffectedItemsWazuhResult. """ result = AffectedItemsWazuhResult( all_msg='Sync info was returned for all selected agents', some_msg='Sync info was not returned for some selected agents', none_msg='No sync info was returned', ) system_agents = get_agents_info() for agent_id in agent_list: try: if agent_id == "000": raise WazuhError(1703) if agent_id not in system_agents: raise WazuhResourceNotFound(1701) else: # Check if agent exists and it is active agent_info = Agent(agent_id).get_basic_information() # Check if it has a multigroup if len(agent_info['group']) > 1: multi_group = ','.join(agent_info['group']) multi_group = hashlib.sha256( multi_group.encode()).hexdigest()[:8] group_merged_path = path.join(common.multi_groups_path, multi_group, "merged.mg") else: group_merged_path = path.join(common.shared_path, agent_info['group'][0], "merged.mg") result.affected_items.append({ 'id': agent_id, 'synced': md5(group_merged_path) == agent_info['mergedSum'] }) except (IOError, KeyError): # The file couldn't be opened and therefore the group has not been synced result.affected_items.append({'id': agent_id, 'synced': False}) except WazuhException as e: result.add_failed_item(id_=agent_id, error=e) result.total_affected_items = len(result.affected_items) return result
async def get_system_nodes(): """Get the name of all the cluster nodes. Returns ------- list Name of each cluster node. """ try: lc = local_client.LocalClient() result = await get_nodes(lc) return [node['name'] for node in result['items']] except WazuhInternalError as e: if e.code == 3012: return WazuhError(3013) raise e
def get_rules(rule_ids=None, offset=0, limit=common.database_limit, sort_by=None, sort_ascending=True, search_text=None, complementary_search=False, search_in_fields=None): """Return information from all the security rules. It does not return information from its associated roles. :param rule_ids: List of rule ids (None for all rules) :param offset: First item to return :param limit: Maximum number of items to return :param sort_by: Fields to sort the items by. Format: {"fields":["field1","field2"],"order":"asc|desc"} :param sort_ascending: Sort in ascending (true) or descending (false) order :param search_text: Text to search :param complementary_search: Find items without the text to search :param search_in_fields: Fields to search in :return: Dictionary: {'items': array of items, 'totalItems': Number of items (without applying the limit)} """ affected_items = list() result = AffectedItemsWazuhResult( none_msg='No security rule was returned', some_msg='Some security rules were not returned', all_msg='All specified security rules were returned') with RulesManager() as rum: for ru_id in rule_ids: rule = rum.get_rule(int(ru_id)) if rule != SecurityError.RULE_NOT_EXIST: affected_items.append(rule) else: # Rule id does not exist result.add_failed_item(id_=ru_id, error=WazuhError(4022)) data = process_array(affected_items, search_text=search_text, search_in_fields=search_in_fields, complementary_search=complementary_search, sort_by=sort_by, sort_ascending=sort_ascending, offset=offset, limit=limit) result.affected_items = data['items'] result.total_affected_items = data['totalItems'] return result
def get_sca_list(agent_list=None, q="", offset=0, limit=common.database_limit, sort=None, search=None, select=None, filters=None): """ Get a list of policies analyzed in the configuration assessment for a given agent :param agent_list: agent id to get policies from :param q: Defines query to filter in DB. :param offset: First item to return. :param limit: Maximum number of items to return. :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}. :param search: Looks for items with the specified string. Format: {"fields": ["field1","field2"]} :param select: Select fields to return. Format: {"fields":["field1","field2"]}. :param filters: Define field filters required by the user. Format: {"field1":"value1", "field2":["value2","value3"]} :return: AffectedItemsWazuhResult """ result = AffectedItemsWazuhResult( all_msg='All selected sca information is shown', some_msg='Some sca information is not shown', none_msg='No sca information is shown') if len(agent_list) != 0: if agent_list[0] in get_agents_info(): select = list( fields_translation_sca.keys()) if select is None else select db_query = WazuhDBQuerySCA(agent_id=agent_list[0], offset=offset, limit=limit, sort=sort, search=search, select=select, count=True, get_data=True, query=q, filters=filters) data = db_query.run() result.affected_items.extend(data['items']) result.total_affected_items = data['totalItems'] else: result.add_failed_item(id_=agent_list[0], error=WazuhError(1701)) return result
def get_policies(policy_ids, offset=0, limit=common.database_limit, sort_by=None, sort_ascending=True, search_text=None, complementary_search=False, search_in_fields=None): """Returns the information of a certain policy :param policy_ids: ID of the policy on which the information will be collected (All for all policies) :param offset: First item to return :param limit: Maximum number of items to return :param sort_by: Fields to sort the items by. Format: {"fields":["field1","field2"],"order":"asc|desc"} :param sort_ascending: Sort in ascending (true) or descending (false) order :param search_text: Text to search :param complementary_search: Find items without the text to search :param search_in_fields: Fields to search in :return: Dictionary: {'items': array of items, 'totalItems': Number of items (without applying the limit)} """ result = AffectedItemsWazuhResult( none_msg='No policy was returned', some_msg='Some policies were not returned', all_msg='All specified policies were returned') affected_items = list() with PoliciesManager() as pm: for p_id in policy_ids: policy = pm.get_policy_id(int(p_id)) if policy != SecurityError.POLICY_NOT_EXIST: affected_items.append(policy) else: # Policy id does not exist result.add_failed_item(id_=int(p_id), error=WazuhError(4007)) data = process_array(affected_items, search_text=search_text, search_in_fields=search_in_fields, complementary_search=complementary_search, sort_by=sort_by, sort_ascending=sort_ascending, offset=offset, limit=limit) result.affected_items = data['items'] result.total_affected_items = data['totalItems'] return result
def run(agent_list: Union[list, None] = None) -> AffectedItemsWazuhResult: """Run a rootcheck scan in the specified agents. Parameters ---------- agent_list : Union[list, None] List of the agents IDs to run the scan for. Returns ------- result : AffectedItemsWazuhResult JSON containing the affected agents. """ result = AffectedItemsWazuhResult(all_msg='Rootcheck scan was restarted on returned agents', some_msg='Rootcheck scan was not restarted on some agents', none_msg='No rootcheck scan was restarted') system_agents = get_agents_info() rbac_filters = get_rbac_filters(system_resources=system_agents, permitted_resources=agent_list) agent_list = set(agent_list) not_found_agents = agent_list - system_agents # Add non existent agents to failed_items [result.add_failed_item(id_=agent, error=WazuhResourceNotFound(1701)) for agent in not_found_agents] # Add non eligible agents to failed_items with WazuhDBQueryAgents(limit=None, select=["id", "status"], query=f'status!=active', **rbac_filters) as db_query: non_eligible_agents = db_query.run()['items'] [result.add_failed_item( id_=agent['id'], error=WazuhError(1707)) for agent in non_eligible_agents] wq = WazuhQueue(common.ARQUEUE) eligible_agents = agent_list - not_found_agents - {d['id'] for d in non_eligible_agents} for agent_id in eligible_agents: try: wq.send_msg_to_agent(WazuhQueue.HC_SK_RESTART, agent_id) result.affected_items.append(agent_id) except WazuhError as e: result.add_failed_item(id_=agent_id, error=e) wq.close() result.affected_items.sort(key=int) result.total_affected_items = len(result.affected_items) return result
def get_agents(agent_list=None, offset=0, limit=common.database_limit, sort=None, search=None, select=None, filters=None, q=None): """Gets a list of available agents with basic attributes. :param agent_list: List of agents ID's. :param offset: First item to return. :param limit: Maximum number of items to return. :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}. :param select: Select fields to return. Format: {"fields":["field1","field2"]}. :param search: Looks for items with the specified string. Format: {"fields": ["field1","field2"]} :param filters: Defines required field filters. Format: {"field1":"value1", "field2":["value2","value3"]} :param q: Defines query to filter in DB. :return: AffectedItemsWazuhResult. """ result = AffectedItemsWazuhResult( all_msg='All selected agents information is shown', some_msg='Some agents information is not shown', none_msg='No agent information is shown') if len(agent_list) != 0: if filters is None: filters = dict() filters['id'] = agent_list system_agents = get_agents_info() for agent_id in agent_list: if agent_id not in system_agents: result.add_failed_item(id_=agent_id, error=WazuhError(1701)) db_query = WazuhDBQueryAgents(offset=offset, limit=limit, sort=sort, search=search, select=select, filters=filters, query=q) data = db_query.run() result.affected_items.extend(data['items']) result.total_affected_items = data['totalItems'] return result
def get_upgrade_result(agent_list=None): """Read upgrade result output from agent. Parameters ---------- agent_list : list List of agent ID's. Returns ------- Upgrade result. """ result = AffectedItemsWazuhResult( all_msg='All upgrade tasks were returned', some_msg='Some upgrade tasks were not returned', none_msg='No upgrade task was returned') agent_list = list( map(int, agents_padding(result=result, agent_list=agent_list))) agents_result_chunks = [ agent_list[x:x + 100] for x in range(0, len(agent_list), 100) ] task_results = list() for agents_chunk in agents_result_chunks: task_results.append( core_upgrade_agents(agents_chunk=agents_chunk, get_result=True)) for task_result_chunk in task_results: for task_result in task_result_chunk['data']: task_error = task_result.pop('error') if task_error == 0: task_result['agent'] = str(task_result['agent']).zfill(3) result.affected_items.append(task_result) result.total_affected_items += 1 else: error = WazuhError(code=1810 + task_error, cmd_error=True, extra_message=task_result['message']) result.add_failed_item(id_=str( task_result.pop('agent')).zfill(3), error=error) result.affected_items = sorted(result.affected_items, key=lambda k: k['agent']) return result
def create_json_message(command: str = '', arguments: list = None, alert: dict = None) -> str: """Create the JSON message that will be sent. Function used when Wazuh agent version is >= 4.2.0. Parameters ---------- command : str Command running in the agent. If this value starts by !, then it refers to a script name instead of a command name. arguments : list Command arguments. alert : dict Alert data that will be sent with the AR command. Raises ------ WazuhError(1650) If the command is not specified. Returns ------- str Message that will be sent to the socket. """ if not command: raise WazuhError(1650) cluster_enabled = not read_cluster_config()['disabled'] node_name = get_node().get('node') if cluster_enabled else None msg_queue = json.dumps( create_wazuh_socket_message(origin={ 'name': node_name, 'module': common.origin_module.get() }, command=command, parameters={ 'extra_args': arguments if arguments else [], 'alert': alert if alert else {} })) return msg_queue