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 returned', all_msg='All selected rules were returned') 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
def get_agents_summary_os(agent_list=None): """Get a list of available OS. Parameters ---------- agent_list : list[str] List of agents ID's Returns ------- WazuhResult """ result = AffectedItemsWazuhResult( none_msg='Could not get the operative system of the agents', all_msg='Showing the operative system of all specified agents', some_msg='Could not get the operative system of some agents') if agent_list: rbac_filters = get_rbac_filters(system_resources=get_agents_info(), permitted_resources=agent_list) # We don't consider agent 000 in order to get the summary db_query = WazuhDBQueryAgents(select=['os.platform'], default_sort_field='os_platform', min_select_fields=set(), distinct=True, query="id!=000", **rbac_filters) query_data = db_query.run() query_data['items'] = [ row['os']['platform'] for row in query_data['items'] ] result.affected_items = query_data['items'] result.total_affected_items = len(result.affected_items) return result
def remove_rules(rule_ids=None): """Remove a rule from the system. :param rule_ids: List of rule ids (None for all rules) :return Result of operation """ result = AffectedItemsWazuhResult( none_msg='No security rule was deleted', some_msg='Some security rules were not deleted', all_msg='All specified security rules were deleted') with RulesManager() as rum: for r_id in rule_ids: rule = rum.get_rule(int(r_id)) role_delete = rum.delete_rule(int(r_id)) if role_delete == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=r_id, error=WazuhError(4008)) elif not role_delete: result.add_failed_item(id_=r_id, error=WazuhError(4022)) elif rule: result.affected_items.append(rule) result.total_affected_items += 1 invalid_roles_tokens(roles=rule['roles']) result.affected_items = sorted(result.affected_items, key=lambda i: i['id']) return result
def get_outdated_agents(agent_list=None, offset=0, limit=common.database_limit, sort=None, search=None, select=None, q=None): """Gets the outdated agents. :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 search: Looks for items with the specified string. :param select: Select fields to return. Format: {"fields":["field1","field2"]}. :param q: Defines query to filter in DB. :return: AffectedItemsWazuhResult. """ result = AffectedItemsWazuhResult(all_msg='All selected agents information was returned', some_msg='Some agents information was not returned', none_msg='No agent information was returned' ) if agent_list: # Get manager version manager = Agent(id='000') manager.load_info_from_db() select = ['version', 'id', 'name'] if select is None else select rbac_filters = get_rbac_filters(system_resources=get_agents_info(), permitted_resources=agent_list) db_query = WazuhDBQueryAgents(offset=offset, limit=limit, sort=sort, search=search, select=select, query=f"version!={manager.version}" + (';' + q if q else ''), **rbac_filters) data = db_query.run() result.affected_items = data['items'] result.total_affected_items = data['totalItems'] return result
def files(agent_list=None, offset=0, limit=common.database_limit, sort=None, search=None, select=None, filters=None, q='', nested=True, summary=False, distinct=False): """Return a list of files from the syscheck database of the specified agents. Parameters ---------- agent_list : str Agent ID. filters : dict Fields to filter by. summary : bool Returns a summary grouping by filename. offset : int First item to return. limit : int Maximum number of items to return. sort : str Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}. search : str Looks for items with the specified string. select : list[str] Select fields to return. Format: ["field1","field2"]. q : str Query to filter by. nested : bool Specify whether there are nested fields or not. distinct : bool Look for distinct values. Returns ------- result : AffectedItemsWazuhResult Confirmation/Error message. """ if filters is None: filters = {} parameters = {"date": "date", "arch": "arch", "value.type": "value_type", "value.name": "value_name", "mtime": "mtime", "file": "file", "size": "size", "perm": "perm", "uname": "uname", "gname": "gname", "md5": "md5", "sha1": "sha1", "sha256": "sha256", "inode": "inode", "gid": "gid", "uid": "uid", "type": "type", "changes": "changes", "attributes": "attributes"} summary_parameters = {"date": "date", "mtime": "mtime", "file": "file"} result = AffectedItemsWazuhResult(all_msg='FIM findings of the agent were returned', none_msg='No FIM information was returned') if 'hash' in filters: q = f'(md5={filters["hash"]},sha1={filters["hash"]},sha256={filters["hash"]})' + ('' if not q else ';' + q) del filters['hash'] db_query = WazuhDBQuerySyscheck(agent_id=agent_list[0], offset=offset, limit=limit, sort=sort, search=search, filters=filters, nested=nested, query=q, select=select, table='fim_entry', distinct=distinct, fields=summary_parameters if summary else parameters, min_select_fields={'file'}) db_query = db_query.run() result.affected_items = db_query['items'] result.total_affected_items = db_query['totalItems'] return result
def run(agent_list=None): """Run syscheck scan. :param agent_list: Run syscheck in the agent. :return: AffectedItemsWazuhResult. """ result = AffectedItemsWazuhResult( all_msg='Syscheck scan was restarted on returned agents', some_msg='Syscheck scan was not restarted on some agents', none_msg='No syscheck scan was restarted') for agent_id in agent_list: try: agent_info = Agent(agent_id).get_basic_information() agent_status = agent_info.get('status', 'N/A') if agent_status.lower() != 'active': result.add_failed_item( id_=agent_id, error=WazuhError( 1601, extra_message='Status - {}'.format(agent_status))) else: oq = OssecQueue(common.ARQUEUE) oq.send_msg_to_agent(OssecQueue.HC_SK_RESTART, agent_id) result.affected_items.append(agent_id) oq.close() except WazuhError as e: result.add_failed_item(id_=agent_id, error=e) result.affected_items = sorted(result.affected_items, key=int) result.total_affected_items = len(result.affected_items) return result
def get_groups(offset=0, limit=common.database_limit, sort_by=None, sort_ascending=True, search_text=None, complementary_search=False, search_in_fields=None): """Get all the groups 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 :return: Dictionary: {'items': array of items, 'totalItems': Number of items (without applying the limit)} """ result = AffectedItemsWazuhResult(none_msg='No groups in rules were returned', some_msg='Some groups in rules were not returned', all_msg='All groups in rules were returned') groups = {group for rule in get_rules(limit=None).affected_items for group in rule['groups']} data = process_array(list(groups), 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_user_me(): """Get the information of the current user Returns ------- AffectedItemsWazuhResult with the desired information """ result = AffectedItemsWazuhResult(all_msg='Current user information was returned') affected_items = list() with AuthenticationManager() as auth: user = auth.get_user(common.current_user.get()) for index, role_id in enumerate(user['roles']): with RolesManager() as rm: role = rm.get_role_id(role_id=int(role_id)) role.pop('users') for index_r, rule_id in enumerate(role['rules']): with RulesManager() as rum: role['rules'][index_r] = rum.get_rule(rule_id=int(rule_id)) role['rules'][index_r].pop('roles') for index_p, policy_id in enumerate(role['policies']): with PoliciesManager() as pm: role['policies'][index_p] = pm.get_policy_id(policy_id=int(policy_id)) role['policies'][index_p].pop('roles') user['roles'][index] = role affected_items.append(user) if user else result.add_failed_item(id_=common.current_user.get(), error=WazuhError(5001)) data = process_array(affected_items) result.affected_items = data['items'] result.total_affected_items = data['totalItems'] return result
def remove_roles(role_ids): """Removes a certain role from the system :param role_ids: List of roles ids (None for all roles) :return Result of operation """ result = AffectedItemsWazuhResult(none_msg='No role were deleted', some_msg='Some roles could not be delete', all_msg='All specified roles were deleted') with RolesManager() as rm: for r_id in role_ids: role = rm.get_role_id(int(r_id)) if role != SecurityError.ROLE_NOT_EXIST and int(r_id) not in admin_role_ids: related_users = check_relationships([role]) role_delete = rm.delete_role(int(r_id)) if role_delete == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=r_id, error=WazuhError(4008)) elif not role_delete: result.add_failed_item(id_=r_id, error=WazuhError(4002)) elif role: result.affected_items.append(role) result.total_affected_items += 1 invalid_users_tokens(users=list(related_users)) result.affected_items = sorted(result.affected_items, key=lambda i: i['id']) return result
def remove_policies(policy_ids=None): """Removes a certain policy from the system :param policy_ids: ID of the policy to be removed (All for all policies) :return Result of operation """ result = AffectedItemsWazuhResult(none_msg='No policies were deleted', some_msg='Some policies could not be deleted', all_msg='All specified policies were deleted') with PoliciesManager() as pm: for p_id in policy_ids: policy = pm.get_policy_id(int(p_id)) if policy != SecurityError.POLICY_NOT_EXIST and int(p_id) not in admin_policy_ids: related_users = check_relationships(policy['roles']) policy_delete = pm.delete_policy(int(p_id)) if policy_delete == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=p_id, error=WazuhError(4008)) elif not policy_delete: result.add_failed_item(id_=p_id, error=WazuhError(4007)) elif policy: result.affected_items.append(policy) result.total_affected_items += 1 invalid_users_tokens(users=list(related_users)) result.affected_items = sorted(result.affected_items, key=lambda i: i['id']) return result
def remove_policies(policy_ids=None): """Removes a certain policy from the system :param policy_ids: ID of the policy to be removed (All for all policies) :return Result of operation """ result = AffectedItemsWazuhResult(none_msg='No policy was deleted', some_msg='Some policies were not deleted', all_msg='All specified policies were deleted') with PoliciesManager() as pm: for p_id in policy_ids: policy = pm.get_policy_id(int(p_id)) policy_delete = pm.delete_policy(int(p_id)) if policy_delete == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=int(p_id), error=WazuhError(4008)) elif policy_delete == SecurityError.RELATIONSHIP_ERROR: result.add_failed_item(id_=int(p_id), error=WazuhError(4025)) elif not policy_delete: result.add_failed_item(id_=int(p_id), error=WazuhError(4007)) elif policy: result.affected_items.append(policy) result.total_affected_items += 1 invalid_roles_tokens(roles=policy['roles']) result.affected_items = sorted(result.affected_items, key=lambda i: i['id']) return result
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_agents_summary_os(agent_list=None): """Gets a list of available OS. :param agent_list: List of agents ID's. :return: WazuhResult. """ result = AffectedItemsWazuhResult( none_msg='Could not get the operative system of the agents', all_msg='Showing the operative system of all specified agents', some_msg='Could not get the operative system of some agents') if len(agent_list) != 0: db_query = WazuhDBQueryAgents(select=['os.platform'], filters={'id': agent_list}, default_sort_field='os_platform', min_select_fields=set(), distinct=True) query_data = db_query.run() query_data['items'] = [ row['os']['platform'] for row in query_data['items'] ] result.affected_items = query_data['items'] result.total_affected_items = len(result.affected_items) return result
def remove_roles(role_ids): """Removes a certain role from the system :param role_ids: List of roles ids (None for all roles) :return Result of operation """ result = AffectedItemsWazuhResult(none_msg='No role was deleted', some_msg='Some roles were not deleted', all_msg='All specified roles were deleted') with RolesManager() as rm: for r_id in role_ids: role = rm.get_role_id(int(r_id)) role_delete = rm.delete_role(int(r_id)) if role_delete == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=int(r_id), error=WazuhError(4008)) elif role_delete == SecurityError.RELATIONSHIP_ERROR: result.add_failed_item(id_=int(r_id), error=WazuhError(4025)) elif not role_delete: result.add_failed_item(id_=int(r_id), error=WazuhError(4002)) elif role: result.affected_items.append(role) result.total_affected_items += 1 invalid_roles_tokens(roles=[role['id'] for role in result.affected_items]) result.affected_items = sorted(result.affected_items, key=lambda i: i['id']) 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[str, None] = None) -> AffectedItemsWazuhResult: """Run a syscheck scan in the specified agents. Parameters ---------- agent_list : Union[str, None] List of the agents IDs to run the scan for. Returns ------- result : AffectedItemsWazuhResult Confirmation/Error message. """ result = AffectedItemsWazuhResult( all_msg='Syscheck scan was restarted on returned agents', some_msg='Syscheck scan was not restarted on some agents', none_msg='No syscheck 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 non_eligible_agents = WazuhDBQueryAgents(limit=None, select=["id", "status"], query='status!=active', **rbac_filters).run()['items'] [ result.add_failed_item( id_=agent['id'], error=WazuhError(1601, extra_message=f'Status - {agent["status"]}')) 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 = sorted(result.affected_items, key=int) result.total_affected_items = len(result.affected_items) return result
def upgrade_agents(agent_list=None, wpk_repo=None, version=None, force=False, use_http=False, file_path=None, installer=None): """Start the agent upgrade process. Parameters ---------- agent_list : list List of agents ID's. wpk_repo : str URL for WPK download. version : str Version to upgrade to. force : bool force the update even if it is a downgrade. use_http : bool False for HTTPS protocol, True for HTTP protocol. file_path : str Path to the installation file. installer : str Selected installer. Returns ------- ID of created tasks """ result = AffectedItemsWazuhResult(all_msg='All upgrade tasks were created', some_msg='Some upgrade tasks were not created', none_msg='No upgrade task was created', sort_fields=['agent'], sort_ascending='True') agent_list = list(map(int, agents_padding(result=result, agent_list=agent_list))) if version and not version.startswith('v'): version = f'v{version}' agents_result_chunks = [agent_list[x:x + 100] for x in range(0, len(agent_list), 100)] agent_results = list() for agents_chunk in agents_result_chunks: agent_results.append( core_upgrade_agents(command='upgrade' if not (installer or file_path) else 'upgrade_custom', agents_chunk=agents_chunk, wpk_repo=wpk_repo, version=version, force=force, use_http=use_http, file_path=file_path, installer=installer)) for agent_result_chunk in agent_results: for agent_result in agent_result_chunk['data']: if agent_result['error'] == 0: task_agent = { 'agent': str(agent_result['agent']).zfill(3), 'task_id': agent_result['task_id'] } result.affected_items.append(task_agent) result.total_affected_items += 1 else: error = WazuhError(code=1810 + agent_result['error'], cmd_error=True, extra_message=agent_result['message']) result.add_failed_item(id_=str(agent_result['agent']).zfill(3), error=error) result.affected_items = sorted(result.affected_items, key=lambda k: k['agent']) return result
def get_agent_groups(group_list=None, offset=0, limit=None, sort=None, search=None, hash_algorithm='md5'): """Gets the existing groups. :param group_list: List of Group names. :param offset: First item to return. :param limit: Maximum number of items to return. :param sort: Fields to sort the items by. :param search: Text to search. :param hash_algorithm: hash algorithm used to get mergedsum and configsum. :return: AffectedItemsWazuhResult. """ affected_groups = list() result = AffectedItemsWazuhResult( all_msg='All selected groups information was returned', some_msg='Some groups information was not returned', none_msg='No group information was returned') if group_list: # Add failed items for invalid_group in set(group_list) - get_groups(): result.add_failed_item(id_=invalid_group, error=WazuhResourceNotFound(1710)) rbac_filters = get_rbac_filters(system_resources=get_groups(), permitted_resources=group_list) group_query = WazuhDBQueryGroup(offset=offset, limit=limit, sort=sort, search=search, **rbac_filters) query_data = group_query.run() for group in query_data['items']: full_entry = path.join(common.shared_path, group['name']) # merged.mg and agent.conf sum merged_sum = get_hash(path.join(full_entry, "merged.mg"), hash_algorithm) conf_sum = get_hash(path.join(full_entry, "agent.conf"), hash_algorithm) if merged_sum: group['mergedSum'] = merged_sum if conf_sum: group['configSum'] = conf_sum affected_groups.append(group) result.affected_items = affected_groups result.total_affected_items = query_data['totalItems'] return result
def get_users(user_ids: list = None, offset: int = 0, limit: int = common.database_limit, sort_by: dict = None, sort_ascending: bool = True, search_text: str = None, complementary_search: bool = False, search_in_fields: list = None): """Get the information of a specified user Parameters ---------- user_ids : list List of user ids offset : int First item to return limit : int Maximum number of items to return sort_by : dict Fields to sort the items by. Format: {"fields":["field1","field2"],"order":"asc|desc"} sort_ascending : bool Sort in ascending (true) or descending (false) order search_text : str Text to search complementary_search : bool Find items without the text to search search_in_fields : list Fields to search in Returns ------- AffectedItemsWazuhResult with the desired information """ result = AffectedItemsWazuhResult( none_msg='No user was returned', some_msg='Some users were not returned', all_msg='All specified users were returned') affected_items = list() with AuthenticationManager() as auth: for user_id in user_ids: user_id = int(user_id) user = auth.get_user_id(user_id) affected_items.append(user) if user else result.add_failed_item( id_=user_id, error=WazuhError(5001)) 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_lists(path=None, offset=0, limit=common.database_limit, select=None, sort_by=None, sort_ascending=True, search_text=None, complementary_search=False, search_in_fields=None, relative_dirname=None, filename=None): """Get CDB lists :param path: Relative path of list file to get (if it is not specified, all lists will be returned) :param offset: First item to return. :param limit: Maximum number of items to return. :param select: List of selected fields 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 relative_dirname: Filters by relative dirname. :param filename: List of filenames to filter by. :return: AffectedItemsWazuhResult """ result = AffectedItemsWazuhResult(none_msg='No list was shown', some_msg='Some lists could not be shown', all_msg='All specified lists were shown') lists = list() for rel_p in path: if not any([ relative_dirname is not None and os.path.dirname(rel_p) != relative_dirname, filename is not None and os.path.split(rel_p)[1] not in filename ]): lists.append({ 'items': get_list_from_file(rel_p), 'relative_dirname': os.path.dirname(rel_p), 'filename': os.path.split(rel_p)[1] }) data = process_array(lists, 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, select=select, allowed_sort_fields=SORT_FIELDS, required_fields=REQUIRED_FIELDS) result.affected_items = data['items'] result.total_affected_items = data['totalItems'] return result
def get_group_files(group_list=None, offset=0, limit=None, search_text=None, search_in_fields=None, complementary_search=False, sort_by=None, sort_ascending=True, hash_algorithm='md5'): """Gets the group files. :param group_list: List of Group names. :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 hash_algorithm: hash algorithm used to get mergedsum and configsum. :return: WazuhResult. """ # We access unique group_id from list, this may change if and when we decide to add option to get files for # a list of groups group_id = group_list[0] group_path = common.shared_path result = AffectedItemsWazuhResult(all_msg='All selected groups files were returned', some_msg='Some groups files were not returned', none_msg='No groups files were returned' ) if group_id: if not Agent.group_exists(group_id): result.add_failed_item(id_=group_id, error=WazuhResourceNotFound(1710)) return result group_path = path.join(common.shared_path, group_id) if not path.exists(group_path): result.add_failed_item(id_=group_path, error=WazuhError(1006)) return result try: data = [] for entry in listdir(group_path): item = dict() item['filename'] = entry item['hash'] = get_hash(path.join(group_path, entry), hash_algorithm) data.append(item) # ar.conf ar_path = path.join(common.shared_path, 'ar.conf') data.append({'filename': "ar.conf", 'hash': get_hash(ar_path, hash_algorithm)}) data = process_array(data, 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'] except WazuhError as e: result.add_failed_item(id_=group_path, error=e) raise e except Exception as e: raise WazuhInternalError(1727, extra_message=str(e)) return result
def get_ciscat_results(agent_list=None, offset=0, limit=common.database_limit, select=None, search=None, sort=None, filters=None, nested=True, array=True, q=''): """ Get CIS-CAT results for a list of agents :param agent_list: list of Agent ID to get scan results from. Currently, only first item will be considered :param offset: First element to return in the collection :param limit: Maximum number of elements to return :param select: Select which fields to return :param search: Looks for items with the specified string. Begins with '-' for a complementary search :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"} :param filters: Fields to filter by :param nested: Nested fields :param array: Array :param q: Defines query to filter in DB. :return: AffectedItemsWazuhResult """ result = AffectedItemsWazuhResult( all_msg='All CISCAT results were returned', some_msg='Some CISCAT results were not returned', none_msg='No CISCAT results were returned', sort_fields=['agent_id'] if sort is None else sort['fields'], sort_casting=['str'], sort_ascending=[sort['order'] == 'asc' for _ in sort['fields']] if sort is not None else ['True'] ) valid_select_fields = {'scan.id': 'scan_id', 'scan.time': 'scan_time', 'benchmark': 'benchmark', 'profile': 'profile', 'pass': '******', 'fail': 'fail', 'error': 'error', 'notchecked': 'notchecked', 'unknown': 'unknown', 'score': 'score'} table = 'ciscat_results' system_agents = get_agents_info() for agent in agent_list: try: if agent not in system_agents: raise WazuhResourceNotFound(1701) db_query = WazuhDBQuerySyscollector(agent_id=agent, offset=offset, limit=limit, select=select, search=search, sort=sort, filters=filters, fields=valid_select_fields, table=table, array=array, nested=nested, query=q) data = db_query.run() if len(data['items']) > 0: for item in data['items']: item['agent_id'] = agent result.affected_items.append(item) result.total_affected_items += data['totalItems'] except WazuhResourceNotFound as e: result.add_failed_item(id_=agent, error=e) result.affected_items = merge(*[[res] for res in result.affected_items], criteria=result.sort_fields, ascending=result.sort_ascending, types=result.sort_casting) return result
def get_lists(filename=None, offset=0, limit=common.database_limit, select=None, sort_by=None, sort_ascending=True, search_text=None, complementary_search=False, search_in_fields=None, relative_dirname=None): """Get CDB lists content. Parameters ---------- filename : list Filenames to filter by. offset : int First item to return. limit : int Maximum number of items to return. select : list List of selected fields to return. sort_by : dict Fields to sort the items by. Format: {"fields":["field1","field2"],"order":"asc|desc"} sort_ascending : boolean Sort in ascending (true) or descending (false) order. search_text : str Find items with the specified string. complementary_search : bool If True, only results NOT containing `search_text` will be returned. If False, only results that contains `search_text` will be returned. search_in_fields : str Name of the field to search in for the `search_text`. relative_dirname : str Filter by relative dirname. Returns ------- result : AffectedItemsWazuhResult Lists content. """ result = AffectedItemsWazuhResult(all_msg='All specified lists were returned', some_msg='Some lists were not returned', none_msg='No list was returned') dirname = join(common.ossec_path, relative_dirname) if relative_dirname else None lists = list() for path in get_filenames_paths(filename): # Only files which exist and whose dirname is the one specified by the user (if any), will be added to response. if not any([dirname is not None and path_dirname(path) != dirname, not isfile(path)]): lists.append({'items': [{'key': key, 'value': value} for key, value in get_list_from_file(path).items()], 'relative_dirname': path_dirname(to_relative_path(path)), 'filename': split(to_relative_path(path))[1]}) data = process_array(lists, 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, select=select, allowed_sort_fields=SORT_FIELDS, required_fields=REQUIRED_FIELDS) result.affected_items = data['items'] result.total_affected_items = data['totalItems'] return result
def get_path_lists(path=None, offset=0, limit=common.database_limit, sort_by=None, sort_ascending=True, search_text=None, complementary_search=False, search_in_fields=None, relative_dirname=None, filename=None): """Get paths of all CDB lists :param path: List of paths to read lists from :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 relative_dirname: Filters by relative dirname. :param filename: List of filenames to filter by. :return: AffectedItemsWazuhResult """ result = AffectedItemsWazuhResult(none_msg='No path was shown', some_msg='Some paths could not be shown', all_msg='All specified paths were shown') lists = iterate_lists(only_names=True) for item in list(lists): if any([ relative_dirname is not None and item['relative_dirname'] != relative_dirname, filename is not None and item['filename'] not in filename, os.path.join(item['relative_dirname'], item['filename']) not in path ]): lists.remove(item) data = process_array(lists, 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_item_agent(agent_list, offset=0, limit=common.database_limit, select=None, search=None, sort=None, filters=None, q='', array=True, nested=True, element_type='os'): """ Get syscollector information about a list of agents. :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 q: Defines query to filter in DB. :param filters: Fields to filter by :param nested: Nested fields :param array: Array :param element_type: Type of element to get syscollector information from :return: AffectedItemsWazuhResult """ result = AffectedItemsWazuhResult( none_msg='No syscollector information was returned', some_msg='Some syscollector information was not returned', all_msg='All specified syscollector information was returned', sort_fields=['agent_id'] if sort is None else sort['fields'], sort_casting=['str'], sort_ascending=[sort['order'] == 'asc' for _ in sort['fields']] if sort is not None else ['True'] ) for agent in agent_list: try: if agent not in get_agents_info(): raise WazuhResourceNotFound(1701) table, valid_select_fields = get_valid_fields(Type(element_type), agent_id=agent) db_query = WazuhDBQuerySyscollector(agent_id=agent, offset=offset, limit=limit, select=select, search=search, sort=sort, filters=filters, fields=valid_select_fields, table=table, array=array, nested=nested, query=q) data = db_query.run() for item in data['items']: item['agent_id'] = agent result.affected_items.append(item) result.total_affected_items += data['totalItems'] except WazuhResourceNotFound as e: result.add_failed_item(id_=agent, error=e) result.affected_items = merge(*[[res] for res in result.affected_items], criteria=result.sort_fields, ascending=result.sort_ascending, types=result.sort_casting) return result
def get_path_lists(filename=None, offset=0, limit=common.database_limit, sort_by=None, sort_ascending=True, search_text=None, complementary_search=False, search_in_fields=None, relative_dirname=None): """Get paths of all CDB lists. Parameters ---------- filename : list List of filenames to filter by. offset : int First item to return. limit : int Maximum number of items to return. sort_by : dict Fields to sort the items by. Format: {"fields":["field1","field2"],"order":"asc|desc"} sort_ascending : boolean Sort in ascending (true) or descending (false) order. search_text : str Find items with the specified string. complementary_search : bool If True, only results NOT containing `search_text` will be returned. If False, only results that contains `search_text` will be returned. search_in_fields : str Name of the field to search in for the `search_text`. relative_dirname : str Filter by relative dirname. Returns ------- result : AffectedItemsWazuhResult Paths of all CDB lists. """ result = AffectedItemsWazuhResult(all_msg='All specified paths were returned', some_msg='Some paths were not returned', none_msg='No path was returned') paths = get_filenames_paths(filename) lists = iterate_lists(only_names=True) for item in list(lists): if any([relative_dirname is not None and item['relative_dirname'] != relative_dirname, join(common.ossec_path, item['relative_dirname'], item['filename']) not in paths]): lists.remove(item) data = process_array(lists, 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 ossec_log_summary(months=3): """ Summary of ossec.log. :param months: Check logs of the last n months. By default is 3 months. :return: AffectedItemsWazuhResult """ result = AffectedItemsWazuhResult(all_msg=f"Log summarized successfully" f"{' in specified node' if node_id != 'manager' else ''}", some_msg='Could not summarize the log in some nodes', none_msg=f"Could not summarize the log" f"{' in specified node' if node_id != 'manager' else ''}" ) categories = dict() first_date = previous_month(months) with open(common.ossec_log, errors='ignore') as f: lines_count = 0 for line in f: if lines_count > 50000: break lines_count = lines_count + 1 line = get_ossec_log_fields(line) # Multiline logs if line is None: continue log_date, category, log_type, _, = line if log_date < first_date: break if category: if category in categories: categories[category]['all'] += 1 else: categories[category] = {'all': 1, 'info': 0, 'error': 0, 'critical': 0, 'warning': 0, 'debug': 0} categories[category][log_type] += 1 else: continue for k, v in categories.items(): result.affected_items.append({k: v}) result.affected_items = sorted(result.affected_items, key=lambda i: list(i.keys())[0]) result.total_affected_items = len(result.affected_items) return result
async def get_health_nodes(lc: local_client.LocalClient, filter_node=None): """ Wrapper for get_health """ result = AffectedItemsWazuhResult( all_msg='All selected nodes healthcheck information was returned', some_msg='Some nodes healthcheck information was not returned', none_msg='No healthcheck information was returned') data = await get_health(lc, filter_node=filter_node) for v in data['nodes'].values(): result.affected_items.append(v) result.affected_items = sorted(result.affected_items, key=lambda i: i['info']['name']) result.total_affected_items = len(result.affected_items) 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 get_decoders_files(status=None, relative_dirname=None, filename=None, offset=0, limit=common.database_limit, sort_by=None, sort_ascending=True, search_text=None, complementary_search=False, search_in_fields=None): """Gets a list of the available decoder files. :param status: Filters by status: enabled, disabled, all. :param relative_dirname: Filters by relative dirname. :param filename: List of filenames to filter by. :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 :return: AffectedItemsWazuhResult """ result = AffectedItemsWazuhResult(none_msg='No decoder files were returned', some_msg='Some decoder files were not returned', all_msg='All decoder files were returned') status = check_status(status) ruleset_conf = configuration.get_ossec_conf(section='ruleset')['ruleset'] if not ruleset_conf: raise WazuhInternalError(1500) decoders_files = list() tags = ['decoder_include', 'decoder_exclude', 'decoder_dir'] if isinstance(filename, list): for f in filename: decoders_files.extend(format_rule_decoder_file( ruleset_conf, {'status': status, 'relative_dirname': relative_dirname, 'filename': f}, tags)) else: decoders_files = format_rule_decoder_file( ruleset_conf, {'status': status, 'relative_dirname': relative_dirname, 'filename': filename}, tags) data = process_array(decoders_files, 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