SNMPv3 Diffie-hellman Dispatching message canceled

Hello!

I’m trying to create an SNMP listener that will simulate a cable modem and handle the SNMPv3 diffie-hellman exchange. I have a separate software that is sending the snmpv3 request, that I’ve tested against a physical cable modem and that seems to work, however when I send the request to my listener it seems to not enter my processPDU method and instead returns the OIDs the software is requesting with a null value.

This is what I have for my listener + the beginning of my processPdu

public synchronized void listen(TransportIpAddress address, int numberOfDispatcher) throws IOException {

AbstractTransportMapping transport;
if (threadPool != null) {
Log.info(“Threadpool for listener is already active”);
return;
}

if (address instanceof TcpAddress) {
transport = new DefaultTcpTransportMapping((TcpAddress) address);
} else {
transport = new DefaultUdpTransportMapping((UdpAddress) address);
}

OctetString dhKickstart = new OctetString(“dhKickstart”);

threadPool = ThreadPool.create(“DispatcherPool”, numberOfDispatcher);
MessageDispatcher mtDispatcher = new MultiThreadedMessageDispatcher(threadPool, new MessageDispatcherImpl());

// add all security protocols
SecurityProtocols.getInstance().addDefaultProtocols();
SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());
SecurityProtocols.getInstance().addAuthenticationProtocol(new AuthMD5());

// SnmpV3 Configuration
OctetString engineId = new OctetString(MPv3.createLocalEngineID());

USM usm = new USM(SecurityProtocols.getInstance(), engineId, 0);

usm.addLocalizedUser(engineId.getValue(), dhKickstart, SnmpConstants.usmNoAuthProtocol, null, SnmpConstants.usmNoPrivProtocol, null);

OctetString securityName = new OctetString(CONFIG.getSnmpUsername());

UsmUserEntry entry = usm.addLocalizedUser(engineId.getValue(), securityName, AuthMD5.ID, CONFIG.getSnmpAuthKey().getBytes(), PrivDES.ID, CONFIG.getSnmpPrivKey().getBytes());

// add message processing models
mtDispatcher.addMessageProcessingModel(new MPv1());
mtDispatcher.addMessageProcessingModel(new MPv2c());
mtDispatcher.addMessageProcessingModel(new MPv3(usm));

snmp = new Snmp(mtDispatcher, transport);
snmp.addCommandResponder(this);
snmp.listen();

Log.info("Listening on " + address);
}

public synchronized void processPdu(CommandResponderEvent cmdRespEvent) {
Log.debug(“Received PDU…”);

}

What I’m getting from the debug logs

2020-01-22 15:23:28 [INFO] Current working directory: /home/mhinton/git/firmwaretest
2020-01-22 15:23:29.381 main DEBUG Initialized Salt to fc7c4f16487aaced.
2020-01-22 15:23:29.432 main DEBUG Adding user dhKickstart = UsmUser[secName=dhKickstart,authProtocol=1.3.6.1.6.3.10.1.1.1,authPassphrase=null,privProtocol=1.3.6.1.6.3.10.1.2.1,privPassphrase=null,localizationEngineID=80:00:13:70:01:7f:00:01:01:cc:8a:b2:67]
2020-01-22 15:23:29.439 main DEBUG Adding user docsisManager = UsmUser[secName=docsisManager,authProtocol=1.3.6.1.6.3.10.1.1.2,authPassphrase=00B47671A32B43A7487EC540B5C3DFAF1F,privProtocol=1.3.6.1.6.3.10.1.2.2,privPassphrase=00B47671A32B43A7487EC540B5C3DFAF1F,localizationEngineID=80:00:13:70:01:7f:00:01:01:cc:8a:b2:67]
2020-01-22 15:23:29 [INFO] UsmUserEntry[userName=docsisManager,usmUser=UsmUser[secName=docsisManager,authProtocol=1.3.6.1.6.3.10.1.1.2,authPassphrase=00B47671A32B43A7487EC540B5C3DFAF1F,privProtocol=1.3.6.1.6.3.10.1.2.2,privPassphrase=00B47671A32B43A7487EC540B5C3DFAF1F,localizationEngineID=80:00:13:70:01:7f:00:01:01:cc:8a:b2:67],storageType=nonVolatile]
2020-01-22 15:23:29 [INFO] Listening on 0.0.0.0/161
2020-01-22 15:23:29 [INFO] Count
2020-01-22 15:23:29.460 DefaultUDPTransportMapping_0.0.0.0/161 DEBUG UDP receive buffer size for socket 0.0.0.0/161 is set to: 106496
2020-01-22 15:23:29.461 DefaultUDPTransportMapping_0.0.0.0/161 INFO Listening on socket 0.0.0.0/161
2020-01-22 15:23:31.648 DefaultUDPTransportMapping_0.0.0.0/161 DEBUG Received message from /172.20.4.45/40332 with length 63: 30:3d:02:01:03:30:10:02:04:14:1a:82:6f:02:02:05:c0:04:01:04:02:01:03:04:10:30:0e:04:00:02:01:00:02:01:00:04:00:04:00:04:00:30:14:04:00:04:00:a0:0e:02:04:67:bd:a6:0b:02:01:00:02:01:00:30:00
2020-01-22 15:23:31.670 DispatcherPool.0 DEBUG SNMPv3 header decoded: msgId=337281647, msgMaxSize=1472, msgFlags=04, secModel=3
2020-01-22 15:23:31.672 DispatcherPool.0 DEBUG RFC3414 §3.2.3 Unknown engine ID:
2020-01-22 15:23:31.686 DispatcherPool.0 DEBUG Adding cache entry: StateReference[msgID=337281647,pduHandle=PduHandle[1417038593],securityEngineID=,securityModel=org.snmp4j.security.USM@4e9fd3d5,securityName=,securityLevel=1,contextEngineID=,contextName=,retryMsgIDs=null]
2020-01-22 15:23:31.687 DispatcherPool.0 DEBUG Removed cache entry: StateReference[msgID=337281647,pduHandle=null,securityEngineID=,securityModel=org.snmp4j.security.USM@4e9fd3d5,securityName=,securityLevel=1,contextEngineID=,contextName=,retryMsgIDs=null]
2020-01-22 15:23:31.687 DispatcherPool.0 DEBUG RFC3414 §3.1.4.b Outgoing message is not encrypted
2020-01-22 15:23:31.692 DispatcherPool.0 DEBUG Sending message to 172.20.4.45/40332 from 0.0.0.0/161 with length 104: 30:66:02:01:03:30:11:02:04:14:1a:82:6f:02:03:00:ff:ff:04:01:00:02:01:03:04:1d:30:1b:04:0d:80:00:13:70:01:7f:00:01:01:cc:8a:b2:67:02:01:00:02:01:00:04:00:04:00:04:00:30:2f:04:0d:80:00:13:70:01:7f:00:01:01:cc:8a:b2:67:04:00:a8:1c:02:01:00:02:01:00:02:01:00:30:11:30:0f:06:0a:2b:06:01:06:03:0f:01:01:04:00:41:01:00
2020-01-22 15:23:31.693 DispatcherPool.0 DEBUG Sending packet to 172.20.4.45/40332
2020-01-22 15:23:31.694 DefaultUDPTransportMapping_0.0.0.0/161 DEBUG Received message from /172.20.4.45/40332 with length 152: 30:81:95:02:01:03:30:10:02:04:14:1a:82:6e:02:02:05:c0:04:01:04:02:01:03:04:28:30:26:04:0d:80:00:13:70:01:7f:00:01:01:cc:8a:b2:67:02:01:00:02:01:00:04:0b:64:68:4b:69:63:6b:73:74:61:72:74:04:00:04:00:30:54:04:0d:80:00:13:70:01:7f:00:01:01:cc:8a:b2:67:04:00:a0:41:02:04:67:bd:a6:0a:02:01:00:02:01:00:30:33:30:0f:06:0b:2b:06:01:03:65:01:02:01:01:02:01:05:00:30:0f:06:0b:2b:06:01:03:65:01:02:01:01:03:01:05:00:30:0f:06:0b:2b:06:01:03:65:01:02:01:01:04:01:05:00
2020-01-22 15:23:31.694 DispatcherPool.1 DEBUG SNMPv3 header decoded: msgId=337281646, msgMaxSize=1472, msgFlags=04, secModel=3
2020-01-22 15:23:31.705 DispatcherPool.1 DEBUG getUser(engineID=80:00:13:70:01:7f:00:01:01:cc:8a:b2:67, securityName=dhKickstart)
2020-01-22 15:23:31.707 DispatcherPool.1 DEBUG RFC3412 §7.2.10 - Received PDU is NOT a response or internal class message → unchanged PduHandle = PduHandle[1740482058]
2020-01-22 15:23:31.707 DispatcherPool.1 DEBUG Adding cache entry: StateReference[msgID=337281646,pduHandle=PduHandle[1740482058],securityEngineID=80:00:13:70:01:7f:00:01:01:cc:8a:b2:67,securityModel=org.snmp4j.security.USM@4e9fd3d5,securityName=dhKickstart,securityLevel=1,contextEngineID=80:00:13:70:01:7f:00:01:01:cc:8a:b2:67,contextName=,retryMsgIDs=null]
2020-01-22 15:23:31.737 DispatcherPool.0 INFO Dispatching message canceled due to security issue: statusInfo=1.3.6.1.6.3.15.1.1.4.0 = 0, status=1410,tmStateReference=TransportStateReference[transport=org.snmp4j.transport.DefaultUdpTransportMapping@f713686, address=0.0.0.0/161, securityName=null, requestedSecurityLevel=undefined, transportSecurityLevel=undefined, sameSecurity=false, sessionID=java.net.DatagramSocket@7a830a79, certifiedIdentity=null]
2020-01-22 15:23:31.739 DispatcherPool.1 DEBUG Fire process PDU event: CommandResponderEvent[securityModel=3, securityLevel=1, maxSizeResponsePDU=1365, pduHandle=PduHandle[1740482058], stateReference=StateReference[msgID=337281646,pduHandle=null,securityEngineID=80:00:13:70:01:7f:00:01:01:cc:8a:b2:67,securityModel=org.snmp4j.security.USM@4e9fd3d5,securityName=dhKickstart,securityLevel=1,contextEngineID=80:00:13:70:01:7f:00:01:01:cc:8a:b2:67,contextName=,retryMsgIDs=null], pdu=GET[{contextEngineID=80:00:13:70:01:7f:00:01:01:cc:8a:b2:67, contextName=}, requestID=1740482058, errorStatus=0, errorIndex=0, VBS[1.3.6.1.3.101.1.2.1.1.2.1 = Null; 1.3.6.1.3.101.1.2.1.1.3.1 = Null; 1.3.6.1.3.101.1.2.1.1.4.1 = Null]], messageProcessingModel=3, securityName=dhKickstart, processed=false, peerAddress=172.20.4.45/40332, transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping@f713686, tmStateReference=TransportStateReference[transport=org.snmp4j.transport.DefaultUdpTransportMapping@f713686, address=0.0.0.0/161, securityName=null, requestedSecurityLevel=undefined, transportSecurityLevel=undefined, sameSecurity=false, sessionID=java.net.DatagramSocket@7a830a79, certifiedIdentity=null]]
2020-01-22 15:23:31.740 DispatcherPool.1 DEBUG Removed cache entry: StateReference[msgID=337281646,pduHandle=null,securityEngineID=80:00:13:70:01:7f:00:01:01:cc:8a:b2:67,securityModel=org.snmp4j.security.USM@4e9fd3d5,securityName=dhKickstart,securityLevel=1,contextEngineID=80:00:13:70:01:7f:00:01:01:cc:8a:b2:67,contextName=,retryMsgIDs=null]
2020-01-22 15:23:31.740 DispatcherPool.1 DEBUG RFC3414 §3.1.4.b Outgoing message is not encrypted
2020-01-22 15:23:31.740 DispatcherPool.1 DEBUG Sending message to 172.20.4.45/40332 from 0.0.0.0/161 with length 153: 30:81:96:02:01:03:30:11:02:04:14:1a:82:6e:02:03:00:ff:ff:04:01:00:02:01:03:04:28:30:26:04:0d:80:00:13:70:01:7f:00:01:01:cc:8a:b2:67:02:01:00:02:01:00:04:0b:64:68:4b:69:63:6b:73:74:61:72:74:04:00:04:00:30:54:04:0d:80:00:13:70:01:7f:00:01:01:cc:8a:b2:67:04:00:a2:41:02:04:67:bd:a6:0a:02:01:00:02:01:00:30:33:30:0f:06:0b:2b:06:01:03:65:01:02:01:01:02:01:05:00:30:0f:06:0b:2b:06:01:03:65:01:02:01:01:03:01:05:00:30:0f:06:0b:2b:06:01:03:65:01:02:01:01:04:01:05:00
2020-01-22 15:23:31.740 DispatcherPool.1 DEBUG Sending packet to 172.20.4.45/40332

The error I’m getting on my software doesn’t seem to get the docsisManager from the dhKickstart.
[ERR] (/device/snmp/get) Could not find user docsisManager while dhKickstarting the device 10.144.0.26

Any insight into what I might be missing would be appreciated. Or I could provide a tcpdump of the exchange too. Thanks!

To support the Diffie-Hellmann kick start process you need to implement the corresponding MIB (and other MIBs). I doubt, that you will get this running in less than six months if you do not use SNMP4J-Agent for this.

The AgentConfigManager class implements all necessary MIBs and agent functions needed for that.

Implementing an agent with Diffie-Hellmann key exchange support from scratch is a task that could take years until it runs securely and without major errors (and all the SNMPv3 security functions and MIBs needed for that).

Fair enough. We had this SNMP listener to handle SNMPv1 and SNMPv2 traffic already so I thought it would be possible to extend it to SNMPv3. I’ll start looking into the SNMP4J-Agent. Thanks!

Hi Frank,

I looked into the SampleAgent, and the AgentConfigManager. I’m able to get an snmp listener up and running, but I have a couple of questions on how I can modify it to handle what I need to do.

I’ve provided the AgentConfigManager the diffieHellmanKickstartParameters, but when attempting to access the usmDHKickstartTable, the response I get back is noSuchInstance for those OIDs. Do I need to create the MIB table for the kickstart table manually?

data: get-response (2)
            get-response
                request-id: 1740482203
                error-status: noError (0)
                error-index: 0
                variable-bindings: 3 items
                    1.3.6.1.3.101.1.2.1.1.2.1: noSuchInstance
                        Object Name: 1.3.6.1.3.101.1.2.1.1.2.1 (iso.3.6.1.3.101.1.2.1.1.2.1)
                        noSuchInstance
                            [Expert Info (Note/Response): noSuchInstance]
                    1.3.6.1.3.101.1.2.1.1.3.1: noSuchInstance
                        Object Name: 1.3.6.1.3.101.1.2.1.1.3.1 (iso.3.6.1.3.101.1.2.1.1.3.1)
                        noSuchInstance
                            [Expert Info (Note/Response): noSuchInstance]
                    1.3.6.1.3.101.1.2.1.1.4.1: noSuchInstance
                        Object Name: 1.3.6.1.3.101.1.2.1.1.4.1 (iso.3.6.1.3.101.1.2.1.1.4.1)
                        noSuchInstance
                            [Expert Info (Note/Response): noSuchInstance]

I saw in the sample agent the method for registering MIBs and I’ve tried the provided code to add a scalar

void registerMIBs() {
if (modules == null) {
modules = new Modules(getFactory());
modules.getSnmp4jDemoMib().getSnmp4jDemoEntry().addMOTableRowListener(new DemoTableRowListener());
((TimeStamp) modules.getSnmp4jDemoMib().getSnmp4jDemoEntry()
.getColumn(Snmp4jDemoMib.idxSnmp4jDemoEntryCol4)).setSysUpTime(agent.getSysUpTime());
}
try {
modules.registerMOs(server, null);
MOScalar myScalar = new MOScalar(new OID(“1.2.3.5.6.0”), MOAccessImpl.ACCESS_READ_CREATE,
new OctetString(“myText”));
server.register(myScalar, null);

And the results come back as noSuchObject when trying to grab that OID, vs one that seems already provided.

Frame 2: 84 bytes on wire (672 bits), 84 bytes captured (672 bits)
Linux cooked capture
Internet Protocol Version 4, Src: 10.144.0.26, Dst: 172.20.4.45
User Datagram Protocol, Src Port: 161, Dst Port: 40537
Simple Network Management Protocol
version: v2c (1)
community: public
data: get-response (2)
get-response
request-id: 1740482228
error-status: noError (0)
error-index: 0
variable-bindings: 1 item
1.2.3.5.6.0: noSuchObject
Object Name: 1.2.3.5.6.0 (iso.2.3.5.6.0)
noSuchObject
[Expert Info (Note/Response): noSuchObject]

Working one

Frame 2: 94 bytes on wire (752 bits), 94 bytes captured (752 bits)
Linux cooked capture
Internet Protocol Version 4, Src: 10.144.0.26, Dst: 172.20.4.45
User Datagram Protocol, Src Port: 161, Dst Port: 42807
Simple Network Management Protocol
version: v2c (1)
community: public
data: get-response (2)
get-response
request-id: 1740482229
error-status: noError (0)
error-index: 0
variable-bindings: 1 item
1.3.6.1.2.1.198.2.2.1.3.1.5.2: 3
Object Name: 1.3.6.1.2.1.198.2.2.1.3.1.5.2 (iso.3.6.1.2.1.198.2.2.1.3.1.5.2)
Value (Integer32): 3

Am I missing something to registering your own OIDs? Thanks!

Regards,
Matt

Hi Matt,

Those objects of the usmDHKickstartTable are not used/published by AgentConfigManager by default. For DH kickstart those values are not required. The current implementation uses out-of-band property file exchange instead.

Nevertheless, future versions of SNMP4J-Agent will add support for that table.

Best regards
Frank