From 21a55bc221565787bccbb8baa3c572ac8a31a6ba Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Mon, 13 Nov 2023 07:42:01 -0700 Subject: [PATCH 1/4] add protocols, update snmp4j version --- .../java/us/dot/its/jpo/ode/snmp/SNMPTest.java | 2 +- .../main/java/us/dot/its/jpo/ode/plugin/SNMP.java | 15 +++++++++++++++ jpo-ode-svcs/pom.xml | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/snmp/SNMPTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/snmp/SNMPTest.java index 2642da264..383cb9995 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/snmp/SNMPTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/snmp/SNMPTest.java @@ -74,6 +74,6 @@ public void testGettersAndSetters() { @Test public void testSnmpTimestampFromIso() throws ParseException { String snmpTS = SNMP.snmpTimestampFromIso("2017-05-04T21:55:00-05:00"); - assertEquals("07E105041537", snmpTS); + assertEquals("07E1050415370000", snmpTS); } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/SNMP.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/SNMP.java index 05470cf22..9c2c5fd66 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/SNMP.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/SNMP.java @@ -127,6 +127,21 @@ public void setStatus(int status) { public static String snmpTimestampFromIso(String isoTimestamp) throws ParseException { ZonedDateTime zdt = DateTimeUtils.isoDateTime(isoTimestamp); + + StringBuilder sb = new StringBuilder(); + + sb.append(String.format("%04X", zdt.getYear())); + sb.append(String.format("%02X", zdt.getMonthValue())); + sb.append(String.format("%02X", zdt.getDayOfMonth())); + sb.append(String.format("%02X", zdt.getHour())); + sb.append(String.format("%02X", zdt.getMinute())); + sb.append(String.format("%02X", zdt.getSecond())); + sb.append(String.format("%02X", zdt.getNano())); + return sb.toString(); + } + + public static String fourOneSnmpTimestampFromIso(String isoTimestamp) throws ParseException { + ZonedDateTime zdt = DateTimeUtils.isoDateTime(isoTimestamp); StringBuilder sb = new StringBuilder(); sb.append(String.format("%04X", zdt.getYear())); diff --git a/jpo-ode-svcs/pom.xml b/jpo-ode-svcs/pom.xml index d108e764a..65c2df698 100644 --- a/jpo-ode-svcs/pom.xml +++ b/jpo-ode-svcs/pom.xml @@ -115,7 +115,7 @@ org.snmp4j snmp4j - 3.4.4 + 3.7.7 From e1e6e751fbdefdecdc5d3bb60aceded0ffb9cf03 Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Mon, 13 Nov 2023 07:42:32 -0700 Subject: [PATCH 2/4] update fourdot1 and snmp1218 pdu creation --- .../us/dot/its/jpo/ode/OdeSvcsApplication.java | 14 ++++++++++++++ .../dot/its/jpo/ode/snmp/SnmpFourDot1Protocol.java | 4 ++-- .../its/jpo/ode/snmp/SnmpNTCIP1218Protocol.java | 3 ++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java index 5515f53aa..7b41d7640 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java @@ -27,6 +27,14 @@ import org.snmp4j.security.AuthMD5; import org.snmp4j.security.AuthSHA; +import org.snmp4j.security.AuthHMAC128SHA224; +import org.snmp4j.security.AuthHMAC192SHA256; +import org.snmp4j.security.AuthHMAC256SHA384; +import org.snmp4j.security.AuthHMAC384SHA512; +import org.snmp4j.security.PrivAES128; +import org.snmp4j.security.PrivAES192; +import org.snmp4j.security.PrivAES256; + import org.snmp4j.security.SecurityProtocols; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; @@ -50,7 +58,13 @@ public static void main(String[] args) throws MalformedObjectNameException, Inte mbs.registerMBean(mBean, name); SecurityProtocols.getInstance().addAuthenticationProtocol(new AuthSHA()); + SecurityProtocols.getInstance().addAuthenticationProtocol(new AuthHMAC128SHA224()); + SecurityProtocols.getInstance().addAuthenticationProtocol(new AuthHMAC192SHA256()); + SecurityProtocols.getInstance().addAuthenticationProtocol(new AuthHMAC256SHA384()); + SecurityProtocols.getInstance().addAuthenticationProtocol(new AuthHMAC384SHA512()); SecurityProtocols.getInstance().addAuthenticationProtocol(new AuthMD5()); + SecurityProtocols.getInstance().addPrivacyProtocol(new PrivAES128()); + } @Bean diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpFourDot1Protocol.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpFourDot1Protocol.java index 039a49067..01a5b4c84 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpFourDot1Protocol.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpFourDot1Protocol.java @@ -56,14 +56,14 @@ public static VariableBinding getVbRsuSrmTxInterval(int index, int interval) { public static VariableBinding getVbRsuSrmDeliveryStart(int index, String deliveryStart) throws ParseException { return new VariableBinding( new OID(rsu_srm_delivery_start_oid().concat(".").concat(Integer.toString(index))), - new OctetString(DatatypeConverter.parseHexBinary(SNMP.snmpTimestampFromIso(deliveryStart))) + new OctetString(DatatypeConverter.parseHexBinary(SNMP.fourOneSnmpTimestampFromIso(deliveryStart))) ); } public static VariableBinding getVbRsuSrmDeliveryStop(int index, String deliveryStop) throws ParseException { return new VariableBinding( new OID(rsu_srm_delivery_stop_oid().concat(".").concat(Integer.toString(index))), - new OctetString(DatatypeConverter.parseHexBinary(SNMP.snmpTimestampFromIso(deliveryStop))) + new OctetString(DatatypeConverter.parseHexBinary(SNMP.fourOneSnmpTimestampFromIso(deliveryStop))) ); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpNTCIP1218Protocol.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpNTCIP1218Protocol.java index e72eb72cb..c8f0f486a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpNTCIP1218Protocol.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpNTCIP1218Protocol.java @@ -86,9 +86,10 @@ public static VariableBinding getVbRsuMsgRepeatPriority(int index) { } public static VariableBinding getVbRsuMsgRepeatOptions(int index) { + byte[] val = {(byte) 0xc0}; return new VariableBinding( new OID(rsu_msg_repeat_options_oid().concat(".").concat(Integer.toString(index))), - new OctetString("C0") + new OctetString(val) ); } From dd6eff85ee927118463cd22993b597f585b42ddd Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Mon, 13 Nov 2023 07:42:53 -0700 Subject: [PATCH 3/4] add engineID discovery, snmpsession test update --- .../us/dot/its/jpo/ode/snmp/SnmpSession.java | 19 ++++++++++++++----- .../dot/its/jpo/ode/snmp/SnmpSessionTest.java | 4 ++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpSession.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpSession.java index c32eb2fa4..fdf9cbab9 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpSession.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/snmp/SnmpSession.java @@ -29,6 +29,7 @@ import org.snmp4j.mp.MPv3; import org.snmp4j.mp.SnmpConstants; import org.snmp4j.security.AuthSHA; +import org.snmp4j.security.PrivAES128; import org.snmp4j.security.SecurityLevel; import org.snmp4j.security.SecurityModels; import org.snmp4j.security.SecurityProtocols; @@ -83,7 +84,7 @@ public SnmpSession(RSU rsu) throws IOException { target.setTimeout(rsu.getRsuTimeout()); target.setVersion(SnmpConstants.version3); if (rsu.getRsuUsername() != null) { - target.setSecurityLevel(SecurityLevel.AUTH_NOPRIV); + target.setSecurityLevel(SecurityLevel.AUTH_PRIV); target.setSecurityName(new OctetString(rsu.getRsuUsername())); } else { target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV); @@ -105,7 +106,7 @@ public SnmpSession(RSU rsu) throws IOException { SecurityModels.getInstance().addSecurityModel(usm); if (rsu.getRsuUsername() != null) { snmp.getUSM().addUser(new OctetString(rsu.getRsuUsername()), new UsmUser(new OctetString(rsu.getRsuUsername()), - AuthSHA.ID, new OctetString(rsu.getRsuPassword()), null, null)); + AuthSHA.ID, new OctetString(rsu.getRsuPassword()), PrivAES128.ID, new OctetString(rsu.getRsuPassword()))); } // Assert the ready flag so the user can begin sending messages @@ -133,9 +134,17 @@ public ResponseEvent set(PDU pdu, Snmp snmpob, UserTarget targetob, Boolean keep // Try to send the SNMP request (synchronously) ResponseEvent responseEvent = null; try { - responseEvent = snmpob.set(pdu, targetob); - if (!keepOpen) { - snmpob.close(); + byte[] authEngineID = snmpob.discoverAuthoritativeEngineID(targetob.getAddress(), 1000); + if (authEngineID != null && authEngineID.length > 0) { + targetob.setAuthoritativeEngineID(authEngineID); + } + if (authEngineID != null) { + responseEvent = snmpob.set(pdu, targetob); + if (!keepOpen) { + snmpob.close(); + } + } else { + logger.error("Unable to send TIM to RSU {}: authEngineID is null", targetob.getAddress()); } } catch (IOException e) { throw new IOException("Failed to send SNMP request: " + e); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/snmp/SnmpSessionTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/snmp/SnmpSessionTest.java index 1a88ff699..845bdf211 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/snmp/SnmpSessionTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/snmp/SnmpSessionTest.java @@ -168,8 +168,8 @@ public void shouldCreatePDUWithFourDot1Protocol() throws ParseException { @Test public void shouldCreatePDUWithNTCIP1218Protocol() throws ParseException { - String expectedResult = "[1.3.6.1.4.1.1206.4.2.18.3.2.1.2.3 = 80:03, 1.3.6.1.4.1.1206.4.2.18.3.2.1.3.3 = 4, 1.3.6.1.4.1.1206.4.2.18.3.2.1.4.3 = 5, 1.3.6.1.4.1.1206.4.2.18.3.2.1.5.3 = 07:e1:0c:02:11:2f, 1.3.6.1.4.1.1206.4.2.18.3.2.1.6.3 = 07:e1:0c:02:11:2f, 1.3.6.1.4.1.1206.4.2.18.3.2.1.7.3 = 88, 1.3.6.1.4.1.1206.4.2.18.3.2.1.8.3 = 9, 1.3.6.1.4.1.1206.4.2.18.3.2.1.9.3 = 10, 1.3.6.1.4.1.1206.4.2.18.3.2.1.10.3 = 6, 1.3.6.1.4.1.1206.4.2.18.3.2.1.11.3 = C0]"; - String expectedResult2 = "[1.3.6.1.4.1.1206.4.2.18.3.2.1.2.3 = 80:03, 1.3.6.1.4.1.1206.4.2.18.3.2.1.3.3 = 4, 1.3.6.1.4.1.1206.4.2.18.3.2.1.4.3 = 5, 1.3.6.1.4.1.1206.4.2.18.3.2.1.5.3 = 07:e1:0c:02:11:2f, 1.3.6.1.4.1.1206.4.2.18.3.2.1.6.3 = 07:e1:0c:02:11:2f, 1.3.6.1.4.1.1206.4.2.18.3.2.1.7.3 = 88, 1.3.6.1.4.1.1206.4.2.18.3.2.1.8.3 = 9, 1.3.6.1.4.1.1206.4.2.18.3.2.1.10.3 = 6, 1.3.6.1.4.1.1206.4.2.18.3.2.1.11.3 = C0]"; + String expectedResult = "[1.3.6.1.4.1.1206.4.2.18.3.2.1.2.3 = 80:03, 1.3.6.1.4.1.1206.4.2.18.3.2.1.3.3 = 4, 1.3.6.1.4.1.1206.4.2.18.3.2.1.4.3 = 5, 1.3.6.1.4.1.1206.4.2.18.3.2.1.5.3 = 07:e1:0c:02:11:2f:0b:00, 1.3.6.1.4.1.1206.4.2.18.3.2.1.6.3 = 07:e1:0c:02:11:2f:0b:00, 1.3.6.1.4.1.1206.4.2.18.3.2.1.7.3 = 88, 1.3.6.1.4.1.1206.4.2.18.3.2.1.8.3 = 9, 1.3.6.1.4.1.1206.4.2.18.3.2.1.9.3 = 10, 1.3.6.1.4.1.1206.4.2.18.3.2.1.10.3 = 6, 1.3.6.1.4.1.1206.4.2.18.3.2.1.11.3 = c0]"; + String expectedResult2 = "[1.3.6.1.4.1.1206.4.2.18.3.2.1.2.3 = 80:03, 1.3.6.1.4.1.1206.4.2.18.3.2.1.3.3 = 4, 1.3.6.1.4.1.1206.4.2.18.3.2.1.4.3 = 5, 1.3.6.1.4.1.1206.4.2.18.3.2.1.5.3 = 07:e1:0c:02:11:2f:0b:00, 1.3.6.1.4.1.1206.4.2.18.3.2.1.6.3 = 07:e1:0c:02:11:2f:0b:00, 1.3.6.1.4.1.1206.4.2.18.3.2.1.7.3 = 88, 1.3.6.1.4.1.1206.4.2.18.3.2.1.8.3 = 9, 1.3.6.1.4.1.1206.4.2.18.3.2.1.10.3 = 6, 1.3.6.1.4.1.1206.4.2.18.3.2.1.11.3 = c0]"; String rsuSRMPsid = "00000083"; int rsuSRMTxChannel = 4; From 3f3eb6566dd324eae8ef936a0af1110da6185969 Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Mon, 13 Nov 2023 07:49:39 -0700 Subject: [PATCH 4/4] remove unused imports --- .../src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java index 7b41d7640..5cd188327 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java @@ -32,8 +32,6 @@ import org.snmp4j.security.AuthHMAC256SHA384; import org.snmp4j.security.AuthHMAC384SHA512; import org.snmp4j.security.PrivAES128; -import org.snmp4j.security.PrivAES192; -import org.snmp4j.security.PrivAES256; import org.snmp4j.security.SecurityProtocols; import org.springframework.boot.CommandLineRunner;