def _initialize(self): """ Calculates all Wazuh installation metadata """ # info DB if possible try: conn = Connection(common.database_path_global) query = "SELECT * FROM info" conn.execute(query) for tuple_ in conn: if tuple_[0] == 'max_agents': self.max_agents = tuple_[1] elif tuple_[0] == 'openssl_support': self.openssl_support = tuple_[1] except Exception: self.max_agents = "N/A" self.openssl_support = "N/A" # Ruleset version ruleset_version_file = os.path.join(self.path, 'ruleset', 'VERSION') try: with open(ruleset_version_file, 'r') as f: line_regex = re.compile(r'(^\w+)="(.+)"') for line in f: match = line_regex.match(line) if match and len(match.groups()) == 2: self.ruleset_version = match.group(2) except: raise WazuhInternalError(1005, extra_message=ruleset_version_file) # Timezone info try: self.tz_offset = strftime("%z") self.tz_name = strftime("%Z") except Exception: self.tz_offset = None self.tz_name = None return self.to_dict()
def last_scan(agent_list): """Gets the last scan of the agent. :param agent_list: Agent ID. :return: AffectedItemsWazuhResult. """ my_agent = Agent(agent_list[0]) result = AffectedItemsWazuhResult(all_msg='Last syscheck scan of the agent was returned', none_msg='No last scan information was returned') # If agent status is never_connected, a KeyError happens try: agent_version = my_agent.get_basic_information(select=['version'])['version'] except KeyError: # If the agent is never_connected, it won't have either version (key error) or last scan information. result.affected_items.append({'start': None, 'end': None}) result.total_affected_items += 1 return result if WazuhVersion(agent_version) < WazuhVersion('Wazuh v3.7.0'): db_agent = glob('{0}/{1}-*.db'.format(common.database_path_agents, agent_list[0])) if not db_agent: raise WazuhInternalError(1600, extra_message=agent_list[0]) else: db_agent = db_agent[0] conn = Connection(db_agent) data = {} # end time query = "SELECT max(date_last) FROM pm_event WHERE log = 'Ending rootcheck scan.'" conn.execute(query) for t in conn: data['end'] = t['max(date_last)'] if t['max(date_last)'] is not None else "ND" # start time query = "SELECT max(date_last) FROM pm_event WHERE log = 'Starting rootcheck scan.'" conn.execute(query) for t in conn: data['start'] = t['max(date_last)'] if t['max(date_last)'] is not None else "ND" result.affected_items.append(data) else: fim_scan_info = WazuhDBQuerySyscheck(agent_id=agent_list[0], query='module=fim', offset=0, sort=None, search=None, limit=common.database_limit, select={'end', 'start'}, fields={'end': 'end_scan', 'start': 'start_scan', 'module': 'module'}, table='scan_info', default_sort_field='start_scan').run()['items'][0] end = None if not fim_scan_info['end'] else fim_scan_info['end'] start = None if not fim_scan_info['start'] else fim_scan_info['start'] # If start is None or the scan is running, end will be None. result.affected_items.append( {'start': start, 'end': None if start is None else None if end is None or end < start else end}) result.total_affected_items = len(result.affected_items) return result
def remove_bulk_agents(agent_ids_list: KeysView, logger): """ Removes files created by agents in worker nodes. This function doesn't remove agents from client.keys since the client.keys file is overwritten by the master node. :param agent_ids_list: List of agents ids to remove. :param logger: Logger to use :return: None. """ def remove_agent_file_type(agent_files: List[str]): """ Removes files if they exist :param agent_files: Path regexes of the files to remove :return: None """ for filetype in agent_files: filetype_glob = filetype.format(ossec_path=common.ossec_path, id='*', name='*', ip='*') filetype_agent = { filetype.format(ossec_path=common.ossec_path, id=a['id'], name=a['name'], ip=a['ip']) for a in agent_info } for agent_file in set( glob.iglob(filetype_glob)) & filetype_agent: logger.debug2("Removing {}".format(agent_file)) if os.path.isdir(agent_file): shutil.rmtree(agent_file) else: os.remove(agent_file) if not agent_ids_list: return # the function doesn't make sense if there is no agents to remove logger.info("Removing files from {} agents".format( len(agent_ids_list))) logger.debug("Agents to remove: {}".format(', '.join(agent_ids_list))) # the agents must be removed in groups of 997: 999 is the limit of SQL variables per query. Limit and offset are # always included in the SQL query, so that leaves 997 variables as limit. for agents_ids_sublist in itertools.zip_longest(*itertools.repeat( iter(agent_ids_list), 997), fillvalue='0'): agents_ids_sublist = list( filter(lambda x: x != '0', agents_ids_sublist)) # Get info from DB agent_info = Agent.get_agents_overview(q=",".join( ["id={}".format(i) for i in agents_ids_sublist]), select=['ip', 'id', 'name'], limit=None)['items'] logger.debug2("Removing files from agents {}".format( ', '.join(agents_ids_sublist))) files_to_remove = [ '{ossec_path}/queue/agent-info/{name}-{ip}', '{ossec_path}/queue/rootcheck/({name}) {ip}->rootcheck', '{ossec_path}/queue/diff/{name}', '{ossec_path}/queue/agent-groups/{id}', '{ossec_path}/queue/rids/{id}', '{ossec_path}/var/db/agents/{name}-{id}.db' ] remove_agent_file_type(files_to_remove) logger.debug2("Removing agent group assigments from database") # remove agent from groups db_global = glob.glob(common.database_path_global) if not db_global: raise WazuhInternalError(1600) conn = Connection(db_global[0]) agent_ids_db = { 'id_agent{}'.format(i): int(i) for i in agents_ids_sublist } conn.execute( 'delete from belongs where {}'.format(' or '.join([ 'id_agent = :{}'.format(i) for i in agent_ids_db.keys() ])), agent_ids_db) conn.commit() # Tell wazuhbd to delete agent database wdb_conn = WazuhDBConnection() wdb_conn.delete_agents_db(agents_ids_sublist) logger.info("Agent files removed")