Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 06 Jan 2026 23:55:46 +0000
From:      =?utf-8?Q?Jes=C3=BAs?= Daniel Colmenares Oviedo <dtxdf@FreeBSD.org>
To:        ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org
Subject:   git: 284813ec0382 - main - security/wazuh-{agent,manager}: Improve getSerialNumber
Message-ID:  <695da102.32a56.4df718b3@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by dtxdf:

URL: https://cgit.FreeBSD.org/ports/commit/?id=284813ec0382a2bfe5b2e74a3081a67599d3155d

commit 284813ec0382a2bfe5b2e74a3081a67599d3155d
Author:     Jesús Daniel Colmenares Oviedo <dtxdf@FreeBSD.org>
AuthorDate: 2026-01-06 22:39:27 +0000
Commit:     Jesús Daniel Colmenares Oviedo <dtxdf@FreeBSD.org>
CommitDate: 2026-01-06 23:54:56 +0000

    security/wazuh-{agent,manager}: Improve getSerialNumber
    
    Instead of returning UNKNOWN_VALUE, we can leverage the sysctl
    'kern.hostuuid' so that users can uniquely identify their devices.
    
    Approved by:    acm@
---
 security/wazuh-agent/Makefile                      |   2 +-
 .../patch-src-data_provider-src_sysInfoFreeBSD.cpp | 139 ++++++++++++++-------
 security/wazuh-agent/files/pkg-message.in          |   8 +-
 security/wazuh-manager/Makefile                    |   2 +-
 .../patch-src-data_provider-src_sysInfoFreeBSD.cpp | 139 ++++++++++++++-------
 security/wazuh-manager/files/pkg-message.in        |  10 +-
 6 files changed, 201 insertions(+), 99 deletions(-)

diff --git a/security/wazuh-agent/Makefile b/security/wazuh-agent/Makefile
index 7f9e53c8bd5d..9a81020fe9a5 100644
--- a/security/wazuh-agent/Makefile
+++ b/security/wazuh-agent/Makefile
@@ -1,7 +1,7 @@
 PORTNAME=	wazuh
 DISTVERSION=	4.14.1
 DISTVERSIONPREFIX=	v
-PORTREVISION=	3
+PORTREVISION=	4
 CATEGORIES=	security
 MASTER_SITES=	https://packages.wazuh.com/deps/47/libraries/sources/:wazuh_sources
 PKGNAMESUFFIX=	-agent
diff --git a/security/wazuh-agent/files/patch-src-data_provider-src_sysInfoFreeBSD.cpp b/security/wazuh-agent/files/patch-src-data_provider-src_sysInfoFreeBSD.cpp
index 58bb3ac01b91..9fb64aa3c105 100644
--- a/security/wazuh-agent/files/patch-src-data_provider-src_sysInfoFreeBSD.cpp
+++ b/security/wazuh-agent/files/patch-src-data_provider-src_sysInfoFreeBSD.cpp
@@ -1,5 +1,5 @@
---- src/data_provider/src/sysInfoFreeBSD.cpp	2025-11-07 00:46:03.000000000 -0800
-+++ src/data_provider/src/sysInfoFreeBSD.cpp	2026-01-01 13:18:42.411755000 -0800
+--- src/data_provider/src/sysInfoFreeBSD.cpp.orig	2025-11-07 04:46:03.000000000 -0400
++++ src/data_provider/src/sysInfoFreeBSD.cpp	2026-01-06 19:37:15.309352000 -0400
 @@ -11,20 +11,28 @@
  #include "sysInfo.hpp"
  #include "cmdHelper.h"
@@ -73,7 +73,52 @@
      info["ram_free"] = ramFree;
      info["ram_usage"] = 100 - (100 * ramFree / ramTotal);
  }
-@@ -184,8 +204,12 @@
+@@ -96,7 +116,43 @@
+ 
+ static std::string getSerialNumber()
+ {
+-    return UNKNOWN_VALUE;
++    size_t len{0};
++    auto ret{sysctlbyname("kern.hostuuid", nullptr, &len, nullptr, 0)};
++
++    if (ret)
++    {
++        throw std::system_error
++        {
++            ret,
++            std::system_category(),
++            "Error reading serial number (aka hostuuid)."
++        };
++    }
++
++    const auto spBuff{std::make_unique<char[]>(len + 1)};
++
++    if (!spBuff)
++    {
++        throw std::runtime_error
++        {
++            "Error allocating memory to read the serial number (aka hostuuid)."
++        };
++    }
++
++    ret = sysctlbyname("kern.hostuuid", spBuff.get(), &len, nullptr, 0);
++
++    if (ret)
++    {
++        throw std::system_error
++        {
++            ret,
++            std::system_category(),
++            "Error reading serial number (aka hostuuid)."
++        };
++    }
++
++    spBuff.get()[len] = 0;
++    return std::string{reinterpret_cast<const char*>(spBuff.get())};
+ }
+ 
+ static int getCpuCores()
+@@ -184,8 +240,12 @@
  
  nlohmann::json SysInfo::getProcessesInfo() const
  {
@@ -88,7 +133,7 @@
  }
  
  nlohmann::json SysInfo::getOsInfo() const
-@@ -196,11 +220,12 @@
+@@ -196,11 +256,12 @@
  
      if (!spParser->parseUname(Utils::exec("uname -r"), ret))
      {
@@ -102,7 +147,7 @@
      if (uname(&uts) >= 0)
      {
          ret["sysname"] = uts.sysname;
-@@ -215,43 +240,256 @@
+@@ -215,44 +276,257 @@
  
  nlohmann::json SysInfo::getPorts() const
  {
@@ -119,19 +164,23 @@
 -void SysInfo::getProcessesInfo(std::function<void(nlohmann::json&)> /*callback*/) const
 -{
 -    // Currently not supported for this OS.
+-}
 +    if (!query.empty())
 +    {
 +        nlohmann::json portsjson;
 +        portsjson = nlohmann::json::parse(query);
 +        auto &portsResult = portsjson["sockstat"]["socket"];
-+
+ 
+-void SysInfo::getPackages(std::function<void(nlohmann::json&)> callback) const
+-{
+-    const auto query{Utils::exec(R"(pkg query -a "%n|%m|%v|%q|%c")")};
 +        for(auto &port : portsResult) {
 +            std::string localip = "";
 +            std::string localport = "";
 +            std::string remoteip = "";
 +            std::string remoteport = "";
 +            std::string statedata = "";
-+
+ 
 +            if (port["pid"] != nullptr) {
 +
 +                localip = port["local"]["address"];
@@ -179,16 +228,32 @@
 +#else
 +    const auto query{Utils::exec(R"(sockstat -46qs)")};
 +
-+    if (!query.empty())
-+    {
+     if (!query.empty())
+     {
+-        const auto lines{Utils::split(query, '\n')};
 +        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)
-+        {
+         for (const auto& line : lines)
+         {
+-            const auto data{Utils::split(line, '|')};
+-            nlohmann::json package;
 +            std::smatch data;
-+
+ 
+-            package["name"] = data[0];
+-            package["vendor"] = data[1];
+-            package["version"] = data[2];
+-            package["install_time"] = UNKNOWN_VALUE;
+-            package["location"] = UNKNOWN_VALUE;
+-            package["architecture"] = data[3];
+-            package["groups"] = UNKNOWN_VALUE;
+-            package["description"] = data[4];
+-            package["size"] = 0;
+-            package["priority"] = UNKNOWN_VALUE;
+-            package["source"] = UNKNOWN_VALUE;
+-            package["format"] = "pkg";
+-            // The multiarch field won't have a default value
 +            if (std::regex_search(line, data, expression))
 +            {
 +                std::string localip = "";
@@ -196,7 +261,8 @@
 +                std::string remoteip = "";
 +                std::string remoteport = "";
 +                std::string statedata = "";
-+
+ 
+-            callback(package);
 +                auto localdata{Utils::split(data[6], ':')};
 +                auto remotedata{Utils::split(data[7], ':')};
 +
@@ -249,22 +315,18 @@
 +    }
 +#endif
 +    return ports;
- }
- 
--void SysInfo::getPackages(std::function<void(nlohmann::json&)> callback) const
++}
++
 +void SysInfo::getProcessesInfo(std::function<void(nlohmann::json&)> callback) const
- {
--    const auto query{Utils::exec(R"(pkg query -a "%n|%m|%v|%q|%c")")};
++{
 +    const auto query{Utils::exec(R"(ps -ax -w -o pid,comm,state,ppid,usertime,systime,user,ruser,svuid,group,rgroup,svgid,pri,nice,ssiz,vsz,rss,pmem,etimes,sid,pgid,tpgid,tty,cpu,nlwp,args --libxo json)")};
- 
-     if (!query.empty())
-     {
--        const auto lines{Utils::split(query, '\n')};
++
++    if (!query.empty())
++    {
 +      nlohmann::json psjson;
 +      psjson = nlohmann::json::parse(query);
 +      auto &processes = psjson["process-information"]["process"];
- 
--        for (const auto& line : lines)
++
 +      for(auto &process : processes) {
 +          std::string user_time{""};
 +          std::string system_time{""};
@@ -312,31 +374,15 @@
 +    if (Utils::existsRegular(PKG_DB_PATHNAME))
 +    {
 +        try
-         {
--            const auto data{Utils::split(line, '|')};
--            nlohmann::json package;
++        {
 +            std::shared_ptr<SQLite::IConnection> sqliteConnection = std::make_shared<SQLite::Connection>(PKG_DB_PATHNAME, SQLITE_OPEN_READONLY);
- 
--            package["name"] = data[0];
--            package["vendor"] = data[1];
--            package["version"] = data[2];
--            package["install_time"] = UNKNOWN_VALUE;
--            package["location"] = UNKNOWN_VALUE;
--            package["architecture"] = data[3];
--            package["groups"] = UNKNOWN_VALUE;
--            package["description"] = data[4];
--            package["size"] = 0;
--            package["priority"] = UNKNOWN_VALUE;
--            package["source"] = UNKNOWN_VALUE;
--            package["format"] = "pkg";
--            // The multiarch field won't have a default value
++
 +            SQLite::Statement stmt
 +            {
 +                sqliteConnection,
 +                PKG_QUERY
 +            };
- 
--            callback(package);
++
 +            while (SQLITE_ROW == stmt.step())
 +            {
 +                try
@@ -378,10 +424,11 @@
 +                    std::cerr << e.what() << std::endl;
 +                }
 +            }
-+        }
+         }
 +        catch (const std::exception& e)
 +        {
 +            std::cerr << e.what() << std::endl;
-         }
++        }
      }
  }
+ 
diff --git a/security/wazuh-agent/files/pkg-message.in b/security/wazuh-agent/files/pkg-message.in
index eaa88bed678a..a85b444231f3 100644
--- a/security/wazuh-agent/files/pkg-message.in
+++ b/security/wazuh-agent/files/pkg-message.in
@@ -31,7 +31,11 @@ Wazuh Agent was installed
 
    https://github.com/alonsobsd/wazuh-freebsd
 
-6) Add Wazuh agent to /etc/rc.conf
+6) The sysctl 'kern.hostuuid' is used as a serial number. If you are in a jail,
+    you should have at least started the 'hostid' rc script to uniquely identify
+    this device.
+
+7) Add Wazuh agent to /etc/rc.conf
 
   # sysrc wazuh_agent_enable="YES"
 
@@ -39,7 +43,7 @@ Wazuh Agent was installed
 
   # service wazuh-agent enable
 
-7) Start Wazuh agent
+8) Start Wazuh agent
 
   # service wazuh-agent start
 
diff --git a/security/wazuh-manager/Makefile b/security/wazuh-manager/Makefile
index 28ab424fa460..f1e268b16d35 100644
--- a/security/wazuh-manager/Makefile
+++ b/security/wazuh-manager/Makefile
@@ -1,7 +1,7 @@
 PORTNAME=	wazuh
 DISTVERSIONPREFIX=	v
 DISTVERSION=	4.14.1
-PORTREVISION=	3
+PORTREVISION=	4
 CATEGORIES=	security
 MASTER_SITES=	https://packages.wazuh.com/deps/47/libraries/sources/:wazuh_sources \
 		LOCAL/acm/${PORTNAME}/:wazuh_cache
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 58bb3ac01b91..9fb64aa3c105 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,5 +1,5 @@
---- src/data_provider/src/sysInfoFreeBSD.cpp	2025-11-07 00:46:03.000000000 -0800
-+++ src/data_provider/src/sysInfoFreeBSD.cpp	2026-01-01 13:18:42.411755000 -0800
+--- src/data_provider/src/sysInfoFreeBSD.cpp.orig	2025-11-07 04:46:03.000000000 -0400
++++ src/data_provider/src/sysInfoFreeBSD.cpp	2026-01-06 19:37:15.309352000 -0400
 @@ -11,20 +11,28 @@
  #include "sysInfo.hpp"
  #include "cmdHelper.h"
@@ -73,7 +73,52 @@
      info["ram_free"] = ramFree;
      info["ram_usage"] = 100 - (100 * ramFree / ramTotal);
  }
-@@ -184,8 +204,12 @@
+@@ -96,7 +116,43 @@
+ 
+ static std::string getSerialNumber()
+ {
+-    return UNKNOWN_VALUE;
++    size_t len{0};
++    auto ret{sysctlbyname("kern.hostuuid", nullptr, &len, nullptr, 0)};
++
++    if (ret)
++    {
++        throw std::system_error
++        {
++            ret,
++            std::system_category(),
++            "Error reading serial number (aka hostuuid)."
++        };
++    }
++
++    const auto spBuff{std::make_unique<char[]>(len + 1)};
++
++    if (!spBuff)
++    {
++        throw std::runtime_error
++        {
++            "Error allocating memory to read the serial number (aka hostuuid)."
++        };
++    }
++
++    ret = sysctlbyname("kern.hostuuid", spBuff.get(), &len, nullptr, 0);
++
++    if (ret)
++    {
++        throw std::system_error
++        {
++            ret,
++            std::system_category(),
++            "Error reading serial number (aka hostuuid)."
++        };
++    }
++
++    spBuff.get()[len] = 0;
++    return std::string{reinterpret_cast<const char*>(spBuff.get())};
+ }
+ 
+ static int getCpuCores()
+@@ -184,8 +240,12 @@
  
  nlohmann::json SysInfo::getProcessesInfo() const
  {
@@ -88,7 +133,7 @@
  }
  
  nlohmann::json SysInfo::getOsInfo() const
-@@ -196,11 +220,12 @@
+@@ -196,11 +256,12 @@
  
      if (!spParser->parseUname(Utils::exec("uname -r"), ret))
      {
@@ -102,7 +147,7 @@
      if (uname(&uts) >= 0)
      {
          ret["sysname"] = uts.sysname;
-@@ -215,43 +240,256 @@
+@@ -215,44 +276,257 @@
  
  nlohmann::json SysInfo::getPorts() const
  {
@@ -119,19 +164,23 @@
 -void SysInfo::getProcessesInfo(std::function<void(nlohmann::json&)> /*callback*/) const
 -{
 -    // Currently not supported for this OS.
+-}
 +    if (!query.empty())
 +    {
 +        nlohmann::json portsjson;
 +        portsjson = nlohmann::json::parse(query);
 +        auto &portsResult = portsjson["sockstat"]["socket"];
-+
+ 
+-void SysInfo::getPackages(std::function<void(nlohmann::json&)> callback) const
+-{
+-    const auto query{Utils::exec(R"(pkg query -a "%n|%m|%v|%q|%c")")};
 +        for(auto &port : portsResult) {
 +            std::string localip = "";
 +            std::string localport = "";
 +            std::string remoteip = "";
 +            std::string remoteport = "";
 +            std::string statedata = "";
-+
+ 
 +            if (port["pid"] != nullptr) {
 +
 +                localip = port["local"]["address"];
@@ -179,16 +228,32 @@
 +#else
 +    const auto query{Utils::exec(R"(sockstat -46qs)")};
 +
-+    if (!query.empty())
-+    {
+     if (!query.empty())
+     {
+-        const auto lines{Utils::split(query, '\n')};
 +        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)
-+        {
+         for (const auto& line : lines)
+         {
+-            const auto data{Utils::split(line, '|')};
+-            nlohmann::json package;
 +            std::smatch data;
-+
+ 
+-            package["name"] = data[0];
+-            package["vendor"] = data[1];
+-            package["version"] = data[2];
+-            package["install_time"] = UNKNOWN_VALUE;
+-            package["location"] = UNKNOWN_VALUE;
+-            package["architecture"] = data[3];
+-            package["groups"] = UNKNOWN_VALUE;
+-            package["description"] = data[4];
+-            package["size"] = 0;
+-            package["priority"] = UNKNOWN_VALUE;
+-            package["source"] = UNKNOWN_VALUE;
+-            package["format"] = "pkg";
+-            // The multiarch field won't have a default value
 +            if (std::regex_search(line, data, expression))
 +            {
 +                std::string localip = "";
@@ -196,7 +261,8 @@
 +                std::string remoteip = "";
 +                std::string remoteport = "";
 +                std::string statedata = "";
-+
+ 
+-            callback(package);
 +                auto localdata{Utils::split(data[6], ':')};
 +                auto remotedata{Utils::split(data[7], ':')};
 +
@@ -249,22 +315,18 @@
 +    }
 +#endif
 +    return ports;
- }
- 
--void SysInfo::getPackages(std::function<void(nlohmann::json&)> callback) const
++}
++
 +void SysInfo::getProcessesInfo(std::function<void(nlohmann::json&)> callback) const
- {
--    const auto query{Utils::exec(R"(pkg query -a "%n|%m|%v|%q|%c")")};
++{
 +    const auto query{Utils::exec(R"(ps -ax -w -o pid,comm,state,ppid,usertime,systime,user,ruser,svuid,group,rgroup,svgid,pri,nice,ssiz,vsz,rss,pmem,etimes,sid,pgid,tpgid,tty,cpu,nlwp,args --libxo json)")};
- 
-     if (!query.empty())
-     {
--        const auto lines{Utils::split(query, '\n')};
++
++    if (!query.empty())
++    {
 +      nlohmann::json psjson;
 +      psjson = nlohmann::json::parse(query);
 +      auto &processes = psjson["process-information"]["process"];
- 
--        for (const auto& line : lines)
++
 +      for(auto &process : processes) {
 +          std::string user_time{""};
 +          std::string system_time{""};
@@ -312,31 +374,15 @@
 +    if (Utils::existsRegular(PKG_DB_PATHNAME))
 +    {
 +        try
-         {
--            const auto data{Utils::split(line, '|')};
--            nlohmann::json package;
++        {
 +            std::shared_ptr<SQLite::IConnection> sqliteConnection = std::make_shared<SQLite::Connection>(PKG_DB_PATHNAME, SQLITE_OPEN_READONLY);
- 
--            package["name"] = data[0];
--            package["vendor"] = data[1];
--            package["version"] = data[2];
--            package["install_time"] = UNKNOWN_VALUE;
--            package["location"] = UNKNOWN_VALUE;
--            package["architecture"] = data[3];
--            package["groups"] = UNKNOWN_VALUE;
--            package["description"] = data[4];
--            package["size"] = 0;
--            package["priority"] = UNKNOWN_VALUE;
--            package["source"] = UNKNOWN_VALUE;
--            package["format"] = "pkg";
--            // The multiarch field won't have a default value
++
 +            SQLite::Statement stmt
 +            {
 +                sqliteConnection,
 +                PKG_QUERY
 +            };
- 
--            callback(package);
++
 +            while (SQLITE_ROW == stmt.step())
 +            {
 +                try
@@ -378,10 +424,11 @@
 +                    std::cerr << e.what() << std::endl;
 +                }
 +            }
-+        }
+         }
 +        catch (const std::exception& e)
 +        {
 +            std::cerr << e.what() << std::endl;
-         }
++        }
      }
  }
+ 
diff --git a/security/wazuh-manager/files/pkg-message.in b/security/wazuh-manager/files/pkg-message.in
index 716a0ad7f809..a87bb5c232ba 100644
--- a/security/wazuh-manager/files/pkg-message.in
+++ b/security/wazuh-manager/files/pkg-message.in
@@ -70,8 +70,12 @@ Wazuh Manager was installed
    script for this task. Download it from the following url:
 
    https://people.freebsd.org/~acm/ports/wazuh/wazuh-gen-certs.tar.gz
+
+10) The sysctl 'kern.hostuuid' is used as a serial number. If you are in a jail,
+    you should have at least started the 'hostid' rc script to uniquely identify
+    this device.
   
-10) Add Wazuh manager to /etc/rc.conf
+11) Add Wazuh manager to /etc/rc.conf
 
   # sysrc wazuh_manager_enable="YES"
 
@@ -79,11 +83,11 @@ Wazuh Manager was installed
   
   # service wazuh-manager enable
 
-11) Start Wazuh manager
+12) Start Wazuh manager
 
   # service wazuh-manager start
 
-12) Enjoy it ;)
+13) Enjoy it ;)
 EOM
 }
 ]


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?695da102.32a56.4df718b3>