def get_rule_file(filename=None, raw=False): """Read content of specified file. Parameters ---------- filename : str, optional Name of the rule file. Default `None` raw : bool, optional Whether to return the content in raw format (str->XML) or JSON. Default `False` (JSON format) Returns ------- str or dict Content of the file. AffectedItemsWazuhResult format if `raw=False`. """ result = AffectedItemsWazuhResult(none_msg='No rule was returned', all_msg='Selected rule was returned') files = get_rules_files(filename=filename).affected_items if len(files) > 0: rules_path = files[0]['relative_dirname'] try: full_path = join(common.wazuh_path, rules_path, filename) with open(full_path) as f: content = f.read() if raw: result = content else: # Missing root tag in rule file result.affected_items.append(xmltodict.parse(f'<root>{content}</root>')['root']) result.total_affected_items = 1 except ExpatError as e: result.add_failed_item(id_=filename, error=WazuhError(1413, extra_message=f"{join('WAZUH_HOME', rules_path, filename)}:" f" {str(e)}")) except OSError: result.add_failed_item(id_=filename, error=WazuhError(1414, extra_message=join('WAZUH_HOME', rules_path, filename))) else: result.add_failed_item(id_=filename, error=WazuhError(1415)) return result
def upload_decoder_file(filename: str, content: str, overwrite: bool = False) -> AffectedItemsWazuhResult: """Upload a new decoder file or update an existing one. Parameters ---------- filename : str Name of the decoder file. content : str Content of the file. It must be a valid XML file. overwrite : bool True for updating existing files. False otherwise. Returns ------- AffectedItemsWazuhResult """ result = AffectedItemsWazuhResult(all_msg='Decoder was successfully uploaded', none_msg='Could not upload decoder' ) full_path = join(common.user_decoders_path, filename) backup_file = '' try: if len(content) == 0: raise WazuhError(1112) validate_wazuh_xml(content) # If file already exists and overwrite is False, raise exception if not overwrite and exists(full_path): raise WazuhError(1905) elif overwrite and exists(full_path): backup_file = f'{full_path}.backup' delete_file_with_backup(backup_file, full_path, delete_decoder_file) upload_file(content, to_relative_path(full_path)) result.affected_items.append(to_relative_path(full_path)) result.total_affected_items = len(result.affected_items) backup_file and exists(backup_file) and remove(backup_file) except WazuhError as e: result.add_failed_item(id_=to_relative_path(full_path), error=e) finally: exists(backup_file) and safe_move(backup_file, full_path, permissions=0o0660) return result
def add_role(name=None): """Creates a role in the system :param name: The new role name :return Role information """ result = AffectedItemsWazuhResult(none_msg='Role was not created', all_msg='Role was successfully created') with RolesManager() as rm: status = rm.add_role(name=name) if status == SecurityError.ALREADY_EXIST: result.add_failed_item(id_=name, error=WazuhError(4005)) elif status == SecurityError.INVALID: result.add_failed_item(id_=name, error=WazuhError(4003)) else: result.affected_items.append(rm.get_role(name=name)) result.total_affected_items += 1 return result
def upload_group_file(group_id, file_data, file_name='agent.conf'): """ Updates a group file :param group_id: Group to update :param file_data: Upload data :param file_name: File name to update :return: Confirmation message in string """ # Check if the group exists if not os_path.exists(os_path.join(common.shared_path, group_id)): raise WazuhResourceNotFound(1710, group_id) if file_name == 'agent.conf': if len(file_data) == 0: raise WazuhError(1112) return upload_group_configuration(group_id, file_data) else: raise WazuhError(1111)
def get_decoder_file(filename: str, raw: bool = False) -> Union[str, AffectedItemsWazuhResult]: """Read content of specified file. Parameters ---------- filename : str Name of the decoder file. raw : bool Whether to return the content in raw format (str->XML) or JSON. Returns ------- str or dict Content of the file. AffectedItemsWazuhResult format if `raw=False`. """ result = AffectedItemsWazuhResult(none_msg='No decoder was returned', all_msg='Selected decoder was returned') decoders = get_decoders_files(filename=filename).affected_items if len(decoders) > 0: decoder_path = decoders[0]['relative_dirname'] try: full_path = join(common.wazuh_path, decoder_path, filename) with open(full_path) as f: file_content = f.read() if raw: result = file_content else: # Missing root tag in decoder file result.affected_items.append(xmltodict.parse(f'<root>{file_content}</root>')['root']) result.total_affected_items = 1 except ExpatError as e: result.add_failed_item(id_=filename, error=WazuhError(1501, extra_message=f"{join('WAZUH_HOME', decoder_path, filename)}:" f" {str(e)}")) except OSError: result.add_failed_item(id_=filename, error=WazuhError(1502, extra_message=join('WAZUH_HOME', decoder_path, filename))) else: result.add_failed_item(id_=filename, error=WazuhError(1503)) 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 totals(date): """ Returns the totals file. :param date: date object with the date value of the stats :return: Array of dictionaries. Each dictionary represents an hour. """ stat_filename = "" try: stat_filename = os.path.join( common.stats_path, "totals", str(date.year), MONTHS[date.month - 1], f"ossec-totals-{date.strftime('%d')}.log") stats = open(stat_filename, 'r') except IOError: raise WazuhError(1308, extra_message=stat_filename) response = [] alerts = [] for line in stats: data = line.split('-') if len(data) == 4: sigid = int(data[1]) level = int(data[2]) times = int(data[3]) alert = {'sigid': sigid, 'level': level, 'times': times} alerts.append(alert) else: data = line.split('--') if len(data) != 5: if len(data) in (0, 1): continue else: raise WazuhInternalError(1309) hour = int(data[0]) total_alerts = int(data[1]) events = int(data[2]) syscheck = int(data[3]) firewall = int(data[4]) response.append({ 'hour': hour, 'alerts': alerts, 'totalAlerts': total_alerts, 'events': events, 'syscheck': syscheck, 'firewall': firewall }) alerts = [] return WazuhResult({'data': response})
def totals_(date=datetime.utcnow()): """Compute statistical information for the current or specified date. Parameters ---------- date: date Date object with the date value of the stats, current date by default. Returns ------- array array of dictionaries. Each dictionary represents an hour. Raises ------ WazuhError Raised on `IOError`. """ try: stat_filename = os.path.join( common.stats_path, "totals", str(date.year), MONTHS[date.month - 1], f"ossec-totals-{date.strftime('%d')}.log") with open(stat_filename, mode='r') as statsf: stats = statsf.readlines() except IOError: raise WazuhError(1308, extra_message=stat_filename) alerts = [] affected = [] for line in stats: data = line.split('-') if len(data) == 4: alerts.append({ 'sigid': int(data[1]), 'level': int(data[2]), 'times': int(data[3]) }) else: data = line.split('--') if len(data) != 5: if len(data) in (0, 1): continue else: raise WazuhInternalError(1309) affected.append({ 'hour': int(data[0]), 'alerts': alerts, 'totalAlerts': int(data[1]), 'events': int(data[2]), 'syscheck': int(data[3]), 'firewall': int(data[4]) }) alerts = [] return affected
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_=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_=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 with AuthenticationManager() as am: user_list = list() for user in am.get_users(): if am.user_allow_run_as(username=user['username']): user_list.append(user['user_id']) invalid_users_tokens(users=user_list) 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 """ role = get_role(role_id[0]) if not role: raise WazuhResourceNotFound(4002) 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.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 set_role_rule(role_id, rule_ids, run_as=False): """Create a relationship between a role and one or more rules. Parameters ---------- role_id : int The new role_id rule_ids : list of int List of rule ids run_as : dict Login with an authorization context or not Returns ------- """ result = AffectedItemsWazuhResult(none_msg=f'No link was created to role {role_id[0]}', some_msg=f'Some security rules were not linked to role {role_id[0]}', all_msg=f'All security rules were linked to role {role_id[0]}') success = False with RolesRulesManager() as rrm: for rule_id in rule_ids: role_rule = rrm.add_rule_to_role(role_id=int(role_id[0]), rule_id=int(rule_id)) if role_rule == SecurityError.ALREADY_EXIST: result.add_failed_item(id_=int(rule_id), error=WazuhError(4023)) 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_=int(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 assign_agents_to_group(group_list=None, agent_list=None, replace=False, replace_list=None): """Assign a list of agents to a group. :param group_list: List of Group names. :param agent_list: List of Agent IDs. :param replace: Whether to append new group to current agent's group or replace it. :param replace_list: List of Group names that can be replaced. :return: AffectedItemsWazuhResult. """ group_id = group_list[0] result = AffectedItemsWazuhResult( all_msg=f'All selected agents were assigned to {group_id}' f'{" and removed from the other groups" if replace else ""}', some_msg=f'Some agents were not assigned to {group_id}' f'{" and removed from the other groups" if replace else ""}', none_msg='No agents were assigned to {0}'.format(group_id)) # Check if the group exists if not Agent.group_exists(group_id): raise WazuhError(1710) system_agents = get_agents_info() for agent_id in agent_list: try: if agent_id not in system_agents: raise WazuhError(1701) if agent_id == "000": raise WazuhError(1703) Agent.add_group_to_agent(group_id, agent_id, force=True, replace=replace, replace_list=replace_list) result.affected_items.append(agent_id) except WazuhException as e: result.add_failed_item(id_=agent_id, error=e) result.total_affected_items = len(result.affected_items) result.affected_items.sort(key=int) return result
def get_file_conf(filename, group_id=None, type_conf=None, return_format=None): """ Returns the configuration file as dictionary. :return: configuration file as dictionary. """ if not os_path.exists(os_path.join(common.shared_path, group_id)): raise WazuhResourceNotFound(1710, group_id) file_path = os_path.join(common.shared_path, group_id if not filename == 'ar.conf' else '', filename) if not os_path.exists(file_path): raise WazuhError(1006, file_path) types = { 'conf': get_agent_conf, 'rootkit_files': _rootkit_files2json, 'rootkit_trojans': _rootkit_trojans2json, 'rcl': _rcl2json } if type_conf: if type_conf in types: if type_conf == 'conf': data = types[type_conf](group_id, limit=None, filename=filename, return_format=return_format) else: data = types[type_conf](file_path) else: raise WazuhError(1104, "{0}. Valid types: {1}".format(type_conf, types.keys())) else: if filename == "agent.conf": data = get_agent_conf(group_id, limit=None, filename=filename, return_format=return_format) elif filename == "rootkit_files.txt": data = _rootkit_files2json(file_path) elif filename == "rootkit_trojans.txt": data = _rootkit_trojans2json(file_path) elif filename == "ar.conf": data = _ar_conf2json(file_path) else: data = _rcl2json(file_path) return data
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='Obtained information about all selected groups', some_msg='Some groups information was not obtained', none_msg='No group information was obtained') # Add failed items for invalid_group in set(group_list) - get_groups(): result.add_failed_item(id_=invalid_group, error=WazuhError(1710)) group_query = WazuhDBQueryGroup(filters={'name': group_list}, offset=offset, limit=limit, sort=sort, search=search) 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_file(filename=None): """Reads content of specified file :param filename: File name to read content from :return: File contents """ files = get_rules_files(filename=filename).affected_items if len(files) > 0: rules_path = files[0]['relative_dirname'] try: full_path = os.path.join(common.ossec_path, rules_path, filename) with open(full_path) as f: return f.read() except OSError: raise WazuhError(1414, extra_message=os.path.join( 'WAZUH_HOME', rules_path, filename)) else: raise WazuhError(1415)
def send(self, msg_bytes): if not isinstance(msg_bytes, bytes): raise WazuhError(1104, extra_message="Type must be bytes") try: sent = self.s.send(pack("<I", len(msg_bytes)) + msg_bytes) if sent == 0: raise WazuhInternalError(1014, extra_message="Number of sent bytes is 0") return sent except Exception as e: raise WazuhInternalError(1014, extra_message=str(e))
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') 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_ossec_conf(section=None, field=None, conf_file=common.ossec_conf): """ Returns ossec.conf (manager) as dictionary. :param section: Filters by section (i.e. rules). :param field: Filters by field in section (i.e. included). :param conf_file: Path of the configuration file to read. :return: ossec.conf (manager) as dictionary. """ try: # Read XML xml_data = load_wazuh_xml(conf_file) # Parse XML to JSON data = _ossecconf2json(xml_data) except Exception as e: raise WazuhError(1101, extra_message=str(e)) if section: try: data = {section: data[section]} except KeyError as e: if section not in conf_sections.keys(): raise WazuhError(1102, extra_message=e.args[0]) else: raise WazuhError(1106, extra_message=e.args[0]) if section and field: try: if isinstance(data[section], list): data = { section: [{ field: item[field] } for item in data[section]] } else: data = {section: {field: data[section][field]}} except KeyError: raise WazuhError(1103) return data
def remove_agent_from_groups(agent_list=None, group_list=None): """Removes an agent assigment from a list of groups. :param agent_list: List of agents ID's. :param group_list: List of Group names. :return: AffectedItemsWazuhResult. """ agent_id = agent_list[0] result = AffectedItemsWazuhResult( all_msg='Specified agent removed from shown groups', some_msg='Specified agent could not be removed from some groups', none_msg='Specified agent could not be removed from any group') # Check if agent exists and it is not 000 if agent_id == '000': raise WazuhError(1703) if agent_id not in get_agents_info(): raise WazuhError(1701) # We move default group to last position in case it is contained in group_list. When an agent is removed from all # groups it is reverted to 'default'. We try default last to avoid removing it and then adding again. try: group_list.append(group_list.pop(group_list.index('default'))) except ValueError: pass system_groups = get_groups() for group_id in group_list: try: if group_id not in system_groups: raise WazuhError(1710) Agent.unset_single_group_agent(agent_id=agent_id, group_id=group_id, force=True) result.affected_items.append(group_id) except WazuhException as e: result.add_failed_item(id_=group_id, error=e) result.total_affected_items = len(result.affected_items) result.affected_items.sort() return result
def unset_single_group_agent(agent_id, group_id, force=False): """Unset the agent group. If agent has multigroups, it will preserve all previous groups except the last one. :param agent_id: Agent ID. :param group_id: Group ID. :param force: Do not check if agent or group exists :return: Confirmation message. """ if not force: # Check if agent exists, it is not 000 and the group exists Agent(agent_id).get_basic_information() if agent_id == "000": raise WazuhError(1703) if not Agent.group_exists(group_id): raise WazuhResourceNotFound(1710) # Get agent's group group_name = Agent.get_agents_group_file(agent_id) group_list = group_name.split(',') # Check agent belongs to group group_id if group_id not in group_list: raise WazuhError(1734) elif group_id == 'default' and len(group_list) == 1: raise WazuhError(1745) # Remove group from group_list group_list.remove(group_id) set_default = False if len(group_list) > 1: multigroup_name = ','.join(group_list) elif not group_list: set_default = True multigroup_name = 'default' else: multigroup_name = group_list[0] # Update group file Agent.set_agent_group_file(agent_id, multigroup_name) return f"Agent '{agent_id}' removed from '{group_id}'." + ( " Agent reassigned to group default." if set_default else "")
def get_list_from_file(path): """Get CDB list from file :param path: Relative path of list file to get :return: CDB list """ file_path = join(common.ossec_path, path) output = list() try: with open(file_path) as f: for line in f.read().splitlines(): if 'TEMPLATE' not in line: # Check if key and value are not surrounded by double quotes if '"' not in line: key, value = line.split(':') # Check if key and/or value are surrounded by double quotes else: key, value = split_key_value_with_quotes( line, file_path) output.append({'key': key, 'value': value}) except OSError as e: if e.errno == 2: raise WazuhError(1802) elif e.errno == 13: raise WazuhError(1803) elif e.errno == 21: raise WazuhError(1804, extra_message="{0} {1}".format( join('WAZUH_HOME', file_path), "is a directory")) else: raise e except ValueError: raise WazuhError(1800, extra_message={'path': join('WAZUH_HOME', file_path)}) return output
def get_key(self): """Gets agent key. :return: Agent key. """ self.load_info_from_db() if self.id != "000": self.key = self.compute_key() else: raise WazuhError(1703) return self.key
def create_message(command, custom, arguments): """Create the message that will be sent :param command: Command running in the agent. If this value starts by !, then it refers to a script name instead of a command name :param custom: Whether the specified command is a custom command or not :param arguments: Command arguments :return: WazuhResult. """ 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 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 WazuhResourceNotFound( 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_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) 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.USER_NOT_EXIST: result.add_failed_item(id_=int(user_id[0]), error=WazuhError(5001)) break 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 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: with TokenManager() as tm: tm.add_user_roles_rules(users={user_id}) result.affected_items.append(user) result.total_affected_items += 1 result.affected_items.sort(key=str) return result
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_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 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 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