Example #1
0
def get_rule_file(filename=None, raw=False):
    """Read content of specified file.

    Parameters
    ----------
    filename : str, optional
        Name of the rule file. Default `None`
    raw : bool, optional
        Whether to return the content in raw format (str->XML) or JSON. Default `False` (JSON format)

    Returns
    -------
    str or dict
        Content of the file. AffectedItemsWazuhResult format if `raw=False`.
    """
    result = AffectedItemsWazuhResult(none_msg='No rule was returned',
                                      all_msg='Selected rule was returned')
    files = get_rules_files(filename=filename).affected_items

    if len(files) > 0:
        rules_path = files[0]['relative_dirname']
        try:
            full_path = join(common.wazuh_path, rules_path, filename)
            with open(full_path) as f:
                content = f.read()
            if raw:
                result = content
            else:
                # Missing root tag in rule file
                result.affected_items.append(xmltodict.parse(f'<root>{content}</root>')['root'])
                result.total_affected_items = 1
        except ExpatError as e:
            result.add_failed_item(id_=filename,
                                   error=WazuhError(1413, extra_message=f"{join('WAZUH_HOME', rules_path, filename)}:"     
                                                                        f" {str(e)}"))
        except OSError:
            result.add_failed_item(id_=filename,
                                   error=WazuhError(1414, extra_message=join('WAZUH_HOME', rules_path, filename)))

    else:
        result.add_failed_item(id_=filename, error=WazuhError(1415))

    return result
Example #2
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
Example #3
0
def add_role(name=None):
    """Creates a role in the system

    :param name: The new role name
    :return Role information
    """
    result = AffectedItemsWazuhResult(none_msg='Role was not created',
                                      all_msg='Role was successfully created')
    with RolesManager() as rm:
        status = rm.add_role(name=name)
        if status == SecurityError.ALREADY_EXIST:
            result.add_failed_item(id_=name, error=WazuhError(4005))
        elif status == SecurityError.INVALID:
            result.add_failed_item(id_=name, error=WazuhError(4003))
        else:
            result.affected_items.append(rm.get_role(name=name))
            result.total_affected_items += 1

    return result
Example #4
0
def upload_group_file(group_id, file_data, file_name='agent.conf'):
    """
    Updates a group file
    :param group_id: Group to update
    :param file_data: Upload data
    :param file_name: File name to update
    :return: Confirmation message in string
    """
    # Check if the group exists
    if not os_path.exists(os_path.join(common.shared_path, group_id)):
        raise WazuhResourceNotFound(1710, group_id)

    if file_name == 'agent.conf':
        if len(file_data) == 0:
            raise WazuhError(1112)

        return upload_group_configuration(group_id, file_data)
    else:
        raise WazuhError(1111)
Example #5
0
def get_decoder_file(filename: str, raw: bool = False) -> Union[str, AffectedItemsWazuhResult]:
    """Read content of specified file.

    Parameters
    ----------
    filename : str
        Name of the decoder file.
    raw : bool
        Whether to return the content in raw format (str->XML) or JSON.

    Returns
    -------
    str or dict
        Content of the file. AffectedItemsWazuhResult format if `raw=False`.
    """
    result = AffectedItemsWazuhResult(none_msg='No decoder was returned',
                                      all_msg='Selected decoder was returned')
    decoders = get_decoders_files(filename=filename).affected_items

    if len(decoders) > 0:
        decoder_path = decoders[0]['relative_dirname']
        try:
            full_path = join(common.wazuh_path, decoder_path, filename)
            with open(full_path) as f:
                file_content = f.read()
            if raw:
                result = file_content
            else:
                # Missing root tag in decoder file
                result.affected_items.append(xmltodict.parse(f'<root>{file_content}</root>')['root'])
                result.total_affected_items = 1
        except ExpatError as e:
            result.add_failed_item(id_=filename,
                                   error=WazuhError(1501, extra_message=f"{join('WAZUH_HOME', decoder_path, filename)}:"     
                                                                        f" {str(e)}"))
        except OSError:
            result.add_failed_item(id_=filename,
                                   error=WazuhError(1502, extra_message=join('WAZUH_HOME', decoder_path, filename)))

    else:
        result.add_failed_item(id_=filename, error=WazuhError(1503))

    return result
Example #6
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 WazuhResourceNotFound(1710)
            if group_id == 'default':
                raise WazuhError(1712)
            agent_list = list(
                map(
                    operator.itemgetter('id'),
                    WazuhDBQueryMultigroups(group_id=group_id,
                                            limit=None).run()['items']))
            try:
                affected_agents_result = remove_agents_from_group(
                    agent_list=agent_list, group_list=[group_id])
                if affected_agents_result.total_failed_items != 0:
                    raise WazuhError(4015)
            except WazuhError:
                raise WazuhError(4015)
            Agent.delete_single_group(group_id)
            result.affected_items.append(group_id)
            affected_agents.update(affected_agents_result.affected_items)
        except WazuhException as e:
            result.add_failed_item(id_=group_id, error=e)

    result['affected_agents'] = sorted(affected_agents, key=int)
    result.affected_items.sort()
    result.total_affected_items = len(result.affected_items)

    return result
Example #7
0
def totals(date):
    """
    Returns the totals file.
    :param date: date object with the date value of the stats
    :return: Array of dictionaries. Each dictionary represents an hour.
    """

    stat_filename = ""
    try:
        stat_filename = os.path.join(
            common.stats_path, "totals", str(date.year),
            MONTHS[date.month - 1], f"ossec-totals-{date.strftime('%d')}.log")
        stats = open(stat_filename, 'r')
    except IOError:
        raise WazuhError(1308, extra_message=stat_filename)

    response = []
    alerts = []

    for line in stats:
        data = line.split('-')

        if len(data) == 4:
            sigid = int(data[1])
            level = int(data[2])
            times = int(data[3])

            alert = {'sigid': sigid, 'level': level, 'times': times}
            alerts.append(alert)
        else:
            data = line.split('--')

            if len(data) != 5:
                if len(data) in (0, 1):
                    continue
                else:
                    raise WazuhInternalError(1309)

            hour = int(data[0])
            total_alerts = int(data[1])
            events = int(data[2])
            syscheck = int(data[3])
            firewall = int(data[4])

            response.append({
                'hour': hour,
                'alerts': alerts,
                'totalAlerts': total_alerts,
                'events': events,
                'syscheck': syscheck,
                'firewall': firewall
            })
            alerts = []

    return WazuhResult({'data': response})
Example #8
0
def totals_(date=datetime.utcnow()):
    """Compute statistical information for the current or specified date.

    Parameters
    ----------
    date: date
        Date object with the date value of the stats, current date by default.

    Returns
    -------
    array
        array of dictionaries. Each dictionary represents an hour.

    Raises
    ------
    WazuhError
        Raised on `IOError`.
    """
    try:
        stat_filename = os.path.join(
            common.stats_path, "totals", str(date.year),
            MONTHS[date.month - 1], f"ossec-totals-{date.strftime('%d')}.log")
        with open(stat_filename, mode='r') as statsf:
            stats = statsf.readlines()
    except IOError:
        raise WazuhError(1308, extra_message=stat_filename)

    alerts = []
    affected = []
    for line in stats:
        data = line.split('-')
        if len(data) == 4:
            alerts.append({
                'sigid': int(data[1]),
                'level': int(data[2]),
                'times': int(data[3])
            })
        else:
            data = line.split('--')
            if len(data) != 5:
                if len(data) in (0, 1):
                    continue
                else:
                    raise WazuhInternalError(1309)
            affected.append({
                'hour': int(data[0]),
                'alerts': alerts,
                'totalAlerts': int(data[1]),
                'events': int(data[2]),
                'syscheck': int(data[3]),
                'firewall': int(data[4])
            })
            alerts = []

    return affected
Example #9
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_=role_id[0], error=WazuhError(4002))
            elif role_rule == SecurityError.RULE_NOT_EXIST:
                result.add_failed_item(id_=rule_id, error=WazuhError(4022))
            elif role_rule == SecurityError.ADMIN_RESOURCES:
                result.add_failed_item(id_=role_id[0], error=WazuhError(4008))
            else:
                success = True
                result.total_affected_items += 1
        if success:
            with RolesManager() as rm:
                result.affected_items.append(
                    rm.get_role_id(role_id=role_id[0]))
                # Invalidate users with auth_context
                with AuthenticationManager() as am:
                    user_list = list()
                    for user in am.get_users():
                        if am.user_allow_run_as(username=user['username']):
                            user_list.append(user['user_id'])
                invalid_users_tokens(users=user_list)
            result.affected_items.sort(key=str)

    return result
Example #10
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
    """

    role = get_role(role_id[0])

    if not role:
        raise WazuhResourceNotFound(4002)

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

    return result
Example #11
0
def set_role_rule(role_id, rule_ids, run_as=False):
    """Create a relationship between a role and one or more rules.

    Parameters
    ----------
    role_id : int
        The new role_id
    rule_ids : list of int
        List of rule ids
    run_as : dict
        Login with an authorization context or not

    Returns
    -------

    """
    result = AffectedItemsWazuhResult(none_msg=f'No link was created to role {role_id[0]}',
                                      some_msg=f'Some security rules were not linked to role {role_id[0]}',
                                      all_msg=f'All security rules were linked to role {role_id[0]}')
    success = False
    with RolesRulesManager() as rrm:
        for rule_id in rule_ids:
            role_rule = rrm.add_rule_to_role(role_id=int(role_id[0]), rule_id=int(rule_id))
            if role_rule == SecurityError.ALREADY_EXIST:
                result.add_failed_item(id_=int(rule_id), error=WazuhError(4023))
            elif role_rule == SecurityError.ROLE_NOT_EXIST:
                result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4002))
            elif role_rule == SecurityError.RULE_NOT_EXIST:
                result.add_failed_item(id_=int(rule_id), error=WazuhError(4022))
            elif role_rule == SecurityError.ADMIN_RESOURCES:
                result.add_failed_item(id_=int(role_id[0]), error=WazuhError(4008))
            else:
                success = True
                result.total_affected_items += 1
        if success:
            with RolesManager() as rm:
                result.affected_items.append(rm.get_role_id(role_id=role_id[0]))
                # Invalidate users with auth_context
                invalid_run_as_tokens()
            result.affected_items.sort(key=str)

    return result
Example #12
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 WazuhError(1710)
    system_agents = get_agents_info()
    for agent_id in agent_list:
        try:
            if agent_id not in system_agents:
                raise WazuhError(1701)
            if agent_id == "000":
                raise WazuhError(1703)
            Agent.add_group_to_agent(group_id,
                                     agent_id,
                                     force=True,
                                     replace=replace,
                                     replace_list=replace_list)
            result.affected_items.append(agent_id)
        except WazuhException as e:
            result.add_failed_item(id_=agent_id, error=e)

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

    return result
Example #13
0
def get_file_conf(filename, group_id=None, type_conf=None, return_format=None):
    """
    Returns the configuration file as dictionary.

    :return: configuration file as dictionary.
    """
    if not os_path.exists(os_path.join(common.shared_path, group_id)):
        raise WazuhResourceNotFound(1710, group_id)

    file_path = os_path.join(common.shared_path, group_id if not filename == 'ar.conf' else '', filename)

    if not os_path.exists(file_path):
        raise WazuhError(1006, file_path)

    types = {
        'conf': get_agent_conf,
        'rootkit_files': _rootkit_files2json,
        'rootkit_trojans': _rootkit_trojans2json,
        'rcl': _rcl2json
    }

    if type_conf:
        if type_conf in types:
            if type_conf == 'conf':
                data = types[type_conf](group_id, limit=None, filename=filename, return_format=return_format)
            else:
                data = types[type_conf](file_path)
        else:
            raise WazuhError(1104, "{0}. Valid types: {1}".format(type_conf, types.keys()))
    else:
        if filename == "agent.conf":
            data = get_agent_conf(group_id, limit=None, filename=filename, return_format=return_format)
        elif filename == "rootkit_files.txt":
            data = _rootkit_files2json(file_path)
        elif filename == "rootkit_trojans.txt":
            data = _rootkit_trojans2json(file_path)
        elif filename == "ar.conf":
            data = _ar_conf2json(file_path)
        else:
            data = _rcl2json(file_path)

    return data
Example #14
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='Obtained information about all selected groups',
        some_msg='Some groups information was not obtained',
        none_msg='No group information was obtained')

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

    group_query = WazuhDBQueryGroup(filters={'name': group_list},
                                    offset=offset,
                                    limit=limit,
                                    sort=sort,
                                    search=search)
    query_data = group_query.run()

    for group in query_data['items']:
        full_entry = path.join(common.shared_path, group['name'])

        # merged.mg and agent.conf sum
        merged_sum = get_hash(path.join(full_entry, "merged.mg"),
                              hash_algorithm)
        conf_sum = get_hash(path.join(full_entry, "agent.conf"),
                            hash_algorithm)

        if merged_sum:
            group['mergedSum'] = merged_sum

        if conf_sum:
            group['configSum'] = conf_sum
        affected_groups.append(group)

    result.affected_items = affected_groups
    result.total_affected_items = query_data['totalItems']

    return result
Example #15
0
def get_file(filename=None):
    """Reads content of specified file

    :param filename: File name to read content from
    :return: File contents
    """
    files = get_rules_files(filename=filename).affected_items

    if len(files) > 0:
        rules_path = files[0]['relative_dirname']
        try:
            full_path = os.path.join(common.ossec_path, rules_path, filename)
            with open(full_path) as f:
                return f.read()
        except OSError:
            raise WazuhError(1414,
                             extra_message=os.path.join(
                                 'WAZUH_HOME', rules_path, filename))
    else:
        raise WazuhError(1415)
Example #16
0
    def send(self, msg_bytes):
        if not isinstance(msg_bytes, bytes):
            raise WazuhError(1104, extra_message="Type must be bytes")

        try:
            sent = self.s.send(pack("<I", len(msg_bytes)) + msg_bytes)
            if sent == 0:
                raise WazuhInternalError(1014, extra_message="Number of sent bytes is 0")
            return sent
        except Exception as e:
            raise WazuhInternalError(1014, extra_message=str(e))
Example #17
0
def add_policy(name=None, policy=None):
    """Creates a policy in the system

    :param name: The new policy name
    :param policy: The new policy
    :return Policy information
    """
    result = AffectedItemsWazuhResult(none_msg='Policy was not created',
                                      all_msg='Policy was successfully created')
    with PoliciesManager() as pm:
        status = pm.add_policy(name=name, policy=policy)
        if status == SecurityError.ALREADY_EXIST:
            result.add_failed_item(id_=name, error=WazuhError(4009))
        elif status == SecurityError.INVALID:
            result.add_failed_item(id_=name, error=WazuhError(4006))
        else:
            result.affected_items.append(pm.get_policy(name=name))
            result.total_affected_items += 1

    return result
Example #18
0
def get_ossec_conf(section=None, field=None, conf_file=common.ossec_conf):
    """
    Returns ossec.conf (manager) as dictionary.

    :param section: Filters by section (i.e. rules).
    :param field: Filters by field in section (i.e. included).
    :param conf_file: Path of the configuration file to read.
    :return: ossec.conf (manager) as dictionary.
    """
    try:
        # Read XML
        xml_data = load_wazuh_xml(conf_file)

        # Parse XML to JSON
        data = _ossecconf2json(xml_data)
    except Exception as e:
        raise WazuhError(1101, extra_message=str(e))

    if section:
        try:
            data = {section: data[section]}
        except KeyError as e:
            if section not in conf_sections.keys():
                raise WazuhError(1102, extra_message=e.args[0])
            else:
                raise WazuhError(1106, extra_message=e.args[0])

    if section and field:
        try:
            if isinstance(data[section], list):
                data = {
                    section: [{
                        field: item[field]
                    } for item in data[section]]
                }
            else:
                data = {section: {field: data[section][field]}}
        except KeyError:
            raise WazuhError(1103)

    return data
Example #19
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 removed from shown groups',
        some_msg='Specified agent could not be removed from some groups',
        none_msg='Specified agent could not be removed from any group')

    # Check if agent exists and it is not 000
    if agent_id == '000':
        raise WazuhError(1703)
    if agent_id not in get_agents_info():
        raise WazuhError(1701)

    # We move default group to last position in case it is contained in group_list. When an agent is removed from all
    # groups it is reverted to 'default'. We try default last to avoid removing it and then adding again.
    try:
        group_list.append(group_list.pop(group_list.index('default')))
    except ValueError:
        pass

    system_groups = get_groups()
    for group_id in group_list:
        try:
            if group_id not in system_groups:
                raise WazuhError(1710)
            Agent.unset_single_group_agent(agent_id=agent_id,
                                           group_id=group_id,
                                           force=True)
            result.affected_items.append(group_id)
        except WazuhException as e:
            result.add_failed_item(id_=group_id, error=e)
    result.total_affected_items = len(result.affected_items)
    result.affected_items.sort()

    return result
Example #20
0
    def unset_single_group_agent(agent_id, group_id, force=False):
        """Unset the agent group. If agent has multigroups, it will preserve all previous groups except the last one.

        :param agent_id: Agent ID.
        :param group_id: Group ID.
        :param force: Do not check if agent or group exists
        :return: Confirmation message.
        """
        if not force:
            # Check if agent exists, it is not 000 and the group exists
            Agent(agent_id).get_basic_information()

            if agent_id == "000":
                raise WazuhError(1703)

            if not Agent.group_exists(group_id):
                raise WazuhResourceNotFound(1710)

        # Get agent's group
        group_name = Agent.get_agents_group_file(agent_id)
        group_list = group_name.split(',')
        # Check agent belongs to group group_id
        if group_id not in group_list:
            raise WazuhError(1734)
        elif group_id == 'default' and len(group_list) == 1:
            raise WazuhError(1745)
        # Remove group from group_list
        group_list.remove(group_id)
        set_default = False
        if len(group_list) > 1:
            multigroup_name = ','.join(group_list)
        elif not group_list:
            set_default = True
            multigroup_name = 'default'
        else:
            multigroup_name = group_list[0]
        # Update group file
        Agent.set_agent_group_file(agent_id, multigroup_name)

        return f"Agent '{agent_id}' removed from '{group_id}'." + (
            " Agent reassigned to group default." if set_default else "")
Example #21
0
def get_list_from_file(path):
    """Get CDB list from file

    :param path: Relative path of list file to get
    :return: CDB list
    """
    file_path = join(common.ossec_path, path)
    output = list()

    try:
        with open(file_path) as f:
            for line in f.read().splitlines():
                if 'TEMPLATE' not in line:
                    # Check if key and value are not  surrounded by double quotes
                    if '"' not in line:
                        key, value = line.split(':')

                    # Check if key and/or value are surrounded by double quotes
                    else:
                        key, value = split_key_value_with_quotes(
                            line, file_path)

                    output.append({'key': key, 'value': value})

    except OSError as e:
        if e.errno == 2:
            raise WazuhError(1802)
        elif e.errno == 13:
            raise WazuhError(1803)
        elif e.errno == 21:
            raise WazuhError(1804,
                             extra_message="{0} {1}".format(
                                 join('WAZUH_HOME', file_path),
                                 "is a directory"))
        else:
            raise e
    except ValueError:
        raise WazuhError(1800,
                         extra_message={'path': join('WAZUH_HOME', file_path)})

    return output
Example #22
0
    def get_key(self):
        """Gets agent key.

        :return: Agent key.
        """
        self.load_info_from_db()
        if self.id != "000":
            self.key = self.compute_key()
        else:
            raise WazuhError(1703)

        return self.key
Example #23
0
def create_message(command, custom, arguments):
    """Create the message that will be sent

    :param command: Command running in the agent. If this value starts by !, then it refers to a script name instead of
    a command name
    :param custom: Whether the specified command is a custom command or not
    :param arguments: Command arguments
    :return: WazuhResult.
    """
    if not command:
        raise WazuhError(1650)

    commands = get_commands()
    if not custom and command not in commands:
        raise WazuhError(1652)

    msg_queue = "!{}".format(command) if custom else command
    msg_queue += " " + " ".join(shell_escape(str(x))
                                for x in arguments) if arguments else " - -"

    return msg_queue
Example #24
0
def get_agent_conf_multigroup(multigroup_id=None,
                              offset=0,
                              limit=common.database_limit,
                              filename=None):
    """
    Returns agent.conf as dictionary.

    :return: agent.conf as dictionary.
    """
    # Check if a multigroup_id is provided and it exists
    if multigroup_id and not os_path.exists(
            os_path.join(common.multi_groups_path,
                         multigroup_id)) or not multigroup_id:
        raise WazuhResourceNotFound(
            1710,
            extra_message=multigroup_id
            if multigroup_id else "No multigroup provided")

    agent_conf_name = filename if filename else 'agent.conf'
    agent_conf = os_path.join(common.multi_groups_path, multigroup_id,
                              agent_conf_name)

    if not os_path.exists(agent_conf):
        raise WazuhError(1006,
                         extra_message=os_path.join("WAZUH_PATH", "var",
                                                    "multigroups", agent_conf))

    try:
        # Read XML
        xml_data = load_wazuh_xml(agent_conf)

        # Parse XML to JSON
        data = _agentconf2json(xml_data)
    except Exception:
        raise WazuhError(1101)

    return {
        'totalItems': len(data),
        'items': cut_array(data, offset=offset, limit=limit)
    }
Example #25
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
Example #26
0
def remove_users(user_ids):
    """Remove a specified list of users

    Parameters
    ----------
    user_ids : list
        List of IDs

    Returns
    -------
    Status message
    """
    result = AffectedItemsWazuhResult(
        none_msg='No user was deleted',
        some_msg='Some users were not deleted',
        all_msg='Users were successfully deleted')
    with AuthenticationManager() as auth:
        for user_id in user_ids:
            user_id = int(user_id)
            current_user = auth.get_user(common.current_user.get())
            if not isinstance(current_user, bool) and user_id == int(
                    current_user['id']) and user_id > max_id_reserved:
                result.add_failed_item(id_=user_id, error=WazuhError(5008))
                continue
            user = auth.get_user_id(user_id)
            query = auth.delete_user(user_id)
            if not query:
                result.add_failed_item(id_=user_id, error=WazuhError(5001))
            elif query == SecurityError.ADMIN_RESOURCES:
                result.add_failed_item(id_=user_id, error=WazuhError(5004))
            elif query == SecurityError.RELATIONSHIP_ERROR:
                result.add_failed_item(id_=user_id, error=WazuhError(4025))
            elif user:
                with TokenManager() as tm:
                    tm.add_user_roles_rules(users={user_id})
                result.affected_items.append(user)
                result.total_affected_items += 1

        result.affected_items.sort(key=str)
    return result
Example #27
0
File: rule.py Project: zWaR/wazuh
def get_requirement(requirement=None,
                    offset=0,
                    limit=common.database_limit,
                    sort_by=None,
                    sort_ascending=True,
                    search_text=None,
                    complementary_search=False,
                    search_in_fields=None):
    """Get the requirements used in the rules

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

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

        return result

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

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

    return result
Example #28
0
def get_agent_conf(group_id=None,
                   offset=0,
                   limit=common.database_limit,
                   filename='agent.conf',
                   return_format=None):
    """
    Returns agent.conf as dictionary.

    :return: agent.conf as dictionary.
    """
    if not os_path.exists(os_path.join(common.shared_path, group_id)):
        raise WazuhResourceNotFound(1710, group_id)
    agent_conf = os_path.join(common.shared_path,
                              group_id if group_id is not None else '',
                              filename)

    if not os_path.exists(agent_conf):
        raise WazuhError(1006, agent_conf)

    try:
        # Read RAW file
        if filename == 'agent.conf' and return_format and 'xml' == return_format.lower(
        ):
            with open(agent_conf, 'r') as xml_data:
                data = xml_data.read()
                return data
        # Parse XML to JSON
        else:
            # Read XML
            xml_data = load_wazuh_xml(agent_conf)

            data = _agentconf2json(xml_data)
    except Exception as e:
        raise WazuhError(1101, str(e))

    return {
        'total_affected_items': len(data),
        'affected_items': cut_array(data, offset=offset, limit=limit)
    }
Example #29
0
def create_message(command: str = '',
                   custom: bool = False,
                   arguments: list = None) -> str:
    """Create the message that will be sent.

    Parameters
    ----------
    command : str
        Command running in the agent. If this value starts with !, then it refers to a script name instead of a command
        name.
    custom : bool
        Whether the specified command is a custom command or not.
    arguments : list
        Command arguments.

    Raises
    ------
    WazuhError(1650)
        If the command is not specified.
    WazuhError(1652)
        If the command is not custom and the command is not one of the available commands.

    Returns
    -------
    str
        Message that will be sent to the socket.
    """
    if not command:
        raise WazuhError(1650)

    commands = get_commands()
    if not custom and command not in commands:
        raise WazuhError(1652)

    msg_queue = "!{}".format(command) if custom else command
    msg_queue += " " + " ".join(shell_escape(str(x))
                                for x in arguments) if arguments else " - -"

    return msg_queue
Example #30
0
def create_user(username: str = None,
                password: str = None,
                allow_run_as: bool = False):
    """Create a new user

    Parameters
    ----------
    username : str
        Name for the new user
    password : str
        Password for the new user
    allow_run_as : bool
        Enable authorization context login method for the new user

    Returns
    -------
    result : AffectedItemsWazuhResult
        Status message
    """
    if len(password) > 64 or len(password) < 8:
        raise WazuhError(5009)
    elif not _user_password.match(password):
        raise WazuhError(5007)

    result = AffectedItemsWazuhResult(none_msg='User could not be created',
                                      all_msg='User was successfully created')
    with AuthenticationManager() as auth:
        if auth.add_user(username, password, allow_run_as=allow_run_as):
            operation = auth.get_user(username)
            if operation:
                result.affected_items.append(operation)
                result.total_affected_items = 1
            else:
                result.add_failed_item(id_=username, error=WazuhError(5000))
        else:
            result.add_failed_item(id_=username, error=WazuhError(5000))

    return result