summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pysnmp/hlapi/auth.py20
-rw-r--r--pysnmp/proto/secmod/rfc3414/service.py83
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],))