summaryrefslogtreecommitdiff
path: root/security/wazuh-manager/files
diff options
context:
space:
mode:
Diffstat (limited to 'security/wazuh-manager/files')
-rw-r--r--security/wazuh-manager/files/patch-etc_ossec-server.conf47
-rw-r--r--security/wazuh-manager/files/patch-src-data_provider-src_sysInfoFreeBSD.cpp198
-rw-r--r--security/wazuh-manager/files/patch-src-shared_modules-utils_stringHelper.h26
-rw-r--r--security/wazuh-manager/files/patch-src_Makefile54
-rw-r--r--security/wazuh-manager/files/patch-src_analysisd_analysisd.c79
-rw-r--r--security/wazuh-manager/files/patch-src_external_cpython_Makefile.pre.in8
-rw-r--r--security/wazuh-manager/files/patch-src_headers_pthreads_op.h40
-rw-r--r--security/wazuh-manager/files/patch-src_headers_shared.h10
-rw-r--r--security/wazuh-manager/files/patch-src_remoted_manager.c16
-rw-r--r--security/wazuh-manager/files/patch-src_shared__modules_router_CMakeLists.txt10
-rw-r--r--security/wazuh-manager/files/patch-src_shared__modules_utils_socketWrapper.hpp10
-rw-r--r--security/wazuh-manager/files/pkg-message.in34
-rw-r--r--security/wazuh-manager/files/pthreads_portable.c91
-rw-r--r--security/wazuh-manager/files/pthreads_portable.h50
14 files changed, 556 insertions, 117 deletions
diff --git a/security/wazuh-manager/files/patch-etc_ossec-server.conf b/security/wazuh-manager/files/patch-etc_ossec-server.conf
index e80a18d10064..2000faef3d49 100644
--- a/security/wazuh-manager/files/patch-etc_ossec-server.conf
+++ b/security/wazuh-manager/files/patch-etc_ossec-server.conf
@@ -1,6 +1,33 @@
---- etc/ossec-server.conf 2024-05-10 18:10:43.842257000 -0500
-+++ etc/ossec-server.conf 2024-05-10 18:15:26.471699000 -0500
-@@ -28,7 +28,8 @@
+--- etc/ossec-server.conf 2025-09-23 06:59:40.000000000 -0700
++++ etc/ossec-server.conf 2025-10-16 17:18:34.635446000 -0700
+@@ -20,6 +20,26 @@
+ <agents_disconnection_alert_time>0</agents_disconnection_alert_time>
+ </global>
+
++ <vulnerability-detection>
++ <enabled>no</enabled>
++ <index-status>yes</index-status>
++ <feed-update-interval>60m</feed-update-interval>
++ </vulnerability-detection>
++
++ <indexer>
++ <enabled>no</enabled>
++ <hosts>
++ <host>https://127.0.0.1:9200</host>
++ </hosts>
++ <ssl>
++ <certificate_authorities>
++ <ca>/usr/local/etc/logstash/certs/root-ca.pem</ca>
++ </certificate_authorities>
++ <certificate>/usr/local/etc/logstash/certs/server1.pem</certificate>
++ <key>/usr/local/etc/logstash/certs/server1-key.pem</key>
++ </ssl>
++ </indexer>
++
+ <alerts>
+ <log_alert_level>3</log_alert_level>
+ <email_alert_level>12</email_alert_level>
+@@ -28,7 +48,8 @@
<remote>
<connection>secure</connection>
<port>1514</port>
@@ -10,7 +37,15 @@
</remote>
<!-- Policy monitoring -->
-@@ -200,7 +201,7 @@
+@@ -43,7 +64,6 @@
+
+ <system_audit>/var/ossec/etc/shared/system_audit_rcl.txt</system_audit>
+ <system_audit>/var/ossec/etc/shared/system_audit_ssh.txt</system_audit>
+- <system_audit>/var/ossec/etc/shared/cis_debian_linux_rcl.txt</system_audit>
+
+ <skip_nfs>yes</skip_nfs>
+ </rootcheck>
+@@ -200,7 +220,7 @@
<localfile>
<log_format>syslog</log_format>
@@ -19,7 +54,7 @@
</localfile>
<localfile>
-@@ -211,7 +212,7 @@
+@@ -211,7 +231,7 @@
<localfile>
<log_format>full_command</log_format>
@@ -28,7 +63,7 @@
<frequency>360</frequency>
</localfile>
-@@ -233,4 +234,32 @@
+@@ -236,4 +256,32 @@
<rule_dir>etc/rules</rule_dir>
</ruleset>
diff --git a/security/wazuh-manager/files/patch-src-data_provider-src_sysInfoFreeBSD.cpp b/security/wazuh-manager/files/patch-src-data_provider-src_sysInfoFreeBSD.cpp
index 86f1fdf985af..929fef4ec8c1 100644
--- a/security/wazuh-manager/files/patch-src-data_provider-src_sysInfoFreeBSD.cpp
+++ b/security/wazuh-manager/files/patch-src-data_provider-src_sysInfoFreeBSD.cpp
@@ -1,6 +1,6 @@
---- src/data_provider/src/sysInfoFreeBSD.cpp 2025-01-15 06:26:54.000000000 -0800
-+++ src/data_provider/src/sysInfoFreeBSD.cpp 2025-02-17 14:38:11.834720000 -0800
-@@ -11,6 +11,7 @@
+--- src/data_provider/src/sysInfoFreeBSD.cpp 2025-09-23 06:59:40.000000000 -0700
++++ src/data_provider/src/sysInfoFreeBSD.cpp 2025-10-16 15:42:56.638994000 -0700
+@@ -11,20 +11,23 @@
#include "sysInfo.hpp"
#include "cmdHelper.h"
#include "stringHelper.h"
@@ -8,7 +8,9 @@
#include "osinfo/sysOsParsers.h"
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
-@@ -19,12 +20,13 @@
+ #include <sys/utsname.h>
+ #include "sharedDefs.h"
++#include <regex>
static void getMemory(nlohmann::json& info)
{
@@ -25,7 +27,7 @@
if (ret)
{
-@@ -52,11 +54,23 @@
+@@ -52,11 +55,23 @@
};
}
@@ -52,7 +54,7 @@
if (ret)
{
-@@ -64,11 +78,11 @@
+@@ -64,11 +79,11 @@
{
ret,
std::system_category(),
@@ -66,7 +68,7 @@
info["ram_free"] = ramFree;
info["ram_usage"] = 100 - (100 * ramFree / ramTotal);
}
-@@ -184,8 +198,12 @@
+@@ -184,8 +199,12 @@
nlohmann::json SysInfo::getProcessesInfo() const
{
@@ -81,7 +83,7 @@
}
nlohmann::json SysInfo::getOsInfo() const
-@@ -196,11 +214,12 @@
+@@ -196,11 +215,12 @@
if (!spParser->parseUname(Utils::exec("uname -r"), ret))
{
@@ -95,93 +97,148 @@
if (uname(&uts) >= 0)
{
ret["sysname"] = uts.sysname;
-@@ -215,18 +234,145 @@
+@@ -215,18 +235,200 @@
nlohmann::json SysInfo::getPorts() const
{
- // Currently not supported for this OS.
- return nlohmann::json {};
-+ const auto query{Utils::exec(R"(sockstat -46qs)")};
-+
-+ /* USER COMMAND PID FD PROTO LOCAL_ADDRESS FOREIGN_ADDRESS PATH_STATE CONN_STATE */
-+
+ nlohmann::json ports {};
++
++ /* USER COMMAND PID FD PROTO LOCAL_ADDRESS FOREIGN_ADDRESS PATH_STATE CONN_STATE */
++
++#if __FreeBSD_version > 1500045
++ const auto query{exec(R"(sockstat -46qs --libxo json)")};
+
+ if (!query.empty())
+ {
-+ const auto lines{Utils::split(Utils::trimToOneSpace(query), '\n')};
++ nlohmann::json portsjson;
++ portsjson = nlohmann::json::parse(query);
++ auto &portsResult = portsjson["sockstat"]["socket"];
+
-+ for (const auto& line : lines)
-+ {
++ for(auto &port : portsResult) {
+ std::string localip = "";
+ std::string localport = "";
+ std::string remoteip = "";
+ std::string remoteport = "";
+ std::string statedata = "";
+
-+ const auto data{Utils::split(line, ' ')};
-+ auto localdata{Utils::split(data[5], ':')};
-+ auto remotedata{Utils::split(data[6], ':')};
++ if (port["pid"] != nullptr) {
+
-+ localip = localdata[0];
-+ localport = localdata[1];
-+ remoteip = remotedata[0];
-+ remoteport = remotedata[1];
++ localip = port["local"]["address"];
++ remoteip = port["foreign"]["address"];
++ statedata = port["conn-state"] != nullptr ? (port["conn-state"] == "LISTEN" ? "listening" : Utils::toLowerCase(port["conn-state"])) : statedata;
+
-+ if((data[4] != "udp4") && (data[4] != "udp6") && (data[4] != "udp46")) {
-+ statedata = Utils::toLowerCase(data[7]);
-+ }
++ if (port["local"]["address"] == "*") {
++ if ((port["proto"] == "udp4") || (port["proto"] == "tcp4")) {
++ localip = "0.0.0.0";
++ } else {
++ localip = "::";
++ }
++ }
+
-+ if(statedata == "listen") {
-+ statedata = "listening";
-+ }
++ localport = port["local"]["port"];
+
-+ if(localdata.size() == 4) {
-+ localip = localdata[0] + ":"+ localdata[1] + ":" + localdata[2];
-+ localport = localdata[3];
-+ }
++ if (port["foreign"]["address"] == "*") {
++ if ((port["proto"] == "udp4") || (port["proto"] == "tcp4")) {
++ remoteip = 0.0.0.0;
++ } else {
++ remoteip = "::";
++ }
++ }
+
-+ if(localip == "*") {
-+ if((data[4] == "tcp6") || (data[4] == "udp6")) {
-+ localip = "0:0:0:0:0:0:0:0";
-+ } else if((data[4] == "tcp4") || (data[4] == "udp4")) {
-+ localip = "0.0.0.0";
-+ }
-+ }
++ remoteport = port["foreign"]["port"];
+
-+ if(localport == "*") {
-+ localport = "0";
-+ }
++ nlohmann::json portRecord {};
+
-+ if(remotedata.size() == 4) {
-+ remoteip = remotedata[0] + ":"+ remotedata[1] + ":" + remotedata[2];
-+ remoteport = remotedata[3];
-+ }
++ portRecord["protocol"] = port["proto"];
++ portRecord["local_ip"] = localip;
++ portRecord["local_port"] = localport == "*" ? "0" : localport;
++ portRecord["remote_ip"] = remoteip;
++ portRecord["remote_port"] = remoteport == "*" ? "0" : remoteport;
++ portRecord["tx_queue"] = 0;
++ portRecord["rx_queue"] = 0;
++ portRecord["inode"] = port["fd"];
++ portRecord["state"] = statedata == "??" ? "" : statedata;
++ portRecord["pid"] = port["pid"];
++ portRecord["process"] = port["command"];
+
-+ if(remoteport == "*") {
-+ remoteip = "";
-+ remoteport = "0";
-+ }
++ ports.push_back(portRecord);
++ }
++ }
++ }
++#else
++ const auto query{Utils::exec(R"(sockstat -46qs)")};
+
-+ if(data[0] != "?") {
-+ nlohmann::json port {};
-+ port["protocol"] = data[4];
-+ port["local_ip"] = localip;
-+ port["local_port"] = localport;
-+ port["remote_ip"] = remoteip;
-+ port["remote_port"] = remoteport;
-+ port["tx_queue"] = 0;
-+ port["rx_queue"] = 0;
-+ port["inode"] = data[3];
-+ port["state"] = statedata;
-+ port["pid"] = data[2];
-+ port["process"] = data[1];
++ if (!query.empty())
++ {
++ const auto lines{Utils::split(Utils::trimToOneSpace(query), '\n')};
++
++ std::regex expression(R"(^(\S+)\s+(\S+)\s+(\d+)\s+(\d+)\s*(\S+)\s+(\S+)\s+(\S+)(?:\s+(\S+))?\s*$)");
++
++ for (const auto& line : lines)
++ {
++ std::smatch data;
++
++ if (std::regex_search(line, data, expression))
++ {
++ std::string localip = "";
++ std::string localport = "";
++ std::string remoteip = "";
++ std::string remoteport = "";
++ std::string statedata = "";
++
++ auto localdata{Utils::split(data[6], ':')};
++ auto remotedata{Utils::split(data[7], ':')};
+
-+ ports.push_back(port);
++ if (data[8].matched ) {
++ statedata = data[8] == "LISTEN" ? "listening" : Utils::toLowerCase(data[8]);
++ }
++
++ localport = localdata[localdata.size() - 1];
++ localdata.pop_back();
++ localip = Utils::join(localdata, ":");
++ remoteport = remotedata[remotedata.size() - 1];
++ remotedata.pop_back();
++ remoteip = Utils::join(remotedata, ":");
++
++ if(localip == "*") {
++ if((data[5] == "tcp4") || (data[5] == "udp4")) {
++ localip = "0.0.0.0";
++ } else {
++ localip = "::";
++ }
++ }
++
++ if(remoteip == "*") {
++ if((data[5] == "tcp4") || (data[5] == "udp4")) {
++ remoteip = "0.0.0.0";
++ } else {
++ remoteip = "::";
++ }
++ }
++
++ if(data[0] != "?") {
++ nlohmann::json port {};
++
++ port["protocol"] = data[5];
++ port["local_ip"] = localip;
++ port["local_port"] = localport == "*" ? "0" : localport;
++ port["remote_ip"] = remoteip;
++ port["remote_port"] = remoteport == "*" ? "0" : remoteport;
++ port["tx_queue"] = 0;
++ port["rx_queue"] = 0;
++ port["inode"] = data[4];
++ port["state"] = statedata == "??" ? "" : statedata;
++ port["pid"] = data[3];
++ port["process"] = data[2];
++
++ ports.push_back(port);
++ }
+ }
-+ }
++ }
+ }
-+
++#endif
+ return ports;
}
@@ -246,7 +303,7 @@
if (!query.empty())
{
-@@ -235,18 +381,22 @@
+@@ -235,6 +437,9 @@
for (const auto& line : lines)
{
const auto data{Utils::split(line, '|')};
@@ -254,8 +311,11 @@
+ const auto sectiondata{Utils::split(data[8], '/')};
+
nlohmann::json package;
+ std::string vendor { UNKNOWN_VALUE };
+ std::string email { UNKNOWN_VALUE };
+@@ -244,14 +449,15 @@
package["name"] = data[0];
- package["vendor"] = data[1];
+ package["vendor"] = vendor;
package["version"] = data[2];
- package["install_time"] = UNKNOWN_VALUE;
+ package["install_time"] = data[6];
diff --git a/security/wazuh-manager/files/patch-src-shared_modules-utils_stringHelper.h b/security/wazuh-manager/files/patch-src-shared_modules-utils_stringHelper.h
index d06cb28926e7..e60c6542e5a4 100644
--- a/security/wazuh-manager/files/patch-src-shared_modules-utils_stringHelper.h
+++ b/security/wazuh-manager/files/patch-src-shared_modules-utils_stringHelper.h
@@ -1,14 +1,30 @@
---- src/shared_modules/utils/stringHelper.h 2025-01-08 01:15:05.000000000 -0800
-+++ src/shared_modules/utils/stringHelper.h 2025-01-14 21:32:26.067988000 -0800
+--- src/shared_modules/utils/stringHelper.h 2025-09-23 06:59:40.000000000 -0700
++++ src/shared_modules/utils/stringHelper.h 2025-10-16 14:04:29.575997000 -0700
@@ -19,6 +19,7 @@
#include <sstream>
#include <string>
#include <vector>
+#include <map>
+ #if __cplusplus >= 201703L
+ #include <string_view>
+ #endif
+@@ -150,6 +151,15 @@
+ return haystack;
+ }
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-function"
-@@ -254,6 +255,17 @@
++ static std::string join(const std::vector<std::string>& vec, const std::string& delimiter) {
++ std::ostringstream joinResult;
++ for (size_t i = 0; i < vec.size(); ++i) {
++ joinResult << vec[i];
++ if (i != vec.size() - 1) joinResult << delimiter;
++ }
++ return joinResult.str();
++ }
++
+ static std::vector<std::string> split(const std::string& str, const char delimiter)
+ {
+ std::vector<std::string> tokens;
+@@ -257,6 +267,17 @@
// LCOV_EXCL_STOP
return ret;
diff --git a/security/wazuh-manager/files/patch-src_Makefile b/security/wazuh-manager/files/patch-src_Makefile
index 23d66a5f8a86..a45608e5dff6 100644
--- a/security/wazuh-manager/files/patch-src_Makefile
+++ b/security/wazuh-manager/files/patch-src_Makefile
@@ -1,5 +1,5 @@
---- src/Makefile 2025-04-30 02:30:26.000000000 -0700
-+++ src/Makefile 2025-05-23 14:25:52.122383000 -0700
+--- src/Makefile 2025-09-23 06:59:40.000000000 -0700
++++ src/Makefile 2025-10-12 08:02:29.393309000 -0700
@@ -49,9 +49,11 @@
HAS_CHECKMODULE = $(shell command -v checkmodule > /dev/null && echo YES)
@@ -12,7 +12,7 @@
ARCH_FLAGS =
-@@ -110,7 +112,7 @@
+@@ -112,7 +114,7 @@
USE_PRELUDE?=no
USE_ZEROMQ?=no
USE_GEOIP?=no
@@ -21,16 +21,16 @@
USE_BIG_ENDIAN=no
USE_AUDIT=no
MINGW_HOST=unknown
-@@ -175,6 +177,8 @@
+@@ -177,6 +179,8 @@
DEFINES+=-DUSER=\"${WAZUH_USER}\"
DEFINES+=-DGROUPGLOBAL=\"${WAZUH_GROUP}\"
-+OSSEC_CFLAGS+=-I./ -I./headers/ -I${EXTERNAL_OPENSSL}include -I$(EXTERNAL_JSON) -I${EXTERNAL_LIBYAML}include -I${EXTERNAL_CURL}include -I${EXTERNAL_MSGPACK}include -I${EXTERNAL_BZIP2} -I${SHARED_MODULES}common -I${DBSYNC}include -I${RSYNC}include -I${SYSCOLLECTOR}include -I${SYSINFO}include -I${EXTERNAL_LIBPCRE2}include -I${EXTERNAL_RPM}/builddir/output/include -I${SYSCHECK}include -I${ROUTER}include -I${CONTENT_MANAGER}include -I${VULNERABILITY_SCANNER}include -I./shared_modules/
++OSSEC_CFLAGS+=-I./ -I./headers/ -I${EXTERNAL_OPENSSL}include -I$(EXTERNAL_JSON) -I${EXTERNAL_LIBYAML}include -I${EXTERNAL_CURL}include -I${EXTERNAL_MSGPACK}include -I${EXTERNAL_BZIP2} -I${SHARED_MODULES}common -I${DBSYNC}include -I${RSYNC}include -I${SYSCOLLECTOR}include -I${SYSINFO}include -I${EXTERNAL_LIBPCRE2}include -I${EXTERNAL_RPM}/builddir/output/include -I${SYSCHECK}include -I${ROUTER}include -I${CONTENT_MANAGER}include -I${VULNERABILITY_SCANNER}include -I${INVENTORY_HARVESTER}include -I./shared_modules/
+
ifneq (${TARGET},winagent)
DEFINES+=-D${uname_S}
ifeq (${uname_S},Linux)
-@@ -269,13 +273,14 @@
+@@ -271,13 +275,14 @@
ifeq (${uname_S},FreeBSD)
DEFINES+=-DFreeBSD
OSSEC_CFLAGS+=-pthread -I/usr/local/include
@@ -47,15 +47,15 @@
else
ifeq (${uname_S},NetBSD)
DEFINES+=-DNetBSD
-@@ -434,7 +439,6 @@
+@@ -436,7 +441,6 @@
OSSEC_CFLAGS+=${DEFINES}
OSSEC_CFLAGS+=-pipe -Wall -Wextra -std=gnu99
--OSSEC_CFLAGS+=-I./ -I./headers/ -I${EXTERNAL_OPENSSL}include -I$(EXTERNAL_JSON) -I${EXTERNAL_LIBYAML}include -I${EXTERNAL_CURL}include -I${EXTERNAL_MSGPACK}include -I${EXTERNAL_BZIP2} -I${SHARED_MODULES}common -I${DBSYNC}include -I${RSYNC}include -I${SYSCOLLECTOR}include -I${SYSINFO}include -I${EXTERNAL_LIBPCRE2}include -I${EXTERNAL_RPM}/builddir/output/include -I${SYSCHECK}include -I${ROUTER}include -I${CONTENT_MANAGER}include -I${VULNERABILITY_SCANNER}include -I./shared_modules/
+-OSSEC_CFLAGS+=-I./ -I./headers/ -I${EXTERNAL_OPENSSL}include -I$(EXTERNAL_JSON) -I${EXTERNAL_LIBYAML}include -I${EXTERNAL_CURL}include -I${EXTERNAL_MSGPACK}include -I${EXTERNAL_BZIP2} -I${SHARED_MODULES}common -I${DBSYNC}include -I${RSYNC}include -I${SYSCOLLECTOR}include -I${SYSINFO}include -I${EXTERNAL_LIBPCRE2}include -I${EXTERNAL_RPM}/builddir/output/include -I${SYSCHECK}include -I${ROUTER}include -I${CONTENT_MANAGER}include -I${VULNERABILITY_SCANNER}include -I${INVENTORY_HARVESTER}include -I./shared_modules/
OSSEC_CFLAGS += ${CFLAGS}
OSSEC_LDFLAGS += ${LDFLAGS}
-@@ -531,8 +535,8 @@
+@@ -533,8 +537,8 @@
ifneq (,$(filter ${USE_INOTIFY},YES auto yes y Y 1))
DEFINES+=-DINOTIFY_ENABLED
ifeq (${uname_S},FreeBSD)
@@ -66,21 +66,21 @@
OSSEC_CFLAGS+=-I/usr/local/include
endif
endif
-@@ -957,6 +961,8 @@
+@@ -960,6 +964,8 @@
EXTERNAL_LIBS += $(LIBCURL_LIB)
else ifeq (${uname_S},Linux)
EXTERNAL_LIBS += $(LIBCURL_LIB)
+else ifeq (${uname_S},FreeBSD)
-+ EXTERNAL_LIBS += $(LIBCURL_LIB)
++ EXTERNAL_LIBS += $(LIBCURL_LIB)
else ifeq (${uname_S},Darwin)
EXTERNAL_LIBS += $(LIBCURL_LIB)
endif
-@@ -1186,9 +1192,13 @@
+@@ -1193,9 +1199,13 @@
cd $(EXTERNAL_CURL) && CPPFLAGS="-fPIC -I${ROUTE_PATH}/${EXTERNAL_OPENSSL}include" LDFLAGS="-L${ROUTE_PATH}/${EXTERNAL_OPENSSL}" LIBS="-ldl -lpthread" ./configure --with-openssl="${ROUTE_PATH}/${EXTERNAL_OPENSSL}" --disable-ldap --without-libidn2 --without-libpsl --without-brotli --without-nghttp2 --without-zstd
endif
else
+ifeq (${uname_S},FreeBSD)
-+ cd $(EXTERNAL_CURL) && CPPFLAGS="-fPIC -I${ROUTE_PATH}/${EXTERNAL_OPENSSL}include" LDFLAGS="-L${ROUTE_PATH}/${EXTERNAL_OPENSSL}" LIBS="-pthread" ./configure --with-ssl="${ROUTE_PATH}/${EXTERNAL_OPENSSL}" --disable-ldap --without-libidn2 --without-brotli --without-nghttp2 --without-librtmp --without-zstd --without-libpsl
++ cd $(EXTERNAL_CURL) && CPPFLAGS="-fPIC -I${ROUTE_PATH}/${EXTERNAL_OPENSSL}include" LDFLAGS="-L${ROUTE_PATH}/${EXTERNAL_OPENSSL}" LIBS="-pthread" ./configure --with-ssl="${ROUTE_PATH}/${EXTERNAL_OPENSSL}" --disable-ldap --without-libidn2 --without-brotli --without-nghttp2 --without-librtmp --without-zstd --without-libpsl
+else
cd $(EXTERNAL_CURL) && CPPFLAGS="-fPIC -I${ROUTE_PATH}/${EXTERNAL_OPENSSL}include" LDFLAGS="-L${ROUTE_PATH}/${EXTERNAL_OPENSSL}" LIBS="-lpthread" ./configure --with-openssl="${ROUTE_PATH}/${EXTERNAL_OPENSSL}" --disable-ldap --without-libidn2 --without-brotli --without-nghttp2 --without-librtmp --without-zstd --without-libpsl
endif
@@ -89,7 +89,7 @@
#### procps #########
-@@ -2295,7 +2305,7 @@
+@@ -2308,7 +2318,7 @@
#### FIM ######
wazuh-syscheckd: librootcheck.a libwazuh.a ${WAZUHEXT_LIB} build_shared_modules
@@ -98,7 +98,23 @@
#### Monitor #######
-@@ -2473,7 +2483,7 @@
+@@ -2340,13 +2350,13 @@
+ os_auth_o := $(os_auth_c:.c=.o)
+
+ os_auth/%.o: os_auth/%.c
+- ${OSSEC_CC} ${OSSEC_CFLAGS} -I./os_auth -DARGV0=\"wazuh-authd\" -c $^ -o $@
++ ${OSSEC_CC} -I${LOCALBASE}/include/libepoll-shim ${OSSEC_CFLAGS} -I./os_auth -DARGV0=\"wazuh-authd\" -c $^ -o $@
+
+ agent-auth: addagent/validate.o os_auth/main-client.o os_auth/ssl.o os_auth/check_cert.o
+ ${OSSEC_CCBIN} ${OSSEC_LDFLAGS} $^ ${OSSEC_LIBS} -o $@
+
+ wazuh-authd: addagent/validate.o os_auth/main-server.o os_auth/local-server.o os_auth/ssl.o os_auth/check_cert.o os_auth/config.o os_auth/authcom.o os_auth/auth.o os_auth/key_request.o os_auth/generate_cert.o
+- ${OSSEC_CCBIN} ${OSSEC_LDFLAGS} $^ ${OSSEC_LIBS} -o $@
++ ${OSSEC_CCBIN} ${OSSEC_LDFLAGS} $^ ${OSSEC_LIBS} -lepoll-shim -o $@
+
+ #### integratord #####
+
+@@ -2486,7 +2496,7 @@
WPYTHON_DIR := ${INSTALLDIR}/framework/python
OPTIMIZE_CPYTHON?=no
WPYTHON_TAR=cpython.tar.gz
@@ -107,7 +123,7 @@
ifneq (,$(filter ${OPTIMIZE_CPYTHON},YES yes y Y 1))
CPYTHON_FLAGS=--enable-optimizations
-@@ -2487,22 +2497,45 @@
+@@ -2500,22 +2510,45 @@
endif
ifeq (,$(wildcard ${EXTERNAL_CPYTHON}/python))
@@ -133,7 +149,7 @@
+endif
python_dependencies := requirements.txt
-+
+
+ifeq (${uname_S},FreeBSD)
+install_dependencies:
+ifneq (,$(wildcard ${EXTERNAL_CPYTHON}))
@@ -148,14 +164,14 @@
+
+install_api:
+ LD_LIBRARY_PATH="$(STAGEDIR)${INSTALLDIR}/lib" LDFLAGS="-L$(STAGEDIR)${INSTALLDIR}/lib" $(STAGEDIR)${WPYTHON_DIR}/bin/python3 -m pip install wazuh-python/api*.whl --root=$(STAGEDIR) --prefix=${WPYTHON_DIR} --no-deps --no-compile
-
++
+install_mitre:
+ export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1 && cd ../tools/mitre && $(STAGEDIR)${WPYTHON_DIR}/bin/python3 mitredb.py -d $(STAGEDIR)${INSTALLDIR}/var/db/mitre.db
+else
install_dependencies: install_python
ifneq (,$(wildcard ${EXTERNAL_CPYTHON}))
${WPYTHON_DIR}/bin/python3 -m pip install --upgrade pip --index-url=file://${ROUTE_PATH}/${EXTERNAL_CPYTHON}/Dependencies/simple
-@@ -2519,6 +2552,7 @@
+@@ -2532,6 +2565,7 @@
install_mitre: install_python
cd ../tools/mitre && ${WPYTHON_DIR}/bin/python3 mitredb.py -d ${INSTALLDIR}/var/db/mitre.db
diff --git a/security/wazuh-manager/files/patch-src_analysisd_analysisd.c b/security/wazuh-manager/files/patch-src_analysisd_analysisd.c
new file mode 100644
index 000000000000..aa1a242a682b
--- /dev/null
+++ b/security/wazuh-manager/files/patch-src_analysisd_analysisd.c
@@ -0,0 +1,79 @@
+--- src/analysisd/analysisd.c 2025-09-23 06:59:40.000000000 -0700
++++ src/analysisd/analysisd.c 2025-10-13 02:16:24.332647000 -0700
+@@ -237,7 +237,11 @@
+ /* Hourly alerts mutex */
+ pthread_mutex_t hourly_alert_mutex = PTHREAD_MUTEX_INITIALIZER;
+ /* hot reload mutes */
++#if defined(__FreeBSD__)
++static portable_rwlock_t g_hotreload_ruleset_mutex;
++#else
+ static pthread_rwlock_t g_hotreload_ruleset_mutex;
++#endif
+
+ /* Reported mutexes */
+ static pthread_mutex_t writer_threads_mutex = PTHREAD_MUTEX_INITIALIZER;
+@@ -842,11 +846,15 @@
+ w_init_queues();
+
+ /* Sync for event queues and API, for hot reload */
++#if defined(__FreeBSD__)
++ portable_rwlock_init(&g_hotreload_ruleset_mutex);
++#else
+ pthread_rwlockattr_t rwlock_attr;
+ pthread_rwlockattr_init(&rwlock_attr);
+ pthread_rwlockattr_setkind_np(&rwlock_attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
+ pthread_rwlock_init(&g_hotreload_ruleset_mutex, &rwlock_attr);
+ pthread_rwlockattr_destroy(&rwlock_attr);
++#endif
+
+ // Start com request thread
+ w_create_thread(asyscom_main, NULL);
+@@ -1226,7 +1234,11 @@
+
+ result = -1;
+ // take the ruleset
++#if defined(__FreeBSD__)
++ w_portable_rwlock_rdlock(&g_hotreload_ruleset_mutex);
++#else
+ w_rwlock_rdlock(&g_hotreload_ruleset_mutex);
++#endif
+
+ if (msg[0] == SYSCHECK_MQ) {
+ if (!queue_full(decode_queue_syscheck_input)) {
+@@ -1426,8 +1438,11 @@
+ }
+ }
+
+-
++#if defined(__FreeBSD__)
++ w_portable_rwlock_unlock_read(&g_hotreload_ruleset_mutex);
++#else
+ w_rwlock_unlock(&g_hotreload_ruleset_mutex);
++#endif
+
+ if (result == -1) {
+ if (!reported_eps_drop) {
+@@ -2454,7 +2469,11 @@
+
+ // Sync thread for reloading ruleset,
+ mdebug1("Blocking input threads to reload ruleset");
++#if defined(__FreeBSD__)
++ w_portable_rwlock_wrlock(&g_hotreload_ruleset_mutex);
++#else
+ w_rwlock_wrlock(&g_hotreload_ruleset_mutex);
++#endif
+
+ // Wait for a clean pipeline
+ mdebug1("Wait for pipeline to be clean");
+@@ -2481,7 +2500,11 @@
+ w_hotreload_reload_internal_decoders();
+
+ // Run the new ruleset
++#if defined(__FreeBSD__)
++ w_portable_rwlock_unlock_write(&g_hotreload_ruleset_mutex);
++#else
+ w_rwlock_unlock(&g_hotreload_ruleset_mutex);
++#endif
+
+ mdebug1("Unblocking input threads (Enable new ruleset)");
+
diff --git a/security/wazuh-manager/files/patch-src_external_cpython_Makefile.pre.in b/security/wazuh-manager/files/patch-src_external_cpython_Makefile.pre.in
index 6f3aeb6eb06b..3b6ffc040dc2 100644
--- a/security/wazuh-manager/files/patch-src_external_cpython_Makefile.pre.in
+++ b/security/wazuh-manager/files/patch-src_external_cpython_Makefile.pre.in
@@ -1,5 +1,5 @@
---- src/external/cpython/Makefile.pre.in 2025-04-08 07:15:29.000000000 -0700
-+++ src/external/cpython/Makefile.pre.in 2025-05-09 18:15:10.761567000 -0700
+--- src/external/cpython/Makefile.pre.in 2025-10-20 18:41:32.000000000 -0700
++++ src/external/cpython/Makefile.pre.in 2025-10-20 19:52:41.710772000 -0700
@@ -71,14 +71,14 @@
INSTALL_DATA= @INSTALL_DATA@
# Shared libraries must be installed with executable mode on some systems;
@@ -33,7 +33,7 @@
-Programs/_testembed: Programs/_testembed.o $(LINK_PYTHON_DEPS)
- $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS)
+: .o $(LINK_PYTHON_DEPS)
-+ $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ .o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS)
++ $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS)
############################################################################
# "Bootstrap Python" used to run deepfreeze.py
@@ -110,7 +110,7 @@
LIBPL= @LIBPL@
# pkgconfig directory
--LIBPC= $(LIBDIR)/pkgconfig
+-LIBPC= $(PREFIX)/libdata/pkgconfig
+LIBPC= $(prefix)/libdata/pkgconfig
libainstall: all python-config
diff --git a/security/wazuh-manager/files/patch-src_headers_pthreads_op.h b/security/wazuh-manager/files/patch-src_headers_pthreads_op.h
new file mode 100644
index 000000000000..607c15ffdb07
--- /dev/null
+++ b/security/wazuh-manager/files/patch-src_headers_pthreads_op.h
@@ -0,0 +1,40 @@
+--- src/headers/pthreads_op.h 2025-09-23 06:59:40.000000000 -0700
++++ src/headers/pthreads_op.h 2025-10-13 00:48:19.635169000 -0700
+@@ -25,6 +25,37 @@
+ #define w_cond_signal(x) { int error = pthread_cond_signal(x); if (error) merror_exit("At pthread_cond_signal(): %s", strerror(error)); }
+ #define w_cond_broadcast(x) { int error = pthread_cond_broadcast(x); if (error) merror_exit("At pthread_cond_broadcast(): %s", strerror(error)); }
+ #define w_cond_destroy(x) { int error = pthread_cond_destroy(x); if (error) merror_exit("At pthread_cond_destroy(): %s", strerror(error)); }
++#if defined(__FreeBSD__)
++#define w_portable_rwlock_init(x, y) { \
++ if (portable_rwlock_init(x) != 0) \
++ merror_exit("At portable_rwlock_init(): failed to initialize rwlock"); \
++}
++
++#define w_portable_rwlock_rdlock(x) { \
++ if (portable_rwlock_rdlock(x) != 0) \
++ merror_exit("At portable_rwlock_rdlock(): failed to acquire read lock"); \
++}
++
++#define w_portable_rwlock_wrlock(x) { \
++ if (portable_rwlock_wrlock(x) != 0) \
++ merror_exit("At portable_rwlock_wrlock(): failed to acquire write lock"); \
++}
++
++#define w_portable_rwlock_unlock_read(x) { \
++ if (portable_rwlock_rdunlock(x) != 0) \
++ merror_exit("At portable_rwlock_rdunlock(): failed to release read lock"); \
++}
++
++#define w_portable_rwlock_unlock_write(x) { \
++ if (portable_rwlock_wrunlock(x) != 0) \
++ merror_exit("At portable_rwlock_wrunlock(): failed to release write lock"); \
++}
++
++#define w_portable_rwlock_destroy(x) { \
++ if (portable_rwlock_destroy(x) != 0) \
++ merror_exit("At portable_rwlock_destroy(): failed to destroy rwlock"); \
++}
++#endif
+ #define w_rwlock_init(x, y) { int error = pthread_rwlock_init(x, y); if (error) merror_exit("At pthread_rwlock_init(): %s", strerror(error)); }
+ #define w_rwlock_rdlock(x) { int error = pthread_rwlock_rdlock(x); if (error) merror_exit("At pthread_rwlock_rdlock(): %s", strerror(error)); }
+ #define w_rwlock_wrlock(x) { int error = pthread_rwlock_wrlock(x); if (error) merror_exit("At pthread_rwlock_wrlock(): %s", strerror(error)); }
diff --git a/security/wazuh-manager/files/patch-src_headers_shared.h b/security/wazuh-manager/files/patch-src_headers_shared.h
new file mode 100644
index 000000000000..ba698bed03c2
--- /dev/null
+++ b/security/wazuh-manager/files/patch-src_headers_shared.h
@@ -0,0 +1,10 @@
+--- src/headers/shared.h 2025-10-12 17:57:55.002875000 -0700
++++ src/headers/shared.h 2025-10-12 17:41:58.102112000 -0700
+@@ -242,6 +242,7 @@
+ #include "math_op.h"
+ #include "mq_op.h"
+ #include "privsep_op.h"
++#include "pthreads_portable.h"
+ #include "pthreads_op.h"
+ #include "regex_op.h"
+ #include "sig_op.h"
diff --git a/security/wazuh-manager/files/patch-src_remoted_manager.c b/security/wazuh-manager/files/patch-src_remoted_manager.c
new file mode 100644
index 000000000000..a36845ec26ed
--- /dev/null
+++ b/security/wazuh-manager/files/patch-src_remoted_manager.c
@@ -0,0 +1,16 @@
+--- src/remoted/manager.c 2025-12-16 11:37:43.185027000 -0800
++++ src/remoted/manager.c 2025-12-16 11:38:04.427583000 -0800
+@@ -18,7 +18,12 @@
+ #include "../os_crypto/sha256/sha256_op.h"
+ #include <pthread.h>
+
+-#if defined(__FreeBSD__) || defined(__MACH__) || defined(__sun__)
++#if defined(__FreeBSD__)
++#include <sys/param.h>
++#define HOST_NAME_MAX MAXHOSTNAMELEN
++#endif
++
++#if defined(__MACH__) || defined(__sun__)
+ #define HOST_NAME_MAX 64
+ #endif
+
diff --git a/security/wazuh-manager/files/patch-src_shared__modules_router_CMakeLists.txt b/security/wazuh-manager/files/patch-src_shared__modules_router_CMakeLists.txt
index 015ec525e719..c0614dbf67c4 100644
--- a/security/wazuh-manager/files/patch-src_shared__modules_router_CMakeLists.txt
+++ b/security/wazuh-manager/files/patch-src_shared__modules_router_CMakeLists.txt
@@ -1,5 +1,5 @@
---- src/shared_modules/router/CMakeLists.txt.orig 2024-10-21 18:20:47.157822000 -0700
-+++ src/shared_modules/router/CMakeLists.txt 2024-10-21 18:24:54.294400000 -0700
+--- src/shared_modules/router/CMakeLists.txt 2025-09-23 06:59:40.000000000 -0700
++++ src/shared_modules/router/CMakeLists.txt 2025-10-11 22:43:21.449602000 -0700
@@ -19,6 +19,7 @@
# Include directories
@@ -8,12 +8,12 @@
include_directories(${SRC_FOLDER})
include_directories(${SRC_FOLDER}/headers)
-@@ -39,7 +40,7 @@
+@@ -42,7 +43,7 @@
${ROUTER_SRC}
)
--target_link_libraries(router gcc_s flatbuffers)
-+target_link_libraries(router gcc_s flatbuffers epoll-shim)
+-target_link_libraries(router gcc_s flatbuffers wazuhext simdjson)
++target_link_libraries(router gcc_s flatbuffers wazuhext simdjson epoll-shim)
set_target_properties(router PROPERTIES
BUILD_RPATH_USE_ORIGIN TRUE
diff --git a/security/wazuh-manager/files/patch-src_shared__modules_utils_socketWrapper.hpp b/security/wazuh-manager/files/patch-src_shared__modules_utils_socketWrapper.hpp
index 449afde239d5..607e1b96e765 100644
--- a/security/wazuh-manager/files/patch-src_shared__modules_utils_socketWrapper.hpp
+++ b/security/wazuh-manager/files/patch-src_shared__modules_utils_socketWrapper.hpp
@@ -1,5 +1,5 @@
---- src/shared_modules/utils/socketWrapper.hpp.orig 2024-10-20 21:04:00.880393000 -0700
-+++ src/shared_modules/utils/socketWrapper.hpp 2024-10-20 21:07:41.992525000 -0700
+--- src/shared_modules/utils/socketWrapper.hpp 2025-09-23 06:59:40.000000000 -0700
++++ src/shared_modules/utils/socketWrapper.hpp 2025-10-11 22:55:35.847683000 -0700
@@ -28,6 +28,11 @@
#include <thread>
#include <unistd.h>
@@ -9,6 +9,6 @@
+#define SO_SNDBUFFORCE SO_SNDBUF
+#endif
+
- constexpr auto INVALID_SOCKET {-1};
- constexpr auto SOCKET_ERROR {-1};
- using PacketFieldType = uint32_t;
+ #ifdef INVALID_SOCKET
+ #undef INVALID_SOCKET
+ #endif
diff --git a/security/wazuh-manager/files/pkg-message.in b/security/wazuh-manager/files/pkg-message.in
index e0154436e67a..716a0ad7f809 100644
--- a/security/wazuh-manager/files/pkg-message.in
+++ b/security/wazuh-manager/files/pkg-message.in
@@ -36,7 +36,7 @@ Wazuh Manager was installed
https://github.com/alonsobsd/wazuh-freebsd
- Decoders and rules are used for extract some /var/log/userlog and
+ Decoders and rules are used to extract some /var/log/userlog and
/var/log/messages entries from FreeBSD agents. It is necessary add a localfile
entry to /var/ossec/etc/ossec.conf
@@ -44,8 +44,34 @@ Wazuh Manager was installed
<log_format>syslog</log_format>
<location>/var/log/userlog</location>
</localfile>
+
+7) Vulnerability detector and Indexer connector are disabled by default. If you
+ want to use them, don't forget to configure and enable them from
+ /var/ossec/etc/ossec.conf file. Also, you will need download vd database file
+ to Wazuh tmp directory.
+
+ # cd /var/ossec/tmp && fetch http://packages.wazuh.com/deps/vulnerability_model_database/vd_1.0.0_vd_4.13.0.tar.xz
+ # chmod 640 /var/ossec/tmp/vd_1.0.0_vd_4.13.0.tar.xz
+ # chown wazuh:wazuh /var/ossec/tmp/vd_1.0.0_vd_4.13.0.tar.xz
+
+ Take on mind, a valid certificate is necessary to connect Indexer connector
+ (Wazuh manager) to Wazuh indexer (OpenSearch).
+
+8) Save Wazuh indexer username and password into the Wazuh keystore.
+
+ # export WAZUH_HOME=/var/ossec
+ # echo '<INDEXER_USERNAME>' | /var/ossec/bin/wazuh-keystore -f indexer -k username
+ # echo '<INDEXER_PASSWORD>' | /var/ossec/bin/wazuh-keystore -f indexer -k password
+
+ By default, INDEXER_USERNAME and INDEXER_PASSWORD are admin and admin.
+
+9) Use a certificate generated previously. For example, you can use logstash
+ certificates. Otherwise, you can use a simplified certificates generator
+ script for this task. Download it from the following url:
+
+ https://people.freebsd.org/~acm/ports/wazuh/wazuh-gen-certs.tar.gz
-7) Add Wazuh manager to /etc/rc.conf
+10) Add Wazuh manager to /etc/rc.conf
# sysrc wazuh_manager_enable="YES"
@@ -53,11 +79,11 @@ Wazuh Manager was installed
# service wazuh-manager enable
-8) Start Wazuh manager
+11) Start Wazuh manager
# service wazuh-manager start
-9) Enjoy it ;)
+12) Enjoy it ;)
EOM
}
]
diff --git a/security/wazuh-manager/files/pthreads_portable.c b/security/wazuh-manager/files/pthreads_portable.c
new file mode 100644
index 000000000000..fe9be28e725b
--- /dev/null
+++ b/security/wazuh-manager/files/pthreads_portable.c
@@ -0,0 +1,91 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 J. Cardenas Marquez <acm@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "pthreads_portable.h"
+
+int portable_rwlock_init(portable_rwlock_t *rw) {
+ if (pthread_mutex_init(&rw->lock, NULL) != 0) return -1;
+ if (pthread_cond_init(&rw->readers_ok, NULL) != 0) return -1;
+ if (pthread_cond_init(&rw->writers_ok, NULL) != 0) return -1;
+ rw->active_readers = 0;
+ rw->waiting_writers = 0;
+ rw->writer_active = 0;
+ return 0;
+}
+
+int portable_rwlock_rdlock(portable_rwlock_t *rw) {
+ if (pthread_mutex_lock(&rw->lock) != 0) return -1;
+ while (rw->writer_active || rw->waiting_writers > 0) {
+ if (pthread_cond_wait(&rw->readers_ok, &rw->lock) != 0) {
+ pthread_mutex_unlock(&rw->lock);
+ return -1;
+ }
+ }
+ rw->active_readers++;
+ return pthread_mutex_unlock(&rw->lock);
+}
+
+int portable_rwlock_rdunlock(portable_rwlock_t *rw) {
+ if (pthread_mutex_lock(&rw->lock) != 0) return -1;
+ rw->active_readers--;
+ if (rw->active_readers == 0 && rw->waiting_writers > 0)
+ pthread_cond_signal(&rw->writers_ok);
+ return pthread_mutex_unlock(&rw->lock);
+}
+
+int portable_rwlock_wrlock(portable_rwlock_t *rw) {
+ if (pthread_mutex_lock(&rw->lock) != 0) return -1;
+ rw->waiting_writers++;
+ while (rw->writer_active || rw->active_readers > 0) {
+ if (pthread_cond_wait(&rw->writers_ok, &rw->lock) != 0) {
+ rw->waiting_writers--;
+ pthread_mutex_unlock(&rw->lock);
+ return -1;
+ }
+ }
+ rw->waiting_writers--;
+ rw->writer_active = 1;
+ return pthread_mutex_unlock(&rw->lock);
+}
+
+int portable_rwlock_wrunlock(portable_rwlock_t *rw) {
+ if (pthread_mutex_lock(&rw->lock) != 0) return -1;
+ rw->writer_active = 0;
+ if (rw->waiting_writers > 0)
+ pthread_cond_signal(&rw->writers_ok);
+ else
+ pthread_cond_broadcast(&rw->readers_ok);
+ return pthread_mutex_unlock(&rw->lock);
+}
+
+int portable_rwlock_destroy(portable_rwlock_t *rw) {
+ if (pthread_mutex_destroy(&rw->lock) != 0) return -1;
+ if (pthread_cond_destroy(&rw->readers_ok) != 0) return -1;
+ if (pthread_cond_destroy(&rw->writers_ok) != 0) return -1;
+ return 0;
+}
diff --git a/security/wazuh-manager/files/pthreads_portable.h b/security/wazuh-manager/files/pthreads_portable.h
new file mode 100644
index 000000000000..302f76b54318
--- /dev/null
+++ b/security/wazuh-manager/files/pthreads_portable.h
@@ -0,0 +1,50 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 J. Alonso Cardenas <acm@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef PORTABLE_RWLOCK_H
+#define PORTABLE_RWLOCK_H
+
+#include <pthread.h>
+
+typedef struct {
+ pthread_mutex_t lock;
+ pthread_cond_t readers_ok;
+ pthread_cond_t writers_ok;
+ int active_readers;
+ int waiting_writers;
+ int writer_active;
+} portable_rwlock_t;
+
+int portable_rwlock_init(portable_rwlock_t *rw);
+int portable_rwlock_rdlock(portable_rwlock_t *rw);
+int portable_rwlock_rdunlock(portable_rwlock_t *rw);
+int portable_rwlock_wrlock(portable_rwlock_t *rw);
+int portable_rwlock_wrunlock(portable_rwlock_t *rw);
+int portable_rwlock_destroy(portable_rwlock_t *rw);
+
+#endif // PORTABLE_RWLOCK_H