diff --git a/deps/wazuh_testing/wazuh_testing/tools/__init__.py b/deps/wazuh_testing/wazuh_testing/tools/__init__.py
index 811fb23fe2..f160b5c63c 100644
--- a/deps/wazuh_testing/wazuh_testing/tools/__init__.py
+++ b/deps/wazuh_testing/wazuh_testing/tools/__init__.py
@@ -27,6 +27,9 @@
WAZUH_SOURCES = os.path.join('/', 'wazuh')
+ WAZUH_UNIX_USER = 'wazuh'
+ WAZUH_UNIX_GROUP = 'wazuh'
+
if sys.platform == 'darwin':
WAZUH_PATH = os.path.join("/", "Library", "Ossec")
PREFIX = os.path.join('/', 'private', 'var', 'root')
@@ -53,8 +56,8 @@
import grp
import pwd
- WAZUH_UID = pwd.getpwnam("wazuh").pw_uid
- WAZUH_GID = grp.getgrnam("wazuh").gr_gid
+ WAZUH_UID = pwd.getpwnam(WAZUH_UNIX_USER).pw_uid
+ WAZUH_GID = grp.getgrnam(WAZUH_UNIX_GROUP).gr_gid
except (ImportError, KeyError, ModuleNotFoundError):
pass
@@ -86,6 +89,9 @@ def get_service():
_data_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'data')
+LOCAL_RULES_PATH = os.path.join(WAZUH_PATH, 'etc', 'rules', 'local_rules.xml')
+LOCAL_DECODERS_PATH = os.path.join(WAZUH_PATH, 'etc', 'decoders', 'local_decoder.xml')
+
CLIENT_KEYS_PATH = os.path.join(WAZUH_PATH, 'etc', 'client.keys')
SERVER_KEY_PATH = os.path.join(WAZUH_PATH, 'etc', 'manager.key')
SERVER_CERT_PATH = os.path.join(WAZUH_PATH, 'etc', 'manager.cert')
@@ -108,6 +114,7 @@ def get_service():
AUTHD_SOCKET_PATH = os.path.join(QUEUE_SOCKETS_PATH, 'auth')
EXECD_SOCKET_PATH = os.path.join(QUEUE_SOCKETS_PATH, 'com')
LOGCOLLECTOR_SOCKET_PATH = os.path.join(QUEUE_SOCKETS_PATH, 'logcollector')
+LOGTEST_SOCKET_PATH = os.path.join(QUEUE_SOCKETS_PATH, 'logtest')
MONITORD_SOCKET_PATH = os.path.join(QUEUE_SOCKETS_PATH, 'monitor')
REMOTED_SOCKET_PATH = os.path.join(QUEUE_SOCKETS_PATH, 'request')
SYSCHECKD_SOCKET_PATH = os.path.join(QUEUE_SOCKETS_PATH, 'syscheck')
diff --git a/docs/tests/integration/test_logtest/test_log_process_options/test_rules_verbose.md b/docs/tests/integration/test_logtest/test_log_process_options/test_rules_verbose.md
new file mode 100644
index 0000000000..e3684ab436
--- /dev/null
+++ b/docs/tests/integration/test_logtest/test_log_process_options/test_rules_verbose.md
@@ -0,0 +1,33 @@
+# Test log process options - Rules verbose
+## Overview
+
+Check if `wazuh-logtest` works correctly in `verbose` mode for rules debugging
+
+## Objective
+
+- To confirm that `wazuh-logtest` does not do rule debugging when the rules_debug field is omitted
+- To confirm that `wazuh-logtest` does not do rule debugging when the rules_debug field is set to false
+- To confirm that `wazuh-logtest` does not do rule debugging when the rules_debug field is set to a bad type (string)
+- To confirm that `wazuh-logtest` does not do rule debugging when the rules_debug field is set to a bad type (number)
+- To confirm that `wazuh-logtest` does not do rule debugging when the rules_debug field is set to a bad type (object)
+- To confirm that `wazuh-logtest` does not do rule debugging when the rules_debug field is set to a bad type (array)
+- To confirm that `wazuh-logtest` does not do rule debugging when the options field is set to a bad type (boolean)
+- To confirm that `wazuh-logtest` does not do rule debugging when the options field is set to a bad type (array)
+- To confirm that `wazuh-logtest` does not do rule debugging when the options field is set to a bad type (number)
+- To confirm that `wazuh-logtest` does not do rule debugging when the options field is set to a bad type (string)
+- To confirm that `wazuh-logtest` does rule debugging when the rules_debug field is set to true
+
+## General info
+
+|Tier | Number of tests | Time spent |
+|:--:|:--:|:--:|
+| 0 | 11 | 10s |
+
+## Expected behavior
+
+- Pass if `wazuh-logtest` returns rule debugging information when parameters are correct
+- Pass if `wazuh-logtest` does not return rule debugging information when parameters are incorrect.
+
+## Code documentation
+
+::: tests.integration.test_logtest.test_options.test_log_process_options.test_rules_verbose
diff --git a/tests/integration/test_logtest/test_log_process_options/data/rules_verbose.xml b/tests/integration/test_logtest/test_log_process_options/data/rules_verbose.xml
new file mode 100644
index 0000000000..b42c8685c8
--- /dev/null
+++ b/tests/integration/test_logtest/test_log_process_options/data/rules_verbose.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ json
+ rules_verbose
+ Parent rules verbose
+
+
+
+ 880000
+ ^last_match$
+ test last_match
+
+
+
+ 880001
+ ^ok$
+ test_child test_child
+
+
+
diff --git a/tests/integration/test_logtest/test_log_process_options/data/rules_verbose.yaml b/tests/integration/test_logtest/test_log_process_options/data/rules_verbose.yaml
new file mode 100644
index 0000000000..3b66da65c5
--- /dev/null
+++ b/tests/integration/test_logtest/test_log_process_options/data/rules_verbose.yaml
@@ -0,0 +1,74 @@
+---
+-
+ name: 'rules_debug_omitted'
+ rule_file: 'rules_verbose.xml'
+ rule_id: '880002'
+ input: '{"version":1,"origin":{"name":"Integration Test","module":"api"},"command":"log_processing","parameters":{"event": "{\"it_logtest\" : \"rules_verbose\", \"test\": \"last_match\", \"test_child\" : \"ok\"}","log_format": "syslog","location": "master->/var/log/syslog"}}'
+-
+ name: 'rules_debug_true'
+ rule_file: 'rules_verbose.xml'
+ rule_id: '880001'
+ input: '{"version":1,"origin":{"name":"Integration Test","module":"api"},"command":"log_processing","parameters":{"event": "{\"it_logtest\" : \"rules_verbose\", \"test\": \"last_match\"}","log_format": "syslog","location": "master->/var/log/syslog","options":{"rules_debug":true}}}'
+ verbose_mode: True
+-
+ name: 'rules_debug_false'
+ rule_file: 'rules_verbose.xml'
+ rule_id: '880001'
+ input: '{"version":1,"origin":{"name":"Integration Test","module":"api"},"command":"log_processing","parameters":{"event": "{\"it_logtest\" : \"rules_verbose\", \"test\": \"last_match\"}","log_format": "syslog","location": "master->/var/log/syslog","options":{"rules_debug":false}}}'
+ verbose_mode: False
+-
+ name: 'rules_debug_bad_type_string'
+ rule_file: 'rules_verbose.xml'
+ rule_id: '880001'
+ input: '{"version":1,"origin":{"name":"Integration Test","module":"api"},"command":"log_processing","parameters":{"event": "{\"it_logtest\" : \"rules_verbose\", \"test\": \"last_match\"}","log_format": "syslog","location": "master->/var/log/syslog","options":{"rules_debug":"true"}}}'
+ verbose_mode: False
+ warning_message: "WARNING: \\(\\d+\\): 'rules_debug' field must be a boolean. The parameter will be ignored"
+-
+ name: 'rules_debug_bad_type_number'
+ rule_file: 'rules_verbose.xml'
+ rule_id: '880001'
+ input: '{"version":1,"origin":{"name":"Integration Test","module":"api"},"command":"log_processing","parameters":{"event": "{\"it_logtest\" : \"rules_verbose\", \"test\": \"last_match\"}","log_format": "syslog","location": "master->/var/log/syslog","options":{"rules_debug":123}}}'
+ verbose_mode: False
+ warning_message: "WARNING: \\(\\d+\\): 'rules_debug' field must be a boolean. The parameter will be ignored"
+-
+ name: 'rules_debug_bad_type_object'
+ rule_file: 'rules_verbose.xml'
+ rule_id: '880001'
+ input: '{"version":1,"origin":{"name":"Integration Test","module":"api"},"command":"log_processing","parameters":{"event": "{\"it_logtest\" : \"rules_verbose\", \"test\": \"last_match\"}","log_format": "syslog","location": "master->/var/log/syslog","options":{"rules_debug":{"test":"true"}}}}'
+ verbose_mode: False
+ warning_message: "WARNING: \\(\\d+\\): 'rules_debug' field must be a boolean. The parameter will be ignored"
+-
+ name: 'rules_debug_bad_type_array'
+ rule_file: 'rules_verbose.xml'
+ rule_id: '880001'
+ input: '{"version":1,"origin":{"name":"Integration Test","module":"api"},"command":"log_processing","parameters":{"event": "{\"it_logtest\" : \"rules_verbose\", \"test\": \"last_match\"}","log_format": "syslog","location": "master->/var/log/syslog","options":{"rules_debug":["true", "false"]}}}'
+ verbose_mode: False
+ warning_message: "WARNING: \\(\\d+\\): 'rules_debug' field must be a boolean. The parameter will be ignored"
+-
+ name: 'options_bad_type_boolean'
+ rule_file: 'rules_verbose.xml'
+ rule_id: '880001'
+ input: '{"version":1,"origin":{"name":"Integration Test","module":"api"},"command":"log_processing","parameters":{"event": "{\"it_logtest\" : \"rules_verbose\", \"test\": \"last_match\"}","log_format": "syslog","location": "master->/var/log/syslog","options":true}}'
+ verbose_mode: False
+ warning_message: "WARNING: \\(\\d+\\): 'options' field must be a JSON object. The parameter will be ignored"
+-
+ name: 'options_bad_type_array'
+ rule_file: 'rules_verbose.xml'
+ rule_id: '880001'
+ input: '{"version":1,"origin":{"name":"Integration Test","module":"api"},"command":"log_processing","parameters":{"event": "{\"it_logtest\" : \"rules_verbose\", \"test\": \"last_match\"}","log_format": "syslog","location": "master->/var/log/syslog","options":["true", "false"]}}'
+ verbose_mode: False
+ warning_message: "WARNING: \\(\\d+\\): 'options' field must be a JSON object. The parameter will be ignored"
+-
+ name: 'options_bad_type_number'
+ rule_file: 'rules_verbose.xml'
+ rule_id: '880001'
+ input: '{"version":1,"origin":{"name":"Integration Test","module":"api"},"command":"log_processing","parameters":{"event": "{\"it_logtest\" : \"rules_verbose\", \"test\": \"last_match\"}","log_format": "syslog","location": "master->/var/log/syslog","options":123456}}'
+ verbose_mode: False
+ warning_message: "WARNING: \\(\\d+\\): 'options' field must be a JSON object. The parameter will be ignored"
+-
+ name: 'options_bad_type_string'
+ rule_file: 'rules_verbose.xml'
+ rule_id: '880001'
+ input: '{"version":1,"origin":{"name":"Integration Test","module":"api"},"command":"log_processing","parameters":{"event": "{\"it_logtest\" : \"rules_verbose\", \"test\": \"last_match\"}","log_format": "syslog","location": "master->/var/log/syslog","options":"true"}}'
+ verbose_mode: False
+ warning_message: "WARNING: \\(\\d+\\): 'options' field must be a JSON object. The parameter will be ignored"
diff --git a/tests/integration/test_logtest/test_log_process_options/test_rules_verbose.py b/tests/integration/test_logtest/test_log_process_options/test_rules_verbose.py
new file mode 100644
index 0000000000..619f397a0b
--- /dev/null
+++ b/tests/integration/test_logtest/test_log_process_options/test_rules_verbose.py
@@ -0,0 +1,123 @@
+# Copyright (C) 2015-2021, Wazuh Inc.
+# Created by Wazuh, Inc. .
+# This program is free software; you can redistribute it and/or modify it under the terms of GPLv2
+
+import json
+import os
+import shutil
+import re
+
+import pytest
+import yaml
+from wazuh_testing.tools import (WAZUH_PATH, LOGTEST_SOCKET_PATH,
+ WAZUH_UNIX_USER, LOG_FILE_PATH,
+ LOCAL_RULES_PATH, WAZUH_UNIX_GROUP)
+from wazuh_testing.logtest import callback_logtest_started
+from wazuh_testing.tools.services import control_service
+from wazuh_testing.tools.monitoring import FileMonitor
+from wazuh_testing.tools.file import truncate_file
+
+
+# Marks
+pytestmark = [pytest.mark.linux, pytest.mark.tier(level=0), pytest.mark.server]
+
+# Configurations
+test_data_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/')
+messages_path = os.path.join(test_data_path, 'rules_verbose.yaml')
+logtest_startup_timeout = 30
+
+with open(messages_path) as f:
+ test_cases = yaml.safe_load(f)
+
+# Variables
+receiver_sockets_params = [(LOGTEST_SOCKET_PATH, 'AF_UNIX', 'TCP')]
+receiver_sockets = None
+
+local_rules_debug_messages = ['Trying rule: 880000 - Parent rules verbose', '*Rule 880000 matched',
+ '*Trying child rules', 'Trying rule: 880001 - test last_match', '*Rule 880001 matched',
+ '*Trying child rules', 'Trying rule: 880002 - test_child test_child']
+
+
+# Fixtures
+@pytest.fixture(scope='function')
+def configure_rules_list(get_configuration, request):
+ """Configure a custom rules for testing.
+ Restart Wazuh is not needed for applying the configuration is optional.
+ """
+
+ # save current rules
+ shutil.copy(LOCAL_RULES_PATH, LOCAL_RULES_PATH + '.cpy')
+
+ file_test = get_configuration['rule_file']
+ # copy test rules
+ shutil.copy(test_data_path + file_test, LOCAL_RULES_PATH)
+ shutil.chown(LOCAL_RULES_PATH, WAZUH_UNIX_USER, WAZUH_UNIX_GROUP)
+
+ yield
+
+ # restore previous configuration
+ shutil.move(LOCAL_RULES_PATH + '.cpy', LOCAL_RULES_PATH)
+ shutil.chown(LOCAL_RULES_PATH, WAZUH_UNIX_USER, WAZUH_UNIX_GROUP)
+
+
+@pytest.fixture(scope='module', params=test_cases, ids=[test_case['name'] for test_case in test_cases])
+def get_configuration(request):
+ """Get configurations from the module."""
+ return request.param
+
+
+@pytest.fixture(scope='module')
+def wait_for_logtest_startup(request):
+ """Wait until logtest has begun."""
+ log_monitor = FileMonitor(LOG_FILE_PATH)
+ log_monitor.start(timeout=logtest_startup_timeout, callback=callback_logtest_started)
+
+
+@pytest.fixture(scope='module')
+def restart_required_logtest_daemons():
+ """Wazuh logtests daemons handler."""
+ required_logtest_daemons = ['wazuh-analysisd']
+
+ truncate_file(LOG_FILE_PATH)
+
+ for daemon in required_logtest_daemons:
+ control_service('restart', daemon=daemon)
+
+ yield
+
+ for daemon in required_logtest_daemons:
+ control_service('stop', daemon=daemon)
+
+
+# Tests
+def test_rules_verbose(get_configuration, restart_required_logtest_daemons,
+ configure_rules_list, wait_for_logtest_startup,
+ connect_to_sockets_function):
+ """Check the correct behaviour of logtest `rules_debug` field.
+
+ This test writes different inputs at the logtest socket and checks the responses to be the expected.
+ """
+
+ # send the logtest request
+ receiver_sockets[0].send(get_configuration['input'], size=True)
+
+ # receive logtest reply and parse it
+ response = receiver_sockets[0].receive(size=True).rstrip(b'\x00').decode()
+ result = json.loads(response)
+
+ assert result['error'] == 0
+ assert result['data']['output']['rule']['id'] == get_configuration['rule_id']
+
+ if 'verbose_mode' in get_configuration and get_configuration['verbose_mode']:
+ if 'rules_debug' in result['data']:
+ assert result['data']['rules_debug'][-len(local_rules_debug_messages):] == local_rules_debug_messages
+ else:
+ assert False, 'The rules_debug field was not found in the response data'
+
+ else:
+ assert 'rules_debug' not in result['data']
+
+ if 'warning_message' in get_configuration:
+ r = re.compile(get_configuration['warning_message'])
+ match_list = list(filter(r.match, result['data']['messages']))
+ assert match_list, 'The warning message was not found in the response data'