From 357256449f90694b1f2a9003f50d1297a222db60 Mon Sep 17 00:00:00 2001 From: dan-s1 Date: Wed, 13 May 2026 17:49:26 +0000 Subject: [PATCH 1/3] NIFI-15928 Added support for the localizationEngineID in UsmUserDeserializer --- .../org/apache/nifi/snmp/utils/UsmUserDeserializer.java | 9 ++++++++- .../org/apache/nifi/snmp/utils/JsonUsmReaderTest.java | 3 +-- .../apache/nifi/snmp/utils/JsonUsmReaderTestBase.java | 7 +++++-- .../src/test/resources/usm_users.json | 6 ++++-- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/UsmUserDeserializer.java b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/UsmUserDeserializer.java index 779084a82d27..6cfdce04a777 100644 --- a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/UsmUserDeserializer.java +++ b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/UsmUserDeserializer.java @@ -73,12 +73,19 @@ public UsmUser deserialize(JsonParser jp, DeserializationContext ctxt) throws IO "authentication protocol is specified."); } + OctetString localizationEngineID = null; + final JsonNode localizationEngineIDNode = node.get("localizationEngineID"); + if (localizationEngineIDNode != null) { + localizationEngineID = new OctetString(localizationEngineIDNode.asText()); + } + return new UsmUser( new OctetString(securityName), authProtocol, authPassphrase, privProtocol, - privPassphrase + privPassphrase, + localizationEngineID ); } } diff --git a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTest.java b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTest.java index 955efe6f5ec2..b80f732b1ac6 100644 --- a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTest.java +++ b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTest.java @@ -56,8 +56,7 @@ void testReadInvalidJsonThrowsException() { } static String readFile(String path) throws IOException { - byte[] encoded = Files.readAllBytes(Paths.get(path)); - return new String(encoded, StandardCharsets.UTF_8); + return Files.readString(Paths.get(path), StandardCharsets.UTF_8); } } diff --git a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTestBase.java b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTestBase.java index 8dc5362c8677..039c601e28df 100644 --- a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTestBase.java +++ b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTestBase.java @@ -39,14 +39,17 @@ public class JsonUsmReaderTestBase { new OID("1.3.6.1.6.3.10.1.1.7"), new OctetString("abc12345"), new OID("1.3.6.1.4.1.4976.2.2.1.1.1"), - new OctetString("abc12345") + new OctetString("abc12345"), + new OctetString("8000000001020304") + )); expectedUsmUsers.add(new UsmUser( new OctetString("user2"), new OID("1.3.6.1.6.3.10.1.1.5"), new OctetString("abc12345"), new OID("1.3.6.1.4.1.4976.2.2.1.1.2"), - new OctetString("abc12345") + new OctetString("abc12345"), + new OctetString("8000000001020308") )); } diff --git a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/usm_users.json b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/usm_users.json index c93257b6d640..9882663bf8a5 100644 --- a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/usm_users.json +++ b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/usm_users.json @@ -4,13 +4,15 @@ "authProtocol":"HMAC384SHA512", "authPassphrase":"abc12345", "privProtocol":"AES192", - "privPassphrase":"abc12345" + "privPassphrase":"abc12345", + "localizationEngineID":"8000000001020304" }, { "securityName":"user2", "authProtocol":"HMAC192SHA256", "authPassphrase":"abc12345", "privProtocol":"AES256", - "privPassphrase":"abc12345" + "privPassphrase":"abc12345", + "localizationEngineID":"8000000001020308" } ] \ No newline at end of file From 9ae82059f009eac14fe9410b03189f1d9e4870c7 Mon Sep 17 00:00:00 2001 From: dan-s1 Date: Fri, 15 May 2026 15:57:03 +0000 Subject: [PATCH 2/3] NIFI-15928 Added logic for localizationEngineID to be hex decoded and added documentation indicating how users can be configured with or without a localizationEngineID and whether the localizationEngineID has a delimiter or not. --- .../nifi/snmp/utils/UsmUserDeserializer.java | 6 +++++- .../additionalDetails.md | 13 +++++++++++-- .../operations/SNMPTrapReceiverHandlerTest.java | 2 +- .../nifi/snmp/utils/JsonUsmReaderTestBase.java | 14 +++++++++++--- .../src/test/resources/usm_users.json | 13 ++++++++++--- 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/UsmUserDeserializer.java b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/UsmUserDeserializer.java index 6cfdce04a777..1296ba55bab8 100644 --- a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/UsmUserDeserializer.java +++ b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/java/org/apache/nifi/snmp/utils/UsmUserDeserializer.java @@ -76,7 +76,11 @@ public UsmUser deserialize(JsonParser jp, DeserializationContext ctxt) throws IO OctetString localizationEngineID = null; final JsonNode localizationEngineIDNode = node.get("localizationEngineID"); if (localizationEngineIDNode != null) { - localizationEngineID = new OctetString(localizationEngineIDNode.asText()); + if (localizationEngineIDNode.asText().contains(":")) { + localizationEngineID = OctetString.fromHexString(localizationEngineIDNode.asText()); + } else { + localizationEngineID = OctetString.fromHexStringPairs(localizationEngineIDNode.asText()); + } } return new UsmUser( diff --git a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.md b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.md index 9a58ef2fe14c..833c406150bc 100644 --- a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.md +++ b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.md @@ -21,7 +21,7 @@ The ListenTrapSNMP processor listens for incoming SNMP traps and generates a Flo When configured to use SNMPv3, SNMPv1 and SNMPv2c are automatically disabled. As a result, traps using SNMPv1 or SNMPv2c message models will not be received or processed. This is done to enforce a higher level of security, as SNMPv1 and SNMPv2c transmit community strings in plaintext, making them vulnerable to interception and unauthorized access. -For SNMPv3, security is based on a User-Based Security Model (USM). The 'USM Users Input Method' property allows users to configure the USM user database in different ways. Below is an example JSON file defining two users as "Json Content": +For SNMPv3, security is based on a User-Based Security Model (USM). The 'USM Users Input Method' property allows users to configure the USM user database in different ways. Below is an example JSON file defining three users as "Json Content": ```json [ @@ -37,7 +37,16 @@ For SNMPv3, security is based on a User-Based Security Model (USM). The 'USM Use "authProtocol": "HMAC192SHA256", "authPassphrase": "authPassphrase2", "privProtocol": "AES256", - "privPassphrase": "privPassphrase2" + "privPassphrase": "privPassphrase2", + "localizationEngineID":"00:0A:95:9D:68:16" + }, + { + "securityName":"user3", + "authProtocol":"HMAC384SHA512", + "authPassphrase":"authPassphrase3", + "privProtocol":"AES256", + "privPassphrase":"privPassphrase3", + "localizationEngineID":"08A69E" } ] diff --git a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPTrapReceiverHandlerTest.java b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPTrapReceiverHandlerTest.java index 0b9fe21aae1b..07bee38b7959 100644 --- a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPTrapReceiverHandlerTest.java +++ b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/operations/SNMPTrapReceiverHandlerTest.java @@ -99,7 +99,7 @@ void testAddUsmUsers() { trapReceiverHandler.setSnmpManager(mockSnmpManager); trapReceiverHandler.createTrapReceiver(null, null); - verify(mockSnmpManager.getUSM(), times(2)).addUser(usmUserCaptor.capture()); + verify(mockSnmpManager.getUSM(), times(3)).addUser(usmUserCaptor.capture()); verify(mockSnmpManager).addCommandResponder(any(SNMPTrapReceiver.class)); assertTrue(trapReceiverHandler.isStarted()); diff --git a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTestBase.java b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTestBase.java index 039c601e28df..f34f12dac67a 100644 --- a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTestBase.java +++ b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/java/org/apache/nifi/snmp/utils/JsonUsmReaderTestBase.java @@ -31,6 +31,7 @@ public class JsonUsmReaderTestBase { public static final String LEGACY_USERS_JSON_PATH = "src/test/resources/invalid_usm_user_legacy_protocol.json"; static final List expectedUsmUsers; + private static final OctetString EMPTY_LOCALIZATION_ENGINE_ID = null; static { expectedUsmUsers = new ArrayList<>(); @@ -40,7 +41,7 @@ public class JsonUsmReaderTestBase { new OctetString("abc12345"), new OID("1.3.6.1.4.1.4976.2.2.1.1.1"), new OctetString("abc12345"), - new OctetString("8000000001020304") + EMPTY_LOCALIZATION_ENGINE_ID )); expectedUsmUsers.add(new UsmUser( @@ -49,8 +50,15 @@ public class JsonUsmReaderTestBase { new OctetString("abc12345"), new OID("1.3.6.1.4.1.4976.2.2.1.1.2"), new OctetString("abc12345"), - new OctetString("8000000001020308") + OctetString.fromHexString("00:0A:95:9D:68:16") + )); + expectedUsmUsers.add(new UsmUser( + new OctetString("user3"), + new OID("1.3.6.1.6.3.10.1.1.7"), + new OctetString("abc12345"), + new OID("1.3.6.1.4.1.4976.2.2.1.1.2"), + new OctetString("abc12345"), + OctetString.fromHexStringPairs("08A69E") )); } - } diff --git a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/usm_users.json b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/usm_users.json index 9882663bf8a5..2ab3cb58b642 100644 --- a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/usm_users.json +++ b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/test/resources/usm_users.json @@ -4,8 +4,7 @@ "authProtocol":"HMAC384SHA512", "authPassphrase":"abc12345", "privProtocol":"AES192", - "privPassphrase":"abc12345", - "localizationEngineID":"8000000001020304" + "privPassphrase":"abc12345" }, { "securityName":"user2", @@ -13,6 +12,14 @@ "authPassphrase":"abc12345", "privProtocol":"AES256", "privPassphrase":"abc12345", - "localizationEngineID":"8000000001020308" + "localizationEngineID":"00:0A:95:9D:68:16" + }, + { + "securityName":"user3", + "authProtocol":"HMAC384SHA512", + "authPassphrase":"abc12345", + "privProtocol":"AES256", + "privPassphrase":"abc12345", + "localizationEngineID":"08A69E" } ] \ No newline at end of file From 60b1350bb099da0014591f1fd2f96367e0b44f79 Mon Sep 17 00:00:00 2001 From: dan-s1 Date: Fri, 15 May 2026 16:39:22 +0000 Subject: [PATCH 3/3] NIFI-15928 Added more details about the localizationEngineID in the documentation. --- .../additionalDetails.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.md b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.md index 833c406150bc..3988d647d50c 100644 --- a/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.md +++ b/nifi-extension-bundles/nifi-snmp-bundle/nifi-snmp-processors/src/main/resources/docs/org.apache.nifi.snmp.processors.ListenTrapSNMP/additionalDetails.md @@ -50,4 +50,5 @@ For SNMPv3, security is based on a User-Based Security Model (USM). The 'USM Use } ] -``` \ No newline at end of file +``` +**NOTE:** `localizationEngineID` is not required, but if specified it must be a hex string either with or without colon delimiters. \ No newline at end of file