Exemplo n.º 1
0
def get_agents(agent_list=None,
               offset=0,
               limit=common.database_limit,
               sort=None,
               search=None,
               select=None,
               filters=None,
               q=None):
    """Gets a list of available agents with basic attributes.

    :param agent_list: List of agents ID's.
    :param offset: First item to return.
    :param limit: Maximum number of items to return.
    :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}.
    :param select: Select fields to return. Format: {"fields":["field1","field2"]}.
    :param search: Looks for items with the specified string. Format: {"fields": ["field1","field2"]}
    :param filters: Defines required field filters. Format: {"field1":"value1", "field2":["value2","value3"]}
    :param q: Defines query to filter in DB.
    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(
        all_msg='All selected agents information was returned',
        some_msg='Some agents information was not returned',
        none_msg='No agent information was returned')
    if agent_list:
        if filters is None:
            filters = dict()

        system_agents = get_agents_info()

        for agent_id in agent_list:
            if agent_id not in system_agents:
                result.add_failed_item(id_=agent_id,
                                       error=WazuhResourceNotFound(1701))

        rbac_filters = get_rbac_filters(system_resources=system_agents,
                                        permitted_resources=agent_list,
                                        filters=filters)

        db_query = WazuhDBQueryAgents(offset=offset,
                                      limit=limit,
                                      sort=sort,
                                      search=search,
                                      select=select,
                                      query=q,
                                      **rbac_filters)
        data = db_query.run()
        result.affected_items.extend(data['items'])
        result.total_affected_items = data['totalItems']

    return result
Exemplo n.º 2
0
def get_requirement(requirement=None,
                    offset=0,
                    limit=common.database_limit,
                    sort_by=None,
                    sort_ascending=True,
                    search_text=None,
                    complementary_search=False,
                    search_in_fields=None):
    """Get the requirements used in the rules

    :param offset: First item to return.
    :param limit: Maximum number of items to return.
    :param sort_by: Fields to sort the items by
    :param sort_ascending: Sort in ascending (true) or descending (false) order
    :param search_text: Text to search
    :param complementary_search: Find items without the text to search
    :param search_in_fields: Fields to search in
    :param requirement: Requirement to get
    :return: Dictionary: {'items': array of items, 'totalItems': Number of items (without applying the limit)}
    """
    result = AffectedItemsWazuhResult(none_msg='No rule was shown',
                                      all_msg='Selected rules were shown')

    if requirement not in RULE_REQUIREMENTS:
        result.add_failed_item(
            id_=requirement,
            error=WazuhError(
                1205,
                extra_message=requirement,
                extra_remediation=f'Valid ones are {RULE_REQUIREMENTS}'))

        return result

    req = list({
        req
        for rule in get_rules(limit=None).affected_items
        for req in rule[requirement]
    })

    data = process_array(req,
                         search_text=search_text,
                         search_in_fields=search_in_fields,
                         complementary_search=complementary_search,
                         sort_by=sort_by,
                         sort_ascending=sort_ascending,
                         offset=offset,
                         limit=limit)
    result.affected_items = data['items']
    result.total_affected_items = data['totalItems']

    return result
Exemplo n.º 3
0
def update_policy(policy_id=None, name=None, policy=None):
    """Updates a policy in the system

    :param policy_id: Policy id to be update
    :param name: The new policy name
    :param policy: The new policy
    :return Policy information
    """
    if name is None and policy is None:
        raise WazuhError(4001)
    result = AffectedItemsWazuhResult(none_msg='Policy was not updated',
                                      all_msg='Policy was successfully updated')
    with PoliciesManager() as pm:
        status = pm.update_policy(policy_id=policy_id[0], name=name, policy=policy)
        if status == SecurityError.ALREADY_EXIST:
            result.add_failed_item(id_=int(policy_id[0]), error=WazuhError(4013))
        elif status == SecurityError.INVALID:
            result.add_failed_item(id_=int(policy_id[0]), error=WazuhError(4006))
        elif status == SecurityError.POLICY_NOT_EXIST:
            result.add_failed_item(id_=int(policy_id[0]), error=WazuhError(4007))
        elif status == SecurityError.ADMIN_RESOURCES:
            result.add_failed_item(id_=int(policy_id[0]), error=WazuhError(4008))
        else:
            updated = pm.get_policy_id(int(policy_id[0]))
            result.affected_items.append(updated)
            result.total_affected_items += 1
            invalid_roles_tokens(roles=updated['roles'])

    return result
Exemplo n.º 4
0
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
Exemplo n.º 5
0
def remove_role_rule(role_id, rule_ids):
    """Remove a relationship between a role and one or more rules.

    :param role_id: The new role_id
    :param rule_ids: List of rule ids
    :return Result of operation
    """
    result = AffectedItemsWazuhResult(none_msg=f'No security rule was unlinked from role {role_id[0]}',
                                      some_msg=f'Some security rules were not unlinked from role {role_id[0]}',
                                      all_msg=f'All security rules were unlinked from role {role_id[0]}')
    success = False
    with RolesRulesManager() as rrm:
        for rule_id in rule_ids:
            role_rule = rrm.remove_rule_in_role(role_id=int(role_id[0]), rule_id=int(rule_id))
            if role_rule == SecurityError.INVALID:
                result.add_failed_item(id_=rule_id, error=WazuhError(4024))
            elif role_rule == SecurityError.ROLE_NOT_EXIST:
                result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4002))
            elif role_rule == SecurityError.RULE_NOT_EXIST:
                result.add_failed_item(id_=rule_id, error=WazuhError(4022))
            elif role_rule == SecurityError.ADMIN_RESOURCES:
                result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4008))
            else:
                success = True
                result.total_affected_items += 1
        if success:
            with RolesManager() as rm:
                result.affected_items.append(rm.get_role_id(role_id=role_id[0]))
                # Invalidate users with auth_context
                invalid_run_as_tokens()
            result.affected_items.sort(key=str)

    return result
Exemplo n.º 6
0
def remove_role_policy(role_id, policy_ids):
    """Removes a relationship between a role and a policy

    :param role_id: The new role_id
    :param policy_ids: List of policies ids
    :return Result of operation
    """
    result = AffectedItemsWazuhResult(none_msg=f'No policy was unlinked from role {role_id[0]}',
                                      some_msg=f'Some policies were not unlinked from role {role_id[0]}',
                                      all_msg=f'All policies were unlinked from role {role_id[0]}')
    success = False
    with RolesPoliciesManager() as rpm:
        for policy_id in policy_ids:
            policy_id = int(policy_id)
            role_policy = rpm.remove_policy_in_role(role_id=role_id[0], policy_id=policy_id)
            if role_policy == SecurityError.INVALID:
                result.add_failed_item(id_=policy_id, error=WazuhError(4010))
            elif role_policy == SecurityError.ROLE_NOT_EXIST:
                result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4002))
            elif role_policy == SecurityError.POLICY_NOT_EXIST:
                result.add_failed_item(id_=policy_id, error=WazuhError(4007))
            elif role_policy == SecurityError.ADMIN_RESOURCES:
                result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4008))
            else:
                success = True
                result.total_affected_items += 1
        if success:
            with RolesManager() as rm:
                result.affected_items.append(rm.get_role_id(role_id=role_id[0]))
                role = rm.get_role_id(role_id=role_id[0])
                invalid_roles_tokens(roles=[role['id']])
            result.affected_items.sort(key=str)

    return result
Exemplo n.º 7
0
def update_role(role_id=None, name=None):
    """Updates a role in the system

    :param role_id: Role id to be update
    :param name: The new role name
    :return Role information
    """
    if name is None:
        raise WazuhError(4001)
    result = AffectedItemsWazuhResult(none_msg='Role was not updated',
                                      all_msg='Role was successfully updated')
    with RolesManager() as rm:
        status = rm.update_role(role_id=role_id[0], name=name)
        if status == SecurityError.ALREADY_EXIST:
            result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4005))
        elif status == SecurityError.INVALID:
            result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4003))
        elif status == SecurityError.ROLE_NOT_EXIST:
            result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4002))
        elif status == SecurityError.ADMIN_RESOURCES:
            result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4008))
        else:
            updated = rm.get_role_id(int(role_id[0]))
            result.affected_items.append(updated)
            result.total_affected_items += 1
            invalid_roles_tokens(roles=role_id)

    return result
Exemplo n.º 8
0
def delete_agents(agent_list=None, backup=False, purge=False, status="all", older_than="7d", use_only_authd=False):
    """Deletes a list of agents.

    :param agent_list: List of agents ID's.
    :param backup: Create backup before removing the agent.
    :param purge: Delete definitely from key store.
    :param older_than:  Filters out disconnected agents for longer than specified. Time in seconds | "[n_days]d" |
    "[n_hours]h" | "[n_minutes]m" | "[n_seconds]s". For never_connected agents, uses the register date.
    :param status: Filters by agent status: active, disconnected or never_connected. Multiples statuses separated
    by commas.
    :param use_only_authd: Force the use of authd when adding and removing agents.
    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(all_msg='All selected agents were deleted',
                                      some_msg='Some agents were not deleted',
                                      none_msg='No agents were deleted'
                                      )
    if len(agent_list) != 0:
        system_agents = get_agents_info()
        filters = {'older_than': older_than, 'status': status}
        rbac_filters = get_rbac_filters(system_resources=system_agents, permitted_resources=agent_list,
                                        filters=filters)

        db_query = WazuhDBQueryAgents(limit=None, select=["id"], **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)
                else:
                    my_agent = Agent(agent_id)
                    my_agent.load_info_from_db()
                    if agent_id not in can_purge_agents:
                        raise WazuhError(
                            1731,
                            extra_message="The agent has a status different to '{0}' or the specified time "
                                          "frame 'older_than {1}' does not apply".format(status, older_than)
                        )
                    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)
        result['older_than'] = older_than

    return result
Exemplo n.º 9
0
def update_rule(rule_id=None, name=None, rule=None):
    """Update a rule from the system.

    :param rule_id: Rule id to be updated
    :param name: The new name
    :param rule: The new rule
    :return Rule information
    """
    if name is None and rule is None:
        raise WazuhError(4001)
    result = AffectedItemsWazuhResult(
        none_msg='Security rule was not updated',
        all_msg='Security rule was successfully updated')
    with RulesManager() as rum:
        status = rum.update_rule(rule_id=rule_id[0], name=name, rule=rule)
        if status == SecurityError.ALREADY_EXIST:
            result.add_failed_item(id_=int(rule_id[0]), error=WazuhError(4005))
        elif status == SecurityError.INVALID:
            result.add_failed_item(id_=int(rule_id[0]), error=WazuhError(4003))
        elif status == SecurityError.RULE_NOT_EXIST:
            result.add_failed_item(id_=int(rule_id[0]), error=WazuhError(4022))
        elif status == SecurityError.ADMIN_RESOURCES:
            result.add_failed_item(id_=int(rule_id[0]), error=WazuhError(4008))
        else:
            updated = rum.get_rule(rule_id[0])
            result.affected_items.append(updated)
            result.total_affected_items += 1
            invalid_roles_tokens(roles=updated['roles'])

    return result
Exemplo n.º 10
0
def list_handler(result: AffectedItemsWazuhResult,
                 original: dict = None,
                 allowed: dict = None,
                 target: dict = None,
                 add_denied: bool = False,
                 **post_proc_kwargs):
    """Post processor for framework list responses with affected items and optional denied items.

    Parameters
    ----------
    result : AffectedItemsWazuhResult
        Dict with affected_items, failed_items and str_priority.
    original : dict
        Original input call parameter values.
    allowed : dict
        Allowed input call parameter values.
    target : dict
        Name of the input parameters used to calculate resource access.
    add_denied : bool
        Flag to add denied permissions to answer.
    post_proc_kwargs : dict
        Additional kwargs used in post-processing.

    Returns
    -------
    AffectedItemsWazuhResult
    """
    if add_denied:
        for res_id, target_param in target.items():
            denied = _get_denied(original, allowed, target_param, res_id)
            if res_id in integer_resources:
                denied = {int(i) if i.isdigit() else i for i in denied}
            for denied_item in denied:
                result.add_failed_item(
                    id_=denied_item,
                    error=WazuhPermissionError(
                        4000,
                        extra_message=f'Resource type: {res_id}',
                        ids=denied))
    if not add_denied or post_proc_kwargs.get('force'):
        # Apply post processing exclusion/default values if the main resource was not explicit or
        # `force` parameter exists in `post_proc_kwargs` and is True
        if 'default_result_kwargs' in post_proc_kwargs and result is None:
            return AffectedItemsWazuhResult(
                **post_proc_kwargs['default_result_kwargs'])
        if 'exclude_codes' in post_proc_kwargs:
            result.remove_failed_items(post_proc_kwargs['exclude_codes'])

    return result
Exemplo n.º 11
0
def upload_list_file(filename=None, content=None, overwrite=False):
    """Upload a new list file.

    Parameters
    ----------
    filename : str
        Destination path of the new file.
    content : str
        Content of file to be uploaded.
    overwrite : bool
        True for updating existing files, false otherwise.

    Returns
    -------
    result : AffectedItemsWazuhResult
        Confirmation message.
    """
    result = AffectedItemsWazuhResult(all_msg='CDB list file uploaded successfully',
                                      none_msg='Could not upload CDB list file')
    full_path = join(common.user_lists_path, filename)
    backup_file = ''

    try:
        # Raise WazuhError if CDB list is not valid
        validate_cdb_list(content)

        # If file already exists and overwrite is False, raise exception.
        if not overwrite and exists(full_path):
            raise WazuhError(1905)
        # If file with same name already exists in subdirectory.
        elif get_filenames_paths([filename])[0] != full_path:
            raise WazuhError(1805)
        # Create backup and delete original CDB list.
        elif overwrite and exists(full_path):
            backup_file = f"{full_path}.backup"
            delete_file_with_backup(backup_file, full_path, delete_list_file)

        upload_file(content, to_relative_path(full_path), check_xml_formula_values=False)
        result.affected_items.append(to_relative_path(full_path))
        result.total_affected_items = len(result.affected_items)
        # Remove back up file if no exceptions were raised.
        exists(backup_file) and remove(backup_file)
    except WazuhError as e:
        result.add_failed_item(id_=to_relative_path(full_path), error=e)
    finally:
        # If backup file was not deleted (any exception was raised), it should be restored.
        exists(backup_file) and safe_move(backup_file, full_path, permissions=0o660)

    return result
Exemplo n.º 12
0
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
Exemplo n.º 13
0
def read_config_wrapper():
    """ Wrapper for read_config

    :return: AffectedItemsWazuhResult
    """
    result = AffectedItemsWazuhResult(
        all_msg='All selected information is shown',
        none_msg='No information is shown')
    try:
        result.affected_items.append(read_config())
    except WazuhError as e:
        result.add_failed_item(id_=node_id, error=e)
    result.total_affected_items = len(result.affected_items)

    return result
Exemplo n.º 14
0
def validation():
    """Check if Wazuh configuration is OK.

    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(**_validation_default_result_kwargs)

    try:
        response = validate_ossec_conf()
        result.affected_items.append({'name': node_id, **response})
        result.total_affected_items += 1
    except WazuhError as e:
        result.add_failed_item(id_=node_id, error=e)

    return result
Exemplo n.º 15
0
def get_node_wrapper():
    """ Wrapper for get_node

    :return: AffectedItemsWazuhResult
    """
    result = AffectedItemsWazuhResult(
        all_msg='All selected information was returned',
        none_msg='No information was returned')
    try:
        result.affected_items.append(get_node())
    except WazuhError as e:
        result.add_failed_item(id_=node_id, error=e)
    result.total_affected_items = len(result.affected_items)

    return result
Exemplo n.º 16
0
def get_sca_list(agent_list=None,
                 q="",
                 offset=0,
                 limit=common.database_limit,
                 sort=None,
                 search=None,
                 select=None,
                 filters=None):
    """ Get a list of policies analyzed in the configuration assessment for a given agent

    :param agent_list: agent id to get policies from
    :param q: Defines query to filter in DB.
    :param offset: First item to return.
    :param limit: Maximum number of items to return.
    :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}.
    :param search: Looks for items with the specified string. Format: {"fields": ["field1","field2"]}
    :param select: Select fields to return. Format: {"fields":["field1","field2"]}.
    :param filters: Define field filters required by the user. Format: {"field1":"value1", "field2":["value2","value3"]}
    :return: AffectedItemsWazuhResult
    """
    result = AffectedItemsWazuhResult(
        all_msg='All selected sca information was returned',
        some_msg='Some sca information was not returned',
        none_msg='No sca information was returned')

    if len(agent_list) != 0:
        if agent_list[0] in get_agents_info():
            select = list(
                fields_translation_sca.keys()) if select is None else select

            db_query = WazuhDBQuerySCA(agent_id=agent_list[0],
                                       offset=offset,
                                       limit=limit,
                                       sort=sort,
                                       search=search,
                                       select=select,
                                       count=True,
                                       get_data=True,
                                       query=q,
                                       filters=filters)
            data = db_query.run()
            result.affected_items.extend(data['items'])
            result.total_affected_items = data['totalItems']
        else:
            result.add_failed_item(id_=agent_list[0],
                                   error=WazuhResourceNotFound(1701))

    return result
Exemplo n.º 17
0
def run_command(agent_list: list = None,
                command: str = '',
                arguments: list = None,
                custom: bool = False,
                alert: dict = None) -> AffectedItemsWazuhResult:
    """Run AR command in a specific agent.

    Parameters
    ----------
    agent_list : list
        Agents list that will run the AR command.
    command : str
        Command running in the agents. If this value starts with !, then it refers to a script name instead of a
        command name.
    custom : bool
        Whether the specified command is a custom command or not.
    arguments : list
        Command arguments.
    alert : dict
        Alert information depending on the AR executed.

    Returns
    -------
    AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(
        all_msg='AR command was sent to all agents',
        some_msg='AR command was not sent to some agents',
        none_msg='AR command was not sent to any agent')
    if agent_list:
        wq = WazuhQueue(common.ARQUEUE)
        system_agents = get_agents_info()
        for agent_id in agent_list:
            try:
                if agent_id not in system_agents:
                    raise WazuhResourceNotFound(1701)
                if agent_id == "000":
                    raise WazuhError(1703)
                active_response.send_ar_message(agent_id, wq, command,
                                                arguments, custom, alert)
                result.affected_items.append(agent_id)
                result.total_affected_items += 1
            except WazuhException as e:
                result.add_failed_item(id_=agent_id, error=e)
        result.affected_items.sort(key=int)
        wq.close()

    return result
Exemplo n.º 18
0
def get_agents_sync_group(agent_list=None):
    """Get agents configuration sync status.

    :param agent_list: List of agents ID's.
    :return AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(
        all_msg='Sync info was returned for all selected agents',
        some_msg='Sync info was not returned for some selected agents',
        none_msg='No sync info was returned',
    )

    system_agents = get_agents_info()
    for agent_id in agent_list:
        try:
            if agent_id == "000":
                raise WazuhError(1703)
            if agent_id not in system_agents:
                raise WazuhResourceNotFound(1701)
            else:
                # Check if agent exists and it is active
                agent_info = Agent(agent_id).get_basic_information()
                # Check if it has a multigroup
                if len(agent_info['group']) > 1:
                    multi_group = ','.join(agent_info['group'])
                    multi_group = hashlib.sha256(
                        multi_group.encode()).hexdigest()[:8]
                    group_merged_path = path.join(common.multi_groups_path,
                                                  multi_group, "merged.mg")
                else:
                    group_merged_path = path.join(common.shared_path,
                                                  agent_info['group'][0],
                                                  "merged.mg")
                result.affected_items.append({
                    'id':
                    agent_id,
                    'synced':
                    md5(group_merged_path) == agent_info['mergedSum']
                })
        except (IOError, KeyError):
            # The file couldn't be opened and therefore the group has not been synced
            result.affected_items.append({'id': agent_id, 'synced': False})
        except WazuhException as e:
            result.add_failed_item(id_=agent_id, error=e)

    result.total_affected_items = len(result.affected_items)

    return result
Exemplo n.º 19
0
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
Exemplo n.º 20
0
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
Exemplo n.º 21
0
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
Exemplo n.º 22
0
def update_ossec_conf(new_conf=None):
    """
    Replace wazuh configuration (ossec.conf) with the provided configuration.

    Parameters
    ----------
    new_conf: str
        The new configuration to be applied.
    """
    result = AffectedItemsWazuhResult(
        all_msg=f"Configuration was successfully updated"
        f"{' in specified node' if node_id != 'manager' else ''}",
        some_msg='Could not update configuration in some nodes',
        none_msg=f"Could not update configuration"
        f"{' in specified node' if node_id != 'manager' else ''}")
    backup_file = f'{common.ossec_conf}.backup'
    try:
        # Check a configuration has been provided
        if not new_conf:
            raise WazuhError(1125)

        # Check if the configuration is valid
        validate_wazuh_xml(new_conf, config_file=True)

        # Create a backup of the current configuration before attempting to replace it
        try:
            copyfile(common.ossec_conf, backup_file)
        except IOError:
            raise WazuhError(1019)

        # Write the new configuration and validate it
        write_ossec_conf(new_conf)
        is_valid = validate_ossec_conf()

        if not isinstance(is_valid, dict) or ('status' in is_valid
                                              and is_valid['status'] != 'OK'):
            raise WazuhError(1125)
        else:
            result.affected_items.append(node_id)
        exists(backup_file) and remove(backup_file)
    except WazuhError as e:
        result.add_failed_item(id_=node_id, error=e)
    finally:
        exists(backup_file) and safe_move(backup_file, common.ossec_conf)

    result.total_affected_items = len(result.affected_items)
    return result
Exemplo n.º 23
0
def set_user_role(user_id, role_ids, position=None):
    """Create a relationship between a user and a role.

    Parameters
    ----------
    user_id : list
        User ID
    role_ids : list of int
        List of role ids
    position : int
        Position where the new role will be inserted

    Returns
    -------
    Dict
        User-Roles information
    """
    if position is not None and position < 0:
        raise WazuhError(4018)

    username = get_username(user_id=user_id)
    result = AffectedItemsWazuhResult(
        none_msg=f'No link was created to user {username}',
        some_msg=f'Some roles were not linked to user {username}',
        all_msg=f'All roles were linked to user {username}')
    success = False
    with UserRolesManager() as urm:
        for role_id in role_ids:
            user_role = urm.add_role_to_user(user_id=int(user_id[0]),
                                             role_id=int(role_id),
                                             position=position)
            if user_role == SecurityError.ALREADY_EXIST:
                result.add_failed_item(id_=int(role_id),
                                       error=WazuhError(4017))
            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 position is not None:
                    position += 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
Exemplo n.º 24
0
def clear(agent_list=None):
    """Clear the syscheck database of the specified agents.

    Parameters
    ----------
    agent_list : str
        Agent ID.

    Returns
    -------
    result : AffectedItemsWazuhResult
        Confirmation/Error message.
    """
    result = AffectedItemsWazuhResult(
        all_msg='Syscheck database was cleared on returned agents',
        some_msg='Syscheck database was not cleared on some agents',
        none_msg="No syscheck database was cleared")
    wdb_conn = WazuhDBConnection()

    system_agents = get_agents_info()
    for agent in agent_list:
        if agent not in system_agents:
            result.add_failed_item(id_=agent,
                                   error=WazuhResourceNotFound(1701))
        else:
            try:
                wdb_conn.execute(
                    "agent {} sql delete from fim_entry".format(agent),
                    delete=True)
                # Update key fields which contains keys to value 000
                wdb_conn.execute(
                    "agent {} sql update metadata set value = '000' "
                    "where key like 'fim_db%'".format(agent),
                    update=True)
                wdb_conn.execute(
                    "agent {} sql update metadata set value = '000' "
                    "where key = 'syscheck-db-completed'".format(agent),
                    update=True)
                result.affected_items.append(agent)
            except WazuhError as e:
                result.add_failed_item(id_=agent, error=e)

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

    return result
Exemplo n.º 25
0
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
Exemplo n.º 26
0
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:

        system_groups= get_groups()
        # Add failed items
        for invalid_group in set(group_list) - system_groups:
            result.add_failed_item(id_=invalid_group, error=WazuhResourceNotFound(1710))

        rbac_filters = get_rbac_filters(system_resources=system_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
Exemplo n.º 27
0
def run(agent_list: Union[list, None] = None) -> AffectedItemsWazuhResult:
    """Run a rootcheck scan in the specified agents.

    Parameters
    ----------
    agent_list : Union[list, None]
         List of the agents IDs to run the scan for.

    Returns
    -------
    result : AffectedItemsWazuhResult
        JSON containing the affected agents.
    """
    result = AffectedItemsWazuhResult(all_msg='Rootcheck scan was restarted on returned agents',
                                      some_msg='Rootcheck scan was not restarted on some agents',
                                      none_msg='No rootcheck scan was restarted')

    system_agents = get_agents_info()
    rbac_filters = get_rbac_filters(system_resources=system_agents, permitted_resources=agent_list)
    agent_list = set(agent_list)
    not_found_agents = agent_list - system_agents

    # Add non existent agents to failed_items
    [result.add_failed_item(id_=agent, error=WazuhResourceNotFound(1701)) for agent in not_found_agents]

    # Add non eligible agents to failed_items
    with WazuhDBQueryAgents(limit=None, select=["id", "status"], query=f'status!=active', **rbac_filters) as db_query:
        non_eligible_agents = db_query.run()['items']

    [result.add_failed_item(
        id_=agent['id'],
        error=WazuhError(1707)) for agent in non_eligible_agents]

    wq = WazuhQueue(common.ARQUEUE)
    eligible_agents = agent_list - not_found_agents - {d['id'] for d in non_eligible_agents}
    for agent_id in eligible_agents:
        try:
            wq.send_msg_to_agent(WazuhQueue.HC_SK_RESTART, agent_id)
            result.affected_items.append(agent_id)
        except WazuhError as e:
            result.add_failed_item(id_=agent_id, error=e)
    wq.close()
    result.affected_items.sort(key=int)
    result.total_affected_items = len(result.affected_items)

    return result
Exemplo n.º 28
0
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
Exemplo n.º 29
0
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
Exemplo n.º 30
0
def get_api_config():
    """Returns current API configuration.

    Returns
    -------
    result : AffectedItemsWazuhResult
        Current API configuration of the manager.
    """
    result = AffectedItemsWazuhResult(**_get_config_default_result_kwargs)

    try:
        api_config = {'node_name': node_id, 'node_api_config': get_api_conf()}
        result.affected_items.append(api_config)
    except WazuhError as e:
        result.add_failed_item(id_=node_id, error=e)
    result.total_affected_items = len(result.affected_items)

    return result