diff options
-rw-r--r-- | pysnmp/hlapi/auth.py | 20 | ||||
-rw-r--r-- | pysnmp/proto/secmod/rfc3414/service.py | 83 |
2 files changed, 73 insertions, 30 deletions
diff --git a/pysnmp/hlapi/auth.py b/pysnmp/hlapi/auth.py index e784eec8..735d85df 100644 --- a/pysnmp/hlapi/auth.py +++ b/pysnmp/hlapi/auth.py @@ -305,11 +305,6 @@ class UsmUserData(object): * :py:class:`~pysnmp.hlapi.usmKeyTypeMaster` * :py:class:`~pysnmp.hlapi.usmKeyTypeLocalized` - - If `~pysnmp.hlapi.usmKeyTypeLocalized` is used, peer SNMP engine ID - discovery mechanism can't be leveraged for key localization, so - *securityEngineId* must be given by local configuration. - privKeyType: :py:class:`int` Type of `privKey` material. See :RFC:`3414#section-2.6` for technical explanation. @@ -320,6 +315,21 @@ class UsmUserData(object): * :py:class:`~pysnmp.hlapi.usmKeyTypeMaster` * :py:class:`~pysnmp.hlapi.usmKeyTypeLocalized` + Notes + ----- + If `~pysnmp.hlapi.usmKeyTypeLocalized` is used when running a + non-authoritative SNMP engine, USM key localization mechanism + is not invoked. As a consequence, local SNMP engine configuration + won't get automatically populated with remote SNMP engine's + *securityEngineId*. + + Therefore peer SNMP engine's *securityEngineId* must be added + to local configuration and associated with its localized keys. + + Alternatively, the magic *securityEngineId* value of five zeros + (*0x0000000000*) can be used to refer to the localized keys that + should be used with any unknown remote SNMP engine. This feature + is specific to pysnmp. Examples -------- diff --git a/pysnmp/proto/secmod/rfc3414/service.py b/pysnmp/proto/secmod/rfc3414/service.py index 244e9324..be2515ec 100644 --- a/pysnmp/proto/secmod/rfc3414/service.py +++ b/pysnmp/proto/secmod/rfc3414/service.py @@ -59,6 +59,11 @@ class SnmpUSMSecurityModel(AbstractSecurityModel): aes256.Aes256.serviceID: aes256.Aes256(), # non-standard nopriv.NoPriv.serviceID: nopriv.NoPriv()} + # If this, normally impossible, SNMP engine ID is present in LCD, we will use + # its master/localized keys when preparing SNMP message towards any unknown peer + # SNMP engine + wildcardSecurityEngineId = pMod.OctetString(hexValue='0000000000') + def __init__(self): AbstractSecurityModel.__init__(self) self.__securityParametersSpec = UsmSecurityParameters() @@ -278,13 +283,25 @@ class SnmpUSMSecurityModel(AbstractSecurityModel): elif securityEngineID: # 3.1.1b try: - (usmUserName, usmUserSecurityName, usmUserAuthProtocol, - usmUserAuthKeyLocalized, usmUserPrivProtocol, - usmUserPrivKeyLocalized) = self.__getUserInfo( - snmpEngine.msgAndPduDsp.mibInstrumController, - securityEngineID, - self.__sec2usr(snmpEngine, securityName, securityEngineID) - ) + try: + (usmUserName, usmUserSecurityName, usmUserAuthProtocol, + usmUserAuthKeyLocalized, usmUserPrivProtocol, + usmUserPrivKeyLocalized) = self.__getUserInfo( + snmpEngine.msgAndPduDsp.mibInstrumController, + securityEngineID, + self.__sec2usr(snmpEngine, securityName, + securityEngineID) + ) + + except NoSuchInstanceError: + (usmUserName, usmUserSecurityName, usmUserAuthProtocol, + usmUserAuthKeyLocalized, usmUserPrivProtocol, + usmUserPrivKeyLocalized) = self.__getUserInfo( + snmpEngine.msgAndPduDsp.mibInstrumController, + self.wildcardSecurityEngineId, + self.__sec2usr(snmpEngine, securityName, + self.wildcardSecurityEngineId) + ) debug.logger & debug.flagSM and debug.logger( '__generateRequestOrResponseMsg: found USM user entry ' @@ -743,28 +760,44 @@ class SnmpUSMSecurityModel(AbstractSecurityModel): snmpEngine.msgAndPduDsp.mibInstrumController, msgAuthoritativeEngineId, msgUserName ) - debug.logger & debug.flagSM and debug.logger('processIncomingMsg: read user info from LCD') + debug.logger & debug.flagSM and debug.logger( + 'processIncomingMsg: read user info from LCD') except NoSuchInstanceError: - debug.logger & debug.flagSM and debug.logger( - 'processIncomingMsg: unknown securityEngineID %r msgUserName %r' % ( - msgAuthoritativeEngineId, msgUserName)) + try: + (usmUserName, + usmUserSecurityName, + usmUserAuthProtocol, + usmUserAuthKeyLocalized, + usmUserPrivProtocol, + usmUserPrivKeyLocalized) = self.__getUserInfo( + snmpEngine.msgAndPduDsp.mibInstrumController, + self.wildcardSecurityEngineId, msgUserName + ) + debug.logger & debug.flagSM and debug.logger( + 'processIncomingMsg: read wildcard user info from LCD') - usmStatsUnknownUserNames, = mibBuilder.importSymbols( - '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownUserNames') - usmStatsUnknownUserNames.syntax += 1 + except NoSuchInstanceError: - raise error.StatusInformation( - errorIndication=errind.unknownSecurityName, - oid=usmStatsUnknownUserNames.name, - val=usmStatsUnknownUserNames.syntax, - securityStateReference=securityStateReference, - securityLevel=securityLevel, - contextEngineId=contextEngineId, - contextName=contextName, - msgUserName=msgUserName, - maxSizeResponseScopedPDU=maxSizeResponseScopedPDU - ) + debug.logger & debug.flagSM and debug.logger( + 'processIncomingMsg: unknown securityEngineID %r msgUserName %r' % ( + msgAuthoritativeEngineId, msgUserName)) + + usmStatsUnknownUserNames, = mibBuilder.importSymbols( + '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownUserNames') + usmStatsUnknownUserNames.syntax += 1 + + raise error.StatusInformation( + errorIndication=errind.unknownSecurityName, + oid=usmStatsUnknownUserNames.name, + val=usmStatsUnknownUserNames.syntax, + securityStateReference=securityStateReference, + securityLevel=securityLevel, + contextEngineId=contextEngineId, + contextName=contextName, + msgUserName=msgUserName, + maxSizeResponseScopedPDU=maxSizeResponseScopedPDU + ) except PyAsn1Error: debug.logger & debug.flagSM and debug.logger('processIncomingMsg: %s' % (sys.exc_info()[1],)) |