I am building a C++ application which purpose is, among other thing, to receive SNMP traps. For this I am using SNMP ++ library version V3.3 (https://agentpp.com/download.html C++ APIs SNMP++ 3.4.9).
I was expecting for traps using no authentication to be discarded/dropped if configuration was requesting some form of authentication but it does not seem to be the case.
To confirm this behavior I used the provided receive_trap example available in the consoleExamples directory. I commented every call to
usm->add_usm_user(...)
except for the one with "MD5" as security name :
usm->add_usm_user("MD5",
SNMP_AUTHPROTOCOL_HMACMD5, SNMP_PRIVPROTOCOL_NONE,
"MD5UserAuthPassword", "");
I then sent a trap (matching the "MD5" security name) to the application using net-snmp :
snmptrap -v 3 -e 0x090807060504030200 -u MD5 -Z 1,1 -l noAuthNoPriv localhost:10162 '' 1.3.6.1.4.1.8072.2.3.0.1 1.3.6.1.4.1.8072.2.3.2.1 i 123456
Since the application only registered User Security Model requires an MD5 password I would have though the trap would have been refused/dropped/discarded, but it was not :
Trying to register for traps on port 10162.
Waiting for traps/informs...
press return to stop
reason: -7
msg: SNMP++: Received SNMP Notification (trap or inform)
from: 127.0.0.1/45338
ID: 1.3.6.1.4.1.8072.2.3.0.1
Type:167
Oid: 1.3.6.1.4.1.8072.2.3.2.1
Val: 123456
To make sure there was no "default" UserSecurityModel used instead I then commented the remaining
usm->add_usm_user("MD5",
SNMP_AUTHPROTOCOL_HMACMD5, SNMP_PRIVPROTOCOL_NONE,
"MD5UserAuthPassword", "");
and sent my trap again using the same command. This time nothing happened :
Trying to register for traps on port 10162.
Waiting for traps/informs...
press return to stop
V3 is around 18k lines of RFC so it is completely possible I missed or misunderstood something but I would expect to be able to specify which security level I am expecting and drop everything which does not match. What am I missing ?
EDIT Additional testing with SNMPD
I have done some test with SNMPD and I somehow still get similar result.
I have created a user :
net-snmp-create-v3-user -ro -A STrP@SSWRD -a SHA -X STr0ngP@SSWRD -x AES snmpadmin
Then I am trying with authPriv key :
snmpwalk -v3 -a SHA -A STrP@SSWRD -x AES -X STr0ngP@SSWRD -l authPriv -u snmpadmin localhost
The request is accepted
with authNoPriv :
snmpwalk -v3 -a SHA -A STrP@SSWRD -x AES -l AuthNoPriv -u snmpadmin localhost
The request is accepted
with noAuthNoPriv :
snmpwalk -v3 -a SHA -A STrP@SSWRD -x AES -X STr0ngP@SSWR2D -l noauthnoPriv -u snmpadmin localhost
The request is rejected.
As I understand the authNoPriv must be rejected, but is accepted, this is incorrect from what I have read in the RFC and the cisco snmpv3 resume
Disclaimer I am not expert so take the following with a pinch of salt.
I cannot say for the library you are using but regarding the SNMP v3 flow:
In SNMPv3 exchanges, the USM is responsible for validation only on the SNMP authoritative engine side, the authoritative role depending of the kind of message.
The RFC 3414 describes the reception of message in section 3.2 :
If the information about the user indicates that it does not support the securityLevel requested by the caller, then the usmStatsUnsupportedSecLevels counter is incremented and an error indication (unsupportedSecurityLevel) together with the OID and value of the incremented counter is returned to the calling module.
If the securityLevel specifies that the message is to be authenticated, then the message is authenticated according to the user’s authentication protocol. To do so a call is made to the authentication module that implements the user’s authentication protocol according to the abstract service primitive
So in the step 6, the securityLevel is the one from the message. This means the TRAP is accepted by the USM layer on the receiver side even if the authentication is not provided.
It is then the task of the user of the TRAP to decide if the message must be interpreted or not.