Esempio n. 1
0
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')

    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)
            elif group_id == 'default':
                raise WazuhError(1712)
            agent_list = [agent['id'] for agent in 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)
            affected_agents_result.affected_items.sort(key=int)
            result.affected_items.append({group_id: affected_agents_result.affected_items})
        except WazuhException as e:
            result.add_failed_item(id_=group_id, error=e)

    result.affected_items.sort(key=lambda x: next(iter(x)))
    result.total_affected_items = len(result.affected_items)

    return result
Esempio n. 2
0
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 WazuhResourceNotFound(1710)
    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)
            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
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
def remove_agents_from_group(agent_list=None, group_list=None):
    """Remove a list of agents assignment from a specified group.

    :param agent_list: List of agents ID's.
    :param group_list: List of Group names.
    :return: AffectedItemsWazuhResult.
    """
    group_id = group_list[0]
    result = AffectedItemsWazuhResult(
        all_msg=f'All selected agents were removed from group {group_id}',
        some_msg=f'Some agents were not removed from group {group_id}',
        none_msg=f'No agent was removed from group {group_id}')

    system_groups = get_groups()
    system_agents = get_agents_info()
    # Check if group exists
    if group_id not in system_groups:
        raise WazuhResourceNotFound(1710)

    for agent_id in agent_list:
        try:
            if agent_id == '000':
                raise WazuhError(1703)
            elif agent_id not in system_agents:
                raise WazuhResourceNotFound(1701)
            Agent.unset_single_group_agent(agent_id=agent_id,
                                           group_id=group_id,
                                           force=True)
            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
Esempio n. 6
0
def send_ar_message(agent_id: str = '',
                    oq: OssecQueue = None,
                    command: str = '',
                    arguments: list = None,
                    custom: bool = False,
                    alert: dict = None) -> None:
    """Send the active response message to the agent.

    Parameters
    ----------
    agent_id : str
        ID specifying the agent where the msg_queue will be sent to.
    oq : OssecQueue
        OssecQueue used for the active response messages.
    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.

    Raises
    ------
    WazuhError(1651)
        If the agent with ID agent_id is not active.
    """
    # Agent basic information
    agent_info = Agent(agent_id).get_basic_information()

    # Check if agent is active
    if agent_info['status'].lower() != 'active':
        raise WazuhError(1651,
                         extra_message='{0}'.format(agent_info['status']))

    # Once we know the agent is active, store version
    agent_version = agent_info['version']

    # Check if AR is enabled
    agent_conf = Agent(agent_id).getconfig('com', 'active-response',
                                           agent_version)
    if agent_conf['active-response']['disabled'] == 'yes':
        raise WazuhError(1750)

    # Create classic msg or JSON msg depending on the agent version
    if WazuhVersion(agent_version) >= WazuhVersion(common.AR_LEGACY_VERSION):
        msg_queue = create_json_message(command=command,
                                        arguments=arguments,
                                        alert=alert)
    else:
        msg_queue = create_message(command=command,
                                   arguments=arguments,
                                   custom=custom)

    oq.send_msg_to_agent(msg=msg_queue,
                         agent_id=agent_id,
                         msg_type=OssecQueue.AR_TYPE)
Esempio n. 7
0
def test_failed_remove_single_group_agent(agent_patch, get_groups_patch,
                                          agent_groups, agent_id, group_id,
                                          expected_exception):
    with pytest.raises(WazuhException, match=f'.* {expected_exception} .*'):
        get_groups_patch.return_value = agent_groups
        agent_patch.return_value = AgentMock(agent_id, agent_groups)

        Agent.unset_single_group_agent(agent_id, group_id, force=False)
Esempio n. 8
0
def show_groups():
    groups_data = Agent.get_all_groups(limit=None)

    print("Groups ({0}):".format(groups_data['totalItems']))
    for g in groups_data['items']:
        print("  {0} ({1})".format(g['name'], g['count']))

    print("Unassigned agents: {0}.".format(
        Agent.get_agents_without_group()['totalItems']))
Esempio n. 9
0
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
Esempio n. 10
0
def get_agents_component_stats_json(agent_list=None, component=None):
    """Get statistics of an agent's component.

    Parameters
    ----------
    agent_list: list, optional
        List of agents ID's, by default None.
    component: str, optional
        Name of the component to get stats from, by default None.

    Returns
    -------
    AffectedItemsWazuhResult
        Component stats.
    """
    result = AffectedItemsWazuhResult(
        all_msg='Statistical information for each agent was successfully read',
        some_msg='Could not read statistical information for some agents',
        none_msg='Could not read statistical information for any agent')
    system_agents = get_agents_info()
    for agent_id in agent_list:
        try:
            if agent_id not in system_agents:
                raise WazuhResourceNotFound(1701)
            result.affected_items.append(
                Agent(agent_id).get_stats(component=component))
        except WazuhException as e:
            result.add_failed_item(id_=agent_id, error=e)
    result.total_affected_items = len(result.affected_items)

    return result
Esempio n. 11
0
def reconnect_agents(agent_list: Union[list, str] = None) -> AffectedItemsWazuhResult:
    """Force reconnect a list of agents.

    Parameters
    ----------
    agent_list : Union[list, str]
        List of agent IDs. All possible values from 000 onwards. Default `*`

    Returns
    -------
    AffectedItemsWazuhResult
    """
    result = AffectedItemsWazuhResult(all_msg='Force reconnect command was sent to all agents',
                                      some_msg='Force reconnect command was not sent to some agents',
                                      none_msg='Force reconnect command was not sent to any agent'
                                      )

    system_agents = get_agents_info()
    wq = WazuhQueue(common.ARQUEUE)
    for agent_id in agent_list:
        try:
            if agent_id not in system_agents:
                raise WazuhResourceNotFound(1701)
            if agent_id == "000":
                raise WazuhError(1703)
            Agent(agent_id).reconnect(wq)
            result.affected_items.append(agent_id)
        except WazuhException as e:
            result.add_failed_item(id_=agent_id, error=e)
    wq.close()

    result.total_affected_items = len(result.affected_items)
    result.affected_items.sort(key=int)

    return result
Esempio n. 12
0
def add_agent(name=None,
              agent_id=None,
              key=None,
              ip='any',
              force_time=-1,
              use_only_authd=False):
    """Adds a new Wazuh agent.

    :param name: name of the new agent.
    :param agent_id: id of the new agent.
    :param ip: IP of the new agent. It can be an IP, IP/NET or ANY.
    :param key: key of the new agent.
    :param force_time: Remove old agent with same IP if disconnected since <force_time> seconds.
    :param use_only_authd: Force the use of authd when adding and removing agents.
    :return: Agent ID and Agent key.
    """
    # Check length of agent name
    if len(name) > 128:
        raise WazuhError(1738)

    new_agent = Agent(name=name,
                      ip=ip,
                      id=agent_id,
                      key=key,
                      force=force_time,
                      use_only_authd=use_only_authd)

    return WazuhResult({'data': {'id': new_agent.id, 'key': new_agent.key}})
Esempio n. 13
0
def upgrade_agents(agent_list=None,
                   wpk_repo=None,
                   version=None,
                   force=False,
                   chunk_size=None,
                   use_http=False):
    """Read upgrade result output from agent.

    :param agent_list: List of agents ID's.
    :param wpk_repo: URL for WPK download.
    :param version: Version to upgrade to.
    :param force: force the update even if it is a downgrade.
    :param chunk_size: size of each update chunk.
    :param use_http: False for HTTPS protocol, True for HTTP protocol.
    :return: Upgrade message.
    """
    # We access unique agent_id from list, this may change if and when we decide to add option to upgrade a list of
    # agents
    agent_id = agent_list[0]

    return Agent(agent_id).upgrade(wpk_repo=wpk_repo,
                                   version=version,
                                   force=True if int(force) == 1 else False,
                                   chunk_size=chunk_size,
                                   use_http=use_http)
Esempio n. 14
0
def last_scan(agent_id):
    """Get the last rootcheck scan of an agent.

    :param agent_id: Agent ID.
    :return: Dictionary: end, start.
    """
    Agent(agent_id).get_basic_information()
    wdb_conn = WazuhDBConnection()

    # end time
    result = wdb_conn.execute(
        f"agent {agent_id} sql SELECT max(date_last) FROM pm_event WHERE "
        "log = 'Ending rootcheck scan.'")
    time = list(result[0].values())[0] if result else None
    end = datetime.utcfromtimestamp(time).strftime(
        date_format) if time is not None else None

    # start time
    result = wdb_conn.execute(
        f"agent {agent_id} sql SELECT max(date_last) FROM pm_event "
        "WHERE log = 'Starting rootcheck scan.'")
    time = list(result[0].values())[0] if result else None
    start = datetime.utcfromtimestamp(time).strftime(
        date_format) if time is not None else None

    return {
        'start':
        start,
        'end':
        None if start is None else None if end is None or end < start else end
    }
Esempio n. 15
0
    def get_health(self, filter_node) -> Dict:
        """
        Return healthcheck data

        :param filter_node: Node to filter by
        :return: Dictionary
        """
        workers_info = {
            key: val.to_dict()
            for key, val in self.clients.items()
            if filter_node is None or filter_node == {} or key in filter_node
        }
        n_connected_nodes = len(workers_info)
        if filter_node is None or self.configuration[
                'node_name'] in filter_node:
            workers_info.update(
                {self.configuration['node_name']: self.to_dict()})

        # Get active agents by node and format last keep alive date format
        for node_name in workers_info.keys():
            workers_info[node_name]["info"][
                "n_active_agents"] = Agent.get_agents_overview(
                    filters={
                        'status': 'active',
                        'node_name': node_name
                    })['totalItems']
            if workers_info[node_name]['info']['type'] != 'master':
                workers_info[node_name]['status']['last_keep_alive'] = str(
                    datetime.fromtimestamp(
                        workers_info[node_name]['status']['last_keep_alive']))

        return {"n_connected_nodes": n_connected_nodes, "nodes": workers_info}
Esempio n. 16
0
    def get_health(self, filter_node) -> Dict:
        """Get nodes and synchronization information.

        Parameters
        ----------
        filter_node : dict
            Whether to filter by a node or return all health information.

        Returns
        -------
        dict
            Dict object containing nodes information.
        """
        workers_info = {
            key: val.to_dict()
            for key, val in self.clients.items()
            if filter_node is None or filter_node == {} or key in filter_node
        }
        n_connected_nodes = len(workers_info)
        if filter_node is None or self.configuration[
                'node_name'] in filter_node:
            workers_info.update(
                {self.configuration['node_name']: self.to_dict()})

        # Get active agents by node and format last keep alive date format
        active_agents = Agent.get_agents_overview(filters={
            'status': 'active',
            'node_name': filter_node
        })['items']
        for agent in active_agents:
            if (agent_node := agent["node_name"]) in workers_info.keys():
                workers_info[agent_node]["info"]["n_active_agents"] = \
                    workers_info[agent_node]["info"].get("n_active_agents", 0) + 1
Esempio n. 17
0
    def get_health(self, filter_node) -> Dict:
        """Get nodes and synchronization information.

        Parameters
        ----------
        filter_node : dict
            Whether to filter by a node or return all health information.

        Returns
        -------
        dict
            Dict object containing nodes information.
        """
        workers_info = {key: val.to_dict() for key, val in self.clients.items()
                        if filter_node is None or filter_node == {} or key in filter_node}
        n_connected_nodes = len(workers_info)
        if filter_node is None or self.configuration['node_name'] in filter_node:
            workers_info.update({self.configuration['node_name']: self.to_dict()})

        # Get active agents by node and format last keep alive date format
        for node_name in workers_info.keys():
            workers_info[node_name]["info"]["n_active_agents"] = Agent.get_agents_overview(filters={'status': 'active', 'node_name': node_name})['totalItems']
            if workers_info[node_name]['info']['type'] != 'master':
                workers_info[node_name]['status']['last_keep_alive'] = str(
                    datetime.fromtimestamp(workers_info[node_name]['status']['last_keep_alive']))

        return {"n_connected_nodes": n_connected_nodes, "nodes": workers_info}
Esempio n. 18
0
def restart_agents(agent_list=None):
    """Restart a list of agents.

    :param agent_list: List of agents ID's.
    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(all_msg='Restart command was sent to all agents',
                                      some_msg='Restart command was not sent to some agents',
                                      none_msg='Restart command was not sent to any agent'
                                      )

    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)
            Agent(agent_id).restart()
            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
Esempio n. 19
0
def show_group(agent_id):
    agent_info = Agent(id=agent_id).get_basic_information()

    str_group = ', '.join(
        agent_info['group']) if 'group' in agent_info else "Null"
    print("The agent '{0}' with ID '{1}' belongs to groups: {2}.".format(
        agent_info['name'], agent_info['id'], str_group))
Esempio n. 20
0
def send_command(msg_queue, oq, agent_id):
    """Send the message to the agent

    :param msg_queue: Message previously created, contains what is necessary to launch the active response command
    in the agent.
    :param agent_id: Run AR command in the agent.
    :return: WazuhResult.
    """
    agent_info = Agent(agent_id).get_basic_information()
    if agent_info['status'].lower() != 'active':
        raise WazuhError(1651)
    agent_conf = Agent(agent_id).getconfig('com', 'active-response')
    if agent_conf['active-response']['disabled'] == 'yes':
        raise WazuhError(1750)
    oq.send_msg_to_agent(msg=msg_queue,
                         agent_id=agent_id,
                         msg_type=OssecQueue.AR_TYPE)
Esempio n. 21
0
    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)))
        # Remove agents in group of 500 elements (so wazuh-db socket is not saturated)
        for agents_ids_sublist in itertools.zip_longest(*itertools.repeat(iter(agent_ids_list), 500), 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/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
            wdb_conn = WazuhDBConnection()

            query_to_execute = 'global sql delete from belongs where {}'.format(' or '.join([
                'id_agent = {}'.format(agent_id) for agent_id in agents_ids_sublist
            ]))
            wdb_conn.run_wdb_command(query_to_execute)

        logger.info("Agent files removed")
Esempio n. 22
0
def get_agent_config(agent_list=None, component=None, config=None):
    """Read selected configuration from agent.

    :param agent_list: List of agents ID's.
    :param component: Selected component.
    :param config: Configuration to get, written on disk.
    :return: WazuhResult(Loaded configuration in JSON).
    """
    # We access unique agent_id from list, this may change if and when we decide a final way to handle get responses
    # with failed ids and a list of agents
    agent_id = agent_list[0]
    my_agent = Agent(agent_id)
    my_agent.load_info_from_db()

    if my_agent.status != "active":
        raise WazuhError(1740)

    return WazuhResult({'data': my_agent.getconfig(component=component, config=config, agent_version=my_agent.version)})
Esempio n. 23
0
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
Esempio n. 24
0
def show_agents_with_group(group_id):
    agents_data = Agent.get_agent_group(group_id, limit=None)

    if agents_data['totalItems'] == 0:
        print("No agents found in group '{0}'.".format(group_id))
    else:
        print("{0} agent(s) in group '{1}':".format(agents_data['totalItems'],
                                                    group_id))
        for agent in agents_data['items']:
            print("  ID: {0}  Name: {1}.".format(agent['id'], agent['name']))
Esempio n. 25
0
def list_outdated():
    agents = Agent.get_outdated_agents()
    if agents['totalItems'] == 0:
        print("All agents are updated.")
    else:
        print("%-6s%-35s %-25s" % ("ID", "Name", "Version"))
        for agent in agents['items']:
            print("%-6s%-35s %-25s" %
                  (agent['id'], agent['name'], agent['version']))
        print("\nTotal outdated agents: {0}".format(agents['totalItems']))
Esempio n. 26
0
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 WazuhError(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
Esempio n. 27
0
 def __init__(self, agent_id, offset=0, limit=common.database_limit, sort=None, search=None, select=None, query='',
              count=True, get_data=True, distinct=False, default_sort_field='name', filters=None, fields=fields):
     if filters is None:
         filters = {}
     # Check if the agent exists
     Agent(agent_id).get_basic_information()
     backend = WazuhDBBackend(agent_id)
     WazuhDBQuery.__init__(self, offset=offset, limit=limit, table='vuln_cves', sort=sort, search=search,
                           select=select, fields=fields, default_sort_field=default_sort_field,
                           default_sort_order='ASC', filters=filters, query=query, backend=backend,
                           min_select_fields=set(), count=count, get_data=get_data, distinct=distinct)
Esempio n. 28
0
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 was removed from returned groups',
        some_msg='Specified agent was not removed from some groups',
        none_msg='Specified agent was not 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 WazuhResourceNotFound(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 WazuhResourceNotFound(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
Esempio n. 29
0
def get_upgrade_result(agent_list=None, timeout=3):
    """Read upgrade result output from agent.

    :param agent_list: List of agents ID's.
    :param timeout: Maximum time for the call to be considered failed.
    :return: Upgrade result.
    """
    # We access unique agent_id from list, this may change if and when we decide to add option to upgrade a list of
    # agents
    agent_id = agent_list[0]

    return Agent(agent_id).upgrade_result(timeout=int(timeout))
Esempio n. 30
0
def delete_agents(agent_list=None, backup=False, purge=False, use_only_authd=False, filters=None, q=None):
    """Delete a list of agents.

    Parameters
    ----------
    agent_list : list
        List of agents ID's to be deleted.
    backup : bool
        Create backup before removing the agent.
    purge : bool
        Delete definitely from key store.
    use_only_authd : bool
        Force the use of authd when adding and removing agents.
    filters : dict
        Define required field filters. Format: {"field1":"value1", "field2":["value2","value3"]}
    q : str
        Define query to filter in DB.

    Returns
    -------
    result : AffectedItemsWazuhResult
        Result with affected agents.
    """
    result = AffectedItemsWazuhResult(all_msg='All selected agents were deleted',
                                      some_msg='Some agents were not deleted',
                                      none_msg='No agents were deleted'
                                      )
    if agent_list:
        system_agents = get_agents_info()
        rbac_filters = get_rbac_filters(system_resources=system_agents, permitted_resources=agent_list,
                                        filters=filters)

        db_query = WazuhDBQueryAgents(limit=None, select=["id"], query=q, **rbac_filters)
        data = db_query.run()
        can_purge_agents = list(map(operator.itemgetter('id'), data['items']))
        for agent_id in agent_list:
            try:
                if agent_id == "000":
                    raise WazuhError(1703)
                elif agent_id not in system_agents:
                    raise WazuhResourceNotFound(1701)
                elif agent_id not in can_purge_agents:
                    raise WazuhError(
                        1731,
                        extra_message="some of the requirements are not met -> {}".format(
                            ', '.join(f"{key}: {value}" for key, value in filters.items() if key != 'rbac_ids') +
                            (f', q: {q}' if q else '')
                        )
                    )
                else:
                    my_agent = Agent(agent_id)
                    my_agent.load_info_from_db()
                    my_agent.remove(backup=backup, purge=purge, use_only_authd=use_only_authd)
                    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