def test_checkers(key, subkey, arch, key_attrs, value_attrs, tags_to_apply, triggers_modification,
                  get_configuration, configure_environment, restart_syscheckd, wait_for_fim_start):
    """
    Test the functionality of `check_all` option is activated/desactivated alone and together with other
    `check_*` options.

    Example:
        <windows_registry check_all="yes">HKEY_SOME_KEY</windows_registry>.
    Parameters
    ----------
    key: str
        Root key (HKEY_* constants).
    subkey: str
        Path of the key.
    arch: int
        Architecture of the key.
    key_attrs: set
        Attributes for the key events.
    value_attrs: set
        Attributes for the value events.
    tags_to_apply: set
        Configuration that will be applied for every case.
    triggers_modification: boolean
        True if the given attributes trigger modification events.
    """

    check_apply_test(tags_to_apply, get_configuration['tags'])

    # Test registry keys.
    registry_key_cud(key, subkey, wazuh_log_monitor, arch=arch, min_timeout=global_parameters.default_timeout,
                     options=key_attrs, triggers_event_modified=triggers_modification, time_travel=True)

    # Test registry values.
    registry_value_cud(key, subkey, wazuh_log_monitor, min_timeout=global_parameters.default_timeout,
                       options=value_attrs, triggers_event_modified=triggers_modification, time_travel=True)
def test_ignore_over_restrict_values(key, subkey, value_name, arch,
                                     get_configuration, configure_environment,
                                     restart_syscheckd, wait_for_fim_start):
    """
    Check registry values are ignored according to configuration.

    Parameters
    ----------
    key : str
        Root key (HKEY_*)
    subkey : str
        path of the registry where the test will be executed.
    arch : str
        Architecture of the registry.
    """
    check_apply_test({"ambiguous_ignore_restrict_values"},
                     get_configuration['tags'])

    # Test registry keys.
    registry_value_cud(key,
                       subkey,
                       wazuh_log_monitor,
                       arch=arch,
                       value_list=[value_name],
                       min_timeout=global_parameters.default_timeout,
                       time_travel=True,
                       triggers_event=False)
Example #3
0
def test_ambiguous_complex_checks(key, subkey, key_checkers, get_configuration,
                                  configure_environment, restart_syscheckd,
                                  wait_for_fim_start):
    """
    Check if the events of every configured key has the proper check attributes.

    Parameters
    ----------
    key: str
        Key of the registry (HKEY_* constants).
    sub_key: str
        Path of the configured key.
    key_checkers: set
        Set of checks that are expected.
    """
    check_apply_test({"complex_checks"}, get_configuration['tags'])
    # Test registry keys.
    registry_key_cud(key,
                     subkey,
                     wazuh_log_monitor,
                     min_timeout=global_parameters.default_timeout,
                     options=key_checkers,
                     time_travel=True)

    # Test registry values.
    registry_value_cud(key,
                       subkey,
                       wazuh_log_monitor,
                       min_timeout=global_parameters.default_timeout,
                       options=key_checkers,
                       time_travel=True)
Example #4
0
def test_tags(key, subkey, arch, get_configuration, configure_environment,
              restart_syscheckd, wait_for_fim_start):
    """
    Check the tags functionality by applying some tags an ensuring the events raised for the monitored directory has
    the expected tags.

    Parameters
    ----------
    folder : str
        Directory where the file is being created.
    name : str
        Name of the file to be created.
    content : str, bytes
        Content to fill the new file.
    """
    defined_tags = get_configuration['metadata']['fim_tags']

    def tag_validator(event):
        assert defined_tags == event['data'][
            'tags'], f'defined_tags are not equal'

    registry_value_cud(
        key,
        subkey,
        wazuh_log_monitor,
        arch=arch,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
        min_timeout=global_parameters.default_timeout,
        triggers_event=True,
        validators_after_cud=[tag_validator])
def test_no_diff_regex(key, subkey, arch, value_name, truncated, tags_to_apply,
                       get_configuration, configure_environment,
                       restart_syscheckd, wait_for_fim_start):
    """
    Check the only files detected are those matching the restrict regex.

    Parameters
    ----------
    key : str
        Root key (HKEY_*)
    subkey : str
        path of the registry.
    arch : str
        Architecture of the registry.
    value_name : str
        Name of the value that will be created
    truncated : bool
        True if an event must be generated, False otherwise.
    tags_to_apply : set
        Run test if match with a configuration identifier, skip otherwise.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    values = {value_name: "some content"}

    def report_changes_validator(event):
        """Validate content_changes attribute exists in the event"""
        for value in values:
            folder_str = "{} {}".format(
                "[x32]" if arch == KEY_WOW64_32KEY else "[x64]",
                sha1(os.path.join(key, subkey).encode()).hexdigest())

            diff_file = os.path.join(WAZUH_PATH, 'queue', 'diff', 'registry',
                                     folder_str,
                                     sha1(value.encode()).hexdigest())

            assert os.path.exists(diff_file), '{diff_file} does not exist'
            assert event['data'].get(
                'content_changes') is not None, 'content_changes is empty'

    def no_diff_validator(event):
        """Validate content_changes value is truncated if the file is set to no_diff"""
        if truncated:
            assert '<Diff truncated because nodiff option>' in event['data'].get('content_changes'), \
                'content_changes is not truncated'
        else:
            assert '<Diff truncated because nodiff option>' not in event['data'].get('content_changes'), \
                'content_changes is truncated'

    registry_value_cud(
        key,
        subkey,
        wazuh_log_monitor,
        arch=arch,
        value_list=values,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
        min_timeout=global_parameters.default_timeout,
        triggers_event=True,
        validators_after_update=[report_changes_validator, no_diff_validator])
    # Avoid overlapping of events
    sleep(0.5)
Example #6
0
def test_disk_quota_values(key, subkey, arch, value_name, tags_to_apply, size,
                           get_configuration, configure_environment,
                           restart_syscheckd, wait_for_fim_start):
    """
    Check that no events are sent when the disk_quota exceeded

    Parameters
    ----------
    key : str
        Root key (HKEY_*)
    subkey : str
        path of the registry.
    arch : str
        Architecture of the registry.
    value_name : str
        Name of the value that will be created
    tags_to_apply : set
        Run test if match with a configuration identifier, skip otherwise.
    size : int
        Size of the content to write in value
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    value_content = generate_string(size, '0')
    values = {value_name: value_content}

    _, diff_file = calculate_registry_diff_paths(key, subkey, arch, value_name)

    def report_changes_validator_no_diff(event):
        """Validate content_changes attribute exists in the event"""
        assert event['data'].get(
            'content_changes') is None, 'content_changes isn\'t empty'

    def report_changes_validator_diff(event):
        """Validate content_changes attribute exists in the event"""
        assert os.path.exists(diff_file), '{diff_file} does not exist'
        assert event['data'].get(
            'content_changes') is not None, 'content_changes is empty'

    if size > size_limit_configured:
        callback_test = report_changes_validator_no_diff
    else:
        callback_test = report_changes_validator_diff

    create_registry(registry_parser[key], subkey, arch)

    registry_value_cud(
        key,
        subkey,
        wazuh_log_monitor,
        arch=arch,
        value_list=values,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
        min_timeout=global_parameters.default_timeout,
        triggers_event=True,
        validators_after_update=[callback_test])

    delete_registry(registry_parser[key], subkey, arch)
    check_time_travel(True, monitor=wazuh_log_monitor)
Example #7
0
def test_ambiguous_report_tags(key, subkey, tag, get_configuration,
                               configure_environment, restart_syscheckd,
                               wait_for_fim_start):
    """
    Check if syscheck detects the event property 'tags' for each configured entry.

    This test validates both situations, making sure that if tags='no', there won't be a
    tags event property.

    Parameters
    ----------
    key: str
        Key of the registry (HKEY_* constants).
    sub_key: str
        Path of the configured key.
    tag: str
        Tag that is configured for each entry. If None, the entry isn't configured with a tag.
    """
    check_apply_test({'complex_tags'}, get_configuration['tags'])

    def no_tag_validator(event):
        """Validate tags event property does not exist in the event."""
        assert 'tags' not in event['data'].keys(
        ), "'Tags' attribute found in event"

    def tag_validator(event):
        """Validate tags event property exists in the event."""
        assert tag == event['data']['tags'], 'Defined_tags are not equal'

    validator_after_create = [no_tag_validator]
    validator_after_update = [no_tag_validator]
    validator_after_delete = [no_tag_validator]

    if tag is not None:
        validator_after_create = [tag_validator]
        validator_after_update = [tag_validator]
        validator_after_delete = [tag_validator]

    # Test registry values.
    registry_key_cud(key,
                     subkey,
                     wazuh_log_monitor,
                     min_timeout=global_parameters.default_timeout,
                     time_travel=True,
                     validators_after_create=validator_after_create,
                     validators_after_update=validator_after_update,
                     validators_after_delete=validator_after_delete)

    # Test registry values.
    registry_value_cud(key,
                       subkey,
                       wazuh_log_monitor,
                       min_timeout=global_parameters.default_timeout,
                       time_travel=True,
                       validators_after_create=validator_after_create,
                       validators_after_update=validator_after_update,
                       validators_after_delete=validator_after_delete)
Example #8
0
def test_ambiguous_restrict(key, sub_keys, is_key, name, get_configuration,
                            configure_environment, restart_syscheckd,
                            wait_for_fim_start):
    """
    Check restrict configuration events.

    Check if syscheck detects changes (add, modify, delete) of key/events depending on its restrict configuration.

    Parameters
    ----------
    key: str
        Key of the registry (HKEY_* constants).
    sub_keys: tuple
        Tuple where the first element is the path of a key that won't raise alerts due to the restrict and the
        second element is a key that will raise alerts.
    is_key: boolean
        Variable to distinguish if the restrict is for keys or for values.
    name: str
        String with the name of the value/key that will be created.
    """
    check_apply_test({"ambiguous_restrict"}, get_configuration['tags'])

    if is_key:
        registry_key_cud(key,
                         sub_keys[0],
                         wazuh_log_monitor,
                         key_list=[name],
                         arch=KEY_WOW64_64KEY,
                         triggers_event=False,
                         time_travel=True,
                         min_timeout=global_parameters.default_timeout)
        registry_key_cud(key,
                         sub_keys[1],
                         wazuh_log_monitor,
                         key_list=[name],
                         arch=KEY_WOW64_64KEY,
                         triggers_event=True,
                         time_travel=True,
                         min_timeout=global_parameters.default_timeout)
    else:
        registry_value_cud(key,
                           sub_keys[0],
                           wazuh_log_monitor,
                           value_list=[name],
                           arch=KEY_WOW64_64KEY,
                           triggers_event=False,
                           time_travel=True,
                           min_timeout=global_parameters.default_timeout)
        registry_value_cud(key,
                           sub_keys[1],
                           wazuh_log_monitor,
                           value_list=[name],
                           triggers_event=True,
                           time_travel=True,
                           min_timeout=global_parameters.default_timeout)
Example #9
0
def test_ambiguous_checks(key, subkey, key_checkers, subkey_checkers,
                          get_configuration, configure_environment,
                          restart_syscheckd, wait_for_fim_start):
    """
    Check if syscheck detects the event property 'tags' for each event.

    This test validates both situations, making sure that if tags='no', there won't be a
    tags event property.

    Parameters
    ----------
    key: str
        Key of the registry (HKEY_* constants).
    sub_keys: tuple
        Tuple where ther first element is the configured key and the second is the configured subkey.
    arch: int
        Architecture of the key.
    """
    check_apply_test({"ambiguous_checks"}, get_configuration['tags'])
    # Test registry keys.
    registry_key_cud(
        key,
        subkey[0],
        wazuh_log_monitor,
        min_timeout=global_parameters.default_timeout,
        options=key_checkers,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled')

    # Test registry values.
    registry_value_cud(
        key,
        subkey[0],
        wazuh_log_monitor,
        min_timeout=global_parameters.default_timeout,
        options=key_checkers,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled')

    # Test registry keys.
    registry_key_cud(
        key,
        subkey[1],
        wazuh_log_monitor,
        min_timeout=global_parameters.default_timeout,
        options=subkey_checkers,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled')

    # Test registry values.
    registry_value_cud(
        key,
        subkey[1],
        wazuh_log_monitor,
        min_timeout=global_parameters.default_timeout,
        options=subkey_checkers,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled')
def test_long_registry_path(get_configuration, configure_environment, restart_syscheckd, wait_for_fim_start):
    """
    Check if long key names generates events
    """

    max_value_name = "value_test"
    for i in range(16372):
        max_value_name += "a"

    registry_value_cud(key, sub_key_1, wazuh_log_monitor, arch=arch,
                       time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
                       min_timeout=global_parameters.default_timeout,
                       triggers_event=True, value_list=[max_value_name])
Example #11
0
def test_registry_changes(key, subkey, arch, value_type, get_configuration, configure_environment, restart_syscheckd,
                          wait_for_fim_start):
    """
    Check if events appear for subkeys/values of a monitored key
    """
    registry_key_cud(key, subkey, wazuh_log_monitor, arch=arch,
                     time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
                     min_timeout=global_parameters.default_timeout,
                     triggers_event=True)

    registry_value_cud(key, subkey, wazuh_log_monitor, arch=arch,
                       time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
                       min_timeout=global_parameters.default_timeout,
                       triggers_event=True, value_type=value_type)
Example #12
0
def test_ambiguous_recursion(key, subkey, arch, get_configuration,
                             configure_environment, restart_syscheckd,
                             wait_for_fim_start):
    """
    Check if syscheck detects the event property 'tags' for each event.

    This test validates both situations, making sure that if tags='no', there won't be a
    tags event property.

    Parameters
    ----------
    key: str
        Key of the registry (HKEY_* constants).
    sub_keys: str
        Path of the subkey that will be used for the test (must have a higher recursion level than the configured key).
        Example:
        <windows_registry recursion_level="2">HKLM//some_key</windows_registry>
        subkey = HKLM//some_key//1//2//3

    arch: int
        Architecture of the key.
    """
    expected_recursion_key = os.path.join(subkey, key_name)
    check_apply_test({"ambiguous_recursion"}, get_configuration['tags'])

    registry_key_cud(key,
                     subkey,
                     wazuh_log_monitor,
                     arch=arch,
                     time_travel=True,
                     triggers_event=False,
                     min_timeout=global_parameters.default_timeout)

    registry_key_cud(key,
                     expected_recursion_key,
                     wazuh_log_monitor,
                     arch=arch,
                     time_travel=True,
                     triggers_event=True,
                     min_timeout=global_parameters.default_timeout)

    registry_value_cud(key,
                       expected_recursion_key,
                       wazuh_log_monitor,
                       arch=arch,
                       time_travel=True,
                       triggers_event=True,
                       min_timeout=global_parameters.default_timeout)
Example #13
0
def test_duplicate_entries_rc(key, subkey, arch, value_list, tags_to_apply,
                              report_changes, get_configuration,
                              configure_environment, restart_syscheckd,
                              wait_for_fim_start):
    """
    Check registry entries are overwritten when report changes is activated/deactivated.

    Parameters
    ----------
    key: str
        Root key (HKEY_* constants).
    subkey: str
        path of the registry where the test will be executed.
    arch: str
        Architecture of the registry.
    value_list: list
        List with the name of the values that will be used for cud.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    def report_changes_validator(event):
        """Validate content_changes attribute exists in the event"""
        if not report_changes:
            return

        for value in value_list:
            folder_str = "{} {}".format(
                "[x32]" if arch == KEY_WOW64_32KEY else "[x64]",
                sha1(os.path.join(key, subkey).encode()).hexdigest())
            diff_file = os.path.join(WAZUH_PATH, 'queue', 'diff', 'registry',
                                     folder_str,
                                     sha1(value.encode()).hexdigest())

            assert os.path.exists(diff_file), '{diff_file} does not exist'
            assert event['data'].get(
                'content_changes') is not None, 'content_changes is empty'

    registry_value_cud(key,
                       subkey,
                       wazuh_log_monitor,
                       arch=arch,
                       value_list=value_list,
                       time_travel=True,
                       min_timeout=global_parameters.default_timeout,
                       triggers_event=True,
                       validators_after_update=[report_changes_validator])
Example #14
0
def test_duplicate_entries(key, subkey, arch, key_list, value_list, checkers,
                           tags_to_apply, get_configuration,
                           configure_environment, restart_syscheckd,
                           wait_for_fim_start):
    """
    Check that duplicate antries are overwritten by the last entry.

    Parameters
    ----------
    key: str
        Root key (HKEY_*)
    subkey: str
        path of the registry where the test will be executed.
    arch: str
        Architecture of the registry.
    key_list: list
        List with the name of the keys that will be used for cud. If None, registry_key_cud won't be executed.
    value_list: list
        List with the name of the values that will be used for cud. If None, registry_value_cud won't be executed.
    checkers: set
        Set with the checkers that are expected in the events.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    # Test registry keys.
    if key_list is not None:
        registry_key_cud(key,
                         subkey,
                         wazuh_log_monitor,
                         arch=arch,
                         key_list=key_list,
                         options=checkers,
                         min_timeout=global_parameters.default_timeout,
                         time_travel=True,
                         triggers_event=True)

    if value_list is not None:
        registry_value_cud(key,
                           subkey,
                           wazuh_log_monitor,
                           arch=arch,
                           value_list=value_list,
                           options=checkers,
                           min_timeout=global_parameters.default_timeout,
                           time_travel=True,
                           triggers_event=True)
Example #15
0
def test_ambiguous_report_changes(key, subkey, value_list, report,
                                  get_configuration, configure_environment,
                                  restart_syscheckd, wait_for_fim_start):
    """
    Check if report changes works properly for every configured entry

    Parameters
    ----------
    key: str
        Key of the registry (HKEY_* constants).
    sub_key: str
        Path of the configured key.
    value_list: list
        List with the name of the values that will be used in the cud operation.
    report: boolean
        True if the key is configured with report changes.
    """
    check_apply_test({'complex_report_changes'}, get_configuration['tags'])

    validator_after_update = None

    def report_changes_validator(event):
        """Validate content_changes attribute exists in the event"""
        for value in value_list:
            folder_str = "{} {}".format(
                "[x64]",
                sha1(os.path.join(key, subkey).encode()).hexdigest())
            diff_file = os.path.join(WAZUH_PATH, 'queue', 'diff', 'registry',
                                     folder_str,
                                     sha1(value.encode()).hexdigest())

            assert os.path.exists(diff_file), '{diff_file} does not exist'
            assert event['data'].get(
                'content_changes') is not None, 'content_changes is empty'

    if report:
        validator_after_update = [report_changes_validator]
    # Test registry values.
    registry_value_cud(key,
                       subkey,
                       wazuh_log_monitor,
                       min_timeout=global_parameters.default_timeout,
                       value_list=value_list,
                       time_travel=True,
                       validators_after_update=validator_after_update)
def test_new_key(get_configuration, configure_environment, restart_syscheckd,
                 wait_for_fim_start):
    """
    Check that a new monitored key generates events after the next scheduled scan.
    """

    create_registry(registry_parser[key], sub_key_1, arch)

    check_time_travel(True, monitor=wazuh_log_monitor)

    registry_value_cud(
        key,
        sub_key_1,
        wazuh_log_monitor,
        arch=arch,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
        min_timeout=global_parameters.default_timeout,
        triggers_event=True)
def test_report_changes_more_changes(key, subkey, arch, value_name,
                                     tags_to_apply, get_configuration,
                                     configure_environment, restart_syscheckd,
                                     wait_for_fim_start):
    """
    Checks that "More changes..." diff string is MAX_STR_MORE_CHANGES

    Parameters
    ----------
    key : str
        Root key (HKEY_*)
    subkey : str
        path of the registry.
    arch : str
        Architecture of the registry.
    value_name : str
        Name of the value that will be created
    tags_to_apply : set
        Run test if match with a configuration identifier, skip otherwise.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    values = {value_name: generate_string(MAX_STR_MORE_CHANGES, '0')}
    error_str = 'Expected {} in event'.format(MORE_CHANGES_STR)

    def report_changes_validator(event):
        """Validate content_changes attribute exists in the event"""
        for value in values:
            _, diff_file = calculate_registry_diff_paths(
                key, subkey, arch, value)
            assert os.path.exists(diff_file), '{diff_file} does not exist'
            assert event['data'].get('content_changes')[
                -len(MORE_CHANGES_STR):] == MORE_CHANGES_STR, error_str

    registry_value_cud(
        key,
        subkey,
        wazuh_log_monitor,
        arch=arch,
        value_list=values,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
        min_timeout=global_parameters.default_timeout,
        triggers_event=True,
        validators_after_update=[report_changes_validator])
Example #18
0
def test_report_changes(key, subkey, arch, value_name, tags_to_apply,
                        get_configuration, configure_environment,
                        restart_syscheckd, wait_for_fim_start):
    """
    Checks that events of keys configured using report changes are correct.
    It also checks that the diff file is created for each value.

    Parameters
    ----------
    key : str
        Root key (HKEY_*)
    subkey : str
        path of the registry.
    arch : str
        Architecture of the registry.
    value_name : str
        Name of the value that will be created
    tags_to_apply : set
        Run test if match with a configuration identifier, skip otherwise.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    values = {value_name: "some content"}

    def report_changes_validator(event):
        """Validate content_changes attribute exists in the event"""
        for value in values:
            _, diff_file = calculate_registry_diff_paths(
                key, subkey, arch, value)

            assert os.path.exists(diff_file), '{diff_file} does not exist'
            assert event['data'].get(
                'content_changes') is not None, 'content_changes is empty'

    registry_value_cud(
        key,
        subkey,
        wazuh_log_monitor,
        arch=arch,
        value_list=values,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
        min_timeout=global_parameters.default_timeout,
        triggers_event=True,
        validators_after_update=[report_changes_validator])
Example #19
0
def test_report_when_deleted_key(key, subkey, arch, value_name, enabled,
                                 tags_to_apply, get_configuration,
                                 configure_environment, restart_syscheckd,
                                 wait_for_fim_start):
    """
    Check that the diff files are generated when there is a modification in a value and these files are deleted when
    the value is deleted.

    It also checks that the diff folder of the key is deleted when the key is deleted.

    Parameters
    ----------
    key : str
        Root key (HKEY_*)
    subkey : str
        path of the registry.
    arch : str
        Architecture of the registry.
    value_name : str
        Name of the value that will be created
    enabled: boolean
        True if report_changes is enabled
    tags_to_apply : set
        Run test if match with a configuration identifier, skip otherwise.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    vals_after_update = None
    vals_after_delete = None

    folder_path, diff_file = calculate_registry_diff_paths(
        key, subkey, arch, value_name)

    def report_changes_diff_file_validator(unused_param):
        """
        Validator that checks if the files are created.
        """
        assert os.path.exists(diff_file), f'{diff_file} does not exist'

    def report_changes_removed_diff_file_validator(unused_param):
        """
        Validator that checks if the files are removed when the values are removed.
        """
        assert not os.path.exists(diff_file), f'{diff_file} does exist'

    if enabled:
        vals_after_update = [report_changes_diff_file_validator]
        vals_after_delete = [report_changes_removed_diff_file_validator]
    else:
        vals_after_update = [report_changes_removed_diff_file_validator]
        vals_after_delete = [report_changes_removed_diff_file_validator]

    registry_value_cud(key,
                       subkey,
                       wazuh_log_monitor,
                       arch=arch,
                       value_list={value_name: "some content"},
                       time_travel=True,
                       min_timeout=global_parameters.default_timeout,
                       validators_after_update=vals_after_update,
                       validators_after_delete=vals_after_delete)

    delete_registry(registry_parser[key], subkey, arch)

    assert not os.path.exists(folder_path), f'{folder_path} exists'
def test_recursion_level(root_key, registry, arch, edge_limit, ignored_levels,
                         get_configuration, configure_environment,
                         restart_syscheckd, wait_for_fim_start):
    """
    Check that events are generated in the first and last `edge_limit` directory levels in the hierarchy
    It also checks that no events are generated for levels higher than the configured recursion level.

    Example:
        recursion_level = 10
        edge_limit = 2
        ignored_levels = 1
        key = "HKEY_LOCAL_MACHINE"
        registry = "SOFTWARE\\test_key"
        subkey = "subkey"

        With those parameters this function will create values and expect to detect 'added', 'modified' and 'deleted'
        events for the following registry only, as they are the first and last 2 subkeys within recursion
        level 10:

        HKEY_LOCAL_MACHINE\\SOFTWARE\\test_key\\1
        HKEY_LOCAL_MACHINE\\SOFTWARE\\test_key\\1\\2
        HKEY_LOCAL_MACHINE\\SOFTWARE\\test_key\\1\\2\\3\\4\\5\\6\\7\\8\\9
        HKEY_LOCAL_MACHINE\\SOFTWARE\\test_key\\1\\2\\3\\4\\5\\6\\7\\8\\9\\10

        As ignored_levels value is 1, this function will also create files on the following subkeys and ensure that
        no events are raised as they are outside the recursion level specified:

        HKEY_LOCAL_MACHINE\\SOFTWARE\\test_key\\1\\2\\3\\4\\5\\6\\7\\8\\9\\10\\11

    Parameters
    ----------
    root_key : str
        Registry key **STRING** (HKEY_* constants)
    registry : str
        The registry key being monitored by syscheck (indicated in the .conf file without the HKEY_* constant).
    arch : int
        Architecture of the registry key
    edge_limit : int
        Number of subkeys where the test will monitor events.
    ignored_levels : int
        Number of subkeys exceeding the specified recursion_level to verify events are not raised.
    """
    recursion_level = int(rl_dict[registry])
    path = registry

    # Check events in recursion level = 0
    registry_value_cud(root_key,
                       path,
                       wazuh_log_monitor,
                       arch=arch,
                       time_travel=True,
                       min_timeout=global_parameters.default_timeout)

    path_list = list()
    # For recursion lower levels, execute registry_value_cud in every level.
    if recursion_level < edge_limit:
        for level in range(recursion_level):
            path = os.path.join(path, str(level + 1))
            path_list.append(path)
    else:
        for level in range(recursion_level):
            path = os.path.join(path, str(level + 1))
            if level < edge_limit or level > recursion_level - edge_limit:
                path_list.append(path)

    # Create values only in the first/last `edge_limit` levels of recursion
    for registry_path in path_list:
        registry_value_cud(root_key,
                           registry_path,
                           wazuh_log_monitor,
                           arch=arch,
                           time_travel=True,
                           min_timeout=global_parameters.default_timeout,
                           triggers_event=True)

    # Check that no alerts are generated when levels that exceed the specified recursion_level
    for n in range(recursion_level, recursion_level + ignored_levels):
        path = os.path.join(path, str(n + 1))
        registry_value_cud(root_key,
                           path,
                           wazuh_log_monitor,
                           arch=arch,
                           time_travel=True,
                           min_timeout=global_parameters.default_timeout,
                           triggers_event=False)