This is an automated email from the ASF dual-hosted git repository.

szaszm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git

commit dc3239dbf34c3a8beb65f52ea6ebf271b358d67a
Author: Adam Debreceni <[email protected]>
AuthorDate: Tue Aug 8 13:26:16 2023 +0200

    MINIFICPP-2143 Resolve Security/UserID attribute
    
    Closes #1601
    
    Signed-off-by: Marton Szasz <[email protected]>
---
 .../tests/ConsumeWindowsEventLogTests.cpp          |  4 +-
 .../tests/MetadataWalkerTests.cpp                  | 15 +++++++
 .../tests/resources/invalidxml.xml                 |  2 +-
 .../tests/resources/multiplesids.xml               |  2 +-
 .../tests/resources/nobodysid.xml                  |  2 +-
 .../windows-event-log/tests/resources/nodata.xml   |  2 +-
 .../resources/{withsids.xml => resolveduserid.xml} |  4 +-
 .../tests/resources/unknownsid.xml                 |  2 +-
 .../tests/resources/{nobodysid.xml => userid.xml}  |  4 +-
 .../windows-event-log/tests/resources/withsids.xml |  2 +-
 extensions/windows-event-log/wel/JSONUtils.cpp     |  6 +++
 .../windows-event-log/wel/MetadataWalker.cpp       | 48 ++++++++++++++++------
 extensions/windows-event-log/wel/MetadataWalker.h  |  7 +++-
 13 files changed, 74 insertions(+), 26 deletions(-)

diff --git a/extensions/windows-event-log/tests/ConsumeWindowsEventLogTests.cpp 
b/extensions/windows-event-log/tests/ConsumeWindowsEventLogTests.cpp
index 285d0abd8..b0dfd1d42 100644
--- a/extensions/windows-event-log/tests/ConsumeWindowsEventLogTests.cpp
+++ b/extensions/windows-event-log/tests/ConsumeWindowsEventLogTests.cpp
@@ -539,12 +539,12 @@ TEST_CASE("ConsumeWindowsEventLog Simple JSON works with 
UserData", "[cwel][json
   REQUIRE(doc.load_string(event_xml));
   SECTION("simple") {
     const auto simple_json = jsonToString(toSimpleJSON(doc));
-    const auto expected_json = 
R"json({"System":{"Provider":{"Name":"Microsoft-Windows-AppLocker","Guid":"CBDA4DBF-8D5D-4F69-9578-BE14AA540D22"},"EventID":"8002","Version":"0","Level":"4","Task":"0","Opcode":"0","Keywords":"0x8000000000000000","TimeCreated":{"SystemTime":"2023-02-06T16:58:09.008534Z"},"EventRecordID":"46","Correlation":{},"Execution":{"ProcessID":"1234","ThreadID":"1235"},"Channel":"Microsoft-Windows-AppLocker/EXE
 and DLL","Computer":"example.local"},"EventData":[],"User [...]
+    const auto expected_json = 
R"json({"System":{"Provider":{"Name":"Microsoft-Windows-AppLocker","Guid":"CBDA4DBF-8D5D-4F69-9578-BE14AA540D22"},"EventID":"8002","Version":"0","Level":"4","Task":"0","Opcode":"0","Keywords":"0x8000000000000000","TimeCreated":{"SystemTime":"2023-02-06T16:58:09.008534Z"},"EventRecordID":"46","Correlation":{},"Execution":{"ProcessID":"1234","ThreadID":"1235"},"Channel":"Microsoft-Windows-AppLocker/EXE
 and DLL","Computer":"example.local","Security":{"UserID": [...]
     CHECK(expected_json == simple_json);
   }
   SECTION("flattened") {
     const auto flattened_json = jsonToString(toFlattenedJSON(doc));
-    const auto expected_json = 
R"json({"Name":"Microsoft-Windows-AppLocker","Guid":"CBDA4DBF-8D5D-4F69-9578-BE14AA540D22","EventID":"8002","Version":"0","Level":"4","Task":"0","Opcode":"0","Keywords":"0x8000000000000000","SystemTime":"2023-02-06T16:58:09.008534Z","EventRecordID":"46","ProcessID":"1234","ThreadID":"1235","Channel":"Microsoft-Windows-AppLocker/EXE
 and 
DLL","Computer":"example.local","UserData.RuleAndFileData.PolicyNameLength":"3","UserData.RuleAndFileData.PolicyName":"EXE"
 [...]
+    const auto expected_json = 
R"json({"Name":"Microsoft-Windows-AppLocker","Guid":"CBDA4DBF-8D5D-4F69-9578-BE14AA540D22","EventID":"8002","Version":"0","Level":"4","Task":"0","Opcode":"0","Keywords":"0x8000000000000000","SystemTime":"2023-02-06T16:58:09.008534Z","EventRecordID":"46","ProcessID":"1234","ThreadID":"1235","Channel":"Microsoft-Windows-AppLocker/EXE
 and 
DLL","Computer":"example.local","UserID":"S-1-1-0","UserData.RuleAndFileData.PolicyNameLength":"3","UserData.RuleAndFileDat
 [...]
     CHECK(expected_json == flattened_json);
   }
 }
diff --git a/extensions/windows-event-log/tests/MetadataWalkerTests.cpp 
b/extensions/windows-event-log/tests/MetadataWalkerTests.cpp
index 4dec8a544..796a8c252 100644
--- a/extensions/windows-event-log/tests/MetadataWalkerTests.cpp
+++ b/extensions/windows-event-log/tests/MetadataWalkerTests.cpp
@@ -95,6 +95,21 @@ TEST_CASE("MetadataWalker updates the Sid in the XML if both 
update_xml and reso
   }
 }
 
+
+TEST_CASE("MetadataWalker updates the Security/UserId attribute", 
"[updateXmlMetadata][userid]") {
+  std::string xml = readFile("resources/userid.xml");
+
+  SECTION("No resolution") {
+    REQUIRE(updateXmlMetadata(xml, nullptr, nullptr, false, true) == 
formatXml(xml));
+  }
+
+  SECTION("Resolve nobody") {
+    std::string nobody = readFile("resources/resolveduserid.xml");
+    auto regex = utils::Regex("(.*Sid)|UserID");
+    REQUIRE(updateXmlMetadata(xml, nullptr, nullptr, true, true, &regex) == 
formatXml(nobody));
+  }
+}
+
 TEST_CASE("MetadataWalker works even when there is no Data block", 
"[updateXmlMetadata]") {
   std::string xml = readFile("resources/nodata.xml");
 
diff --git a/extensions/windows-event-log/tests/resources/invalidxml.xml 
b/extensions/windows-event-log/tests/resources/invalidxml.xml
index dbcba62f9..f30f8f5ec 100644
--- a/extensions/windows-event-log/tests/resources/invalidxml.xml
+++ b/extensions/windows-event-log/tests/resources/invalidxml.xml
@@ -14,4 +14,4 @@
   <Execution ProcessID="840" ThreadID="11544" /> 
   <Channel>Security</Channel> 
   <Computer>TestComputer</Computer> 
-  <Security /> >>>>>
\ No newline at end of file
+  <Security /> >>>>>
diff --git a/extensions/windows-event-log/tests/resources/multiplesids.xml 
b/extensions/windows-event-log/tests/resources/multiplesids.xml
index b5c35b56c..8afdeaffd 100644
--- a/extensions/windows-event-log/tests/resources/multiplesids.xml
+++ b/extensions/windows-event-log/tests/resources/multiplesids.xml
@@ -21,4 +21,4 @@
   <Data Name="PrivilegeList">SeAssignPrimaryTokenPrivilege SeTcbPrivilege 
SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege 
SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege 
SeSystemEnvironmentPrivilege SeImpersonatePrivilege 
SeDelegateSessionUserImpersonatePrivilege</Data>
    <Data Name="GroupMembership">%{S-1-0-0} %{S-1-1-0} %{S-1-0}</Data>
  </EventData>
-  </Event>
\ No newline at end of file
+  </Event>
diff --git a/extensions/windows-event-log/tests/resources/nobodysid.xml 
b/extensions/windows-event-log/tests/resources/nobodysid.xml
index a248989f3..b25e124fa 100644
--- a/extensions/windows-event-log/tests/resources/nobodysid.xml
+++ b/extensions/windows-event-log/tests/resources/nobodysid.xml
@@ -20,4 +20,4 @@
   <Data Name="SubjectUserSid">S-1-0-0</Data> 
   <Data Name="PrivilegeList">SeAssignPrimaryTokenPrivilege SeTcbPrivilege 
SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege 
SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege 
SeSystemEnvironmentPrivilege SeImpersonatePrivilege 
SeDelegateSessionUserImpersonatePrivilege</Data> 
   </EventData>
-  </Event>
\ No newline at end of file
+  </Event>
diff --git a/extensions/windows-event-log/tests/resources/nodata.xml 
b/extensions/windows-event-log/tests/resources/nodata.xml
index 790580baa..d3484fe08 100644
--- a/extensions/windows-event-log/tests/resources/nodata.xml
+++ b/extensions/windows-event-log/tests/resources/nodata.xml
@@ -16,4 +16,4 @@
   <Computer>TestComputer</Computer> 
   <Security /> 
   </System>
-  </Event>
\ No newline at end of file
+  </Event>
diff --git a/extensions/windows-event-log/tests/resources/withsids.xml 
b/extensions/windows-event-log/tests/resources/resolveduserid.xml
similarity index 96%
copy from extensions/windows-event-log/tests/resources/withsids.xml
copy to extensions/windows-event-log/tests/resources/resolveduserid.xml
index 29d33230d..2f626ba4f 100644
--- a/extensions/windows-event-log/tests/resources/withsids.xml
+++ b/extensions/windows-event-log/tests/resources/resolveduserid.xml
@@ -14,10 +14,10 @@
   <Execution ProcessID="840" ThreadID="11544" /> 
   <Channel>Security</Channel> 
   <Computer>TestComputer</Computer> 
-  <Security /> 
+  <Security UserID="Nobody"/> 
   </System>
  <EventData>
   <Data Name="SubjectUserSid">Nobody</Data> 
   <Data Name="PrivilegeList">SeAssignPrimaryTokenPrivilege SeTcbPrivilege 
SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege 
SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege 
SeSystemEnvironmentPrivilege SeImpersonatePrivilege 
SeDelegateSessionUserImpersonatePrivilege</Data> 
   </EventData>
-  </Event>
\ No newline at end of file
+  </Event>
diff --git a/extensions/windows-event-log/tests/resources/unknownsid.xml 
b/extensions/windows-event-log/tests/resources/unknownsid.xml
index 169944ed9..02b16da05 100644
--- a/extensions/windows-event-log/tests/resources/unknownsid.xml
+++ b/extensions/windows-event-log/tests/resources/unknownsid.xml
@@ -20,4 +20,4 @@
   <Data Name="SubjectUserSid">S-1-8-6-5-3-0-9</Data> 
   <Data Name="PrivilegeList">SeAssignPrimaryTokenPrivilege SeTcbPrivilege 
SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege 
SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege 
SeSystemEnvironmentPrivilege SeImpersonatePrivilege 
SeDelegateSessionUserImpersonatePrivilege</Data> 
   </EventData>
-  </Event>
\ No newline at end of file
+  </Event>
diff --git a/extensions/windows-event-log/tests/resources/nobodysid.xml 
b/extensions/windows-event-log/tests/resources/userid.xml
similarity index 96%
copy from extensions/windows-event-log/tests/resources/nobodysid.xml
copy to extensions/windows-event-log/tests/resources/userid.xml
index a248989f3..06a03257d 100644
--- a/extensions/windows-event-log/tests/resources/nobodysid.xml
+++ b/extensions/windows-event-log/tests/resources/userid.xml
@@ -14,10 +14,10 @@
   <Execution ProcessID="840" ThreadID="11544" /> 
   <Channel>Security</Channel> 
   <Computer>TestComputer</Computer> 
-  <Security /> 
+  <Security UserID="S-1-0-0"/> 
   </System>
  <EventData>
   <Data Name="SubjectUserSid">S-1-0-0</Data> 
   <Data Name="PrivilegeList">SeAssignPrimaryTokenPrivilege SeTcbPrivilege 
SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege 
SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege 
SeSystemEnvironmentPrivilege SeImpersonatePrivilege 
SeDelegateSessionUserImpersonatePrivilege</Data> 
   </EventData>
-  </Event>
\ No newline at end of file
+  </Event>
diff --git a/extensions/windows-event-log/tests/resources/withsids.xml 
b/extensions/windows-event-log/tests/resources/withsids.xml
index 29d33230d..88babbd5d 100644
--- a/extensions/windows-event-log/tests/resources/withsids.xml
+++ b/extensions/windows-event-log/tests/resources/withsids.xml
@@ -20,4 +20,4 @@
   <Data Name="SubjectUserSid">Nobody</Data> 
   <Data Name="PrivilegeList">SeAssignPrimaryTokenPrivilege SeTcbPrivilege 
SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege 
SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege 
SeSystemEnvironmentPrivilege SeImpersonatePrivilege 
SeDelegateSessionUserImpersonatePrivilege</Data> 
   </EventData>
-  </Event>
\ No newline at end of file
+  </Event>
diff --git a/extensions/windows-event-log/wel/JSONUtils.cpp 
b/extensions/windows-event-log/wel/JSONUtils.cpp
index 0f2913d62..107d47571 100644
--- a/extensions/windows-event-log/wel/JSONUtils.cpp
+++ b/extensions/windows-event-log/wel/JSONUtils.cpp
@@ -154,6 +154,12 @@ rapidjson::Document toJSONImpl(const pugi::xml_node& root, 
bool flatten) {
 
     system.AddMember("Channel", 
rapidjson::StringRef(system_xml.child("Channel").text().get()), 
doc.GetAllocator());
     system.AddMember("Computer", 
rapidjson::StringRef(system_xml.child("Computer").text().get()), 
doc.GetAllocator());
+
+    {
+      auto security_xml = system_xml.child("Security");
+      auto& security = flatten ? doc : system.AddMember("Security", 
rapidjson::kObjectType, doc.GetAllocator())["Security"];
+      security.AddMember("UserID", 
rapidjson::StringRef(security_xml.attribute("UserID").value()), 
doc.GetAllocator());
+    }
   }
 
   {
diff --git a/extensions/windows-event-log/wel/MetadataWalker.cpp 
b/extensions/windows-event-log/wel/MetadataWalker.cpp
index 2181db17c..11c2fc75c 100644
--- a/extensions/windows-event-log/wel/MetadataWalker.cpp
+++ b/extensions/windows-event-log/wel/MetadataWalker.cpp
@@ -33,20 +33,25 @@ namespace org::apache::nifi::minifi::wel {
 
 bool MetadataWalker::for_each(pugi::xml_node &node) {
   // don't shortcut resolution here so that we can log attributes.
+  const auto idUpdate = [&](const std::string &input) {
+    if (resolve_) {
+      auto resolved = user_id_to_username_fn_(input);
+      replaced_identifiers_[input] = resolved;
+      return resolved;
+    }
+
+    replaced_identifiers_[input] = input;
+    return input;
+  };
+  for (pugi::xml_attribute attr : node.attributes())  {
+    if (regex_ && utils::regexMatch(attr.name(), *regex_)) {
+      updateAttributeValue(attr, attr.name(), idUpdate);
+    }
+  }
+
   const std::string node_name = node.name();
   if (node_name == "Data") {
     for (pugi::xml_attribute attr : node.attributes())  {
-      const auto idUpdate = [&](const std::string &input) {
-        if (resolve_) {
-          auto resolved = user_id_to_username_fn_(input);
-          replaced_identifiers_[input] = resolved;
-          return resolved;
-        }
-
-        replaced_identifiers_[input] = input;
-        return input;
-      };
-
       if (regex_ && utils::regexMatch(attr.name(), *regex_)) {
         updateText(node, attr.name(), idUpdate);
       }
@@ -158,9 +163,11 @@ std::string MetadataWalker::to_string(const wchar_t* 
pChar) {
   return std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(pChar);
 }
 
-void MetadataWalker::updateText(pugi::xml_node &node, const std::string 
&field_name, std::function<std::string(const std::string &)> &&fn) {
+template<typename Fn>
+requires std::is_convertible_v<std::invoke_result_t<Fn, std::string>, 
std::string>
+void MetadataWalker::updateText(pugi::xml_node &node, const std::string 
&field_name, Fn &&fn) {
   std::string previous_value = node.text().get();
-  auto new_field_value = fn(previous_value);
+  auto new_field_value = std::invoke(std::forward<Fn>(fn), previous_value);
   if (new_field_value != previous_value) {
     metadata_[field_name] = new_field_value;
     if (update_xml_) {
@@ -171,4 +178,19 @@ void MetadataWalker::updateText(pugi::xml_node &node, 
const std::string &field_n
   }
 }
 
+template<typename Fn>
+requires std::is_convertible_v<std::invoke_result_t<Fn, std::string>, 
std::string>
+void MetadataWalker::updateAttributeValue(pugi::xml_attribute &attr, const 
std::string &field_name, Fn &&fn) {
+  std::string previous_value = attr.value();
+  auto new_field_value = std::invoke(std::forward<Fn>(fn), previous_value);
+  if (new_field_value != previous_value) {
+    metadata_[field_name] = new_field_value;
+    if (update_xml_) {
+      attr.set_value(new_field_value.c_str());
+    } else {
+      fields_values_[field_name] = new_field_value;
+    }
+  }
+}
+
 }  // namespace org::apache::nifi::minifi::wel
diff --git a/extensions/windows-event-log/wel/MetadataWalker.h 
b/extensions/windows-event-log/wel/MetadataWalker.h
index a2d949338..869e254f1 100644
--- a/extensions/windows-event-log/wel/MetadataWalker.h
+++ b/extensions/windows-event-log/wel/MetadataWalker.h
@@ -87,7 +87,12 @@ class MetadataWalker : public pugi::xml_tree_walker {
   /**
    * Updates text within the XML representation
    */
-  void updateText(pugi::xml_node &node, const std::string &field_name, 
std::function<std::string(const std::string &)> &&fn);
+  template<typename Fn>
+  requires std::is_convertible_v<std::invoke_result_t<Fn, std::string>, 
std::string>
+  void updateText(pugi::xml_node &node, const std::string &field_name, Fn 
&&fn);
+  template<typename Fn>
+  requires std::is_convertible_v<std::invoke_result_t<Fn, std::string>, 
std::string>
+  void updateAttributeValue(pugi::xml_attribute &node, const std::string 
&field_name, Fn &&fn);
 
   const WindowsEventLogMetadata& windows_event_log_metadata_;
   const std::string log_name_;

Reply via email to