diff options
author | Ilya Etingof <etingof@gmail.com> | 2018-06-30 20:14:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-30 20:14:57 +0200 |
commit | da4539e34cacdc0bd6ecfba98dc48caecc12b104 (patch) | |
tree | 22fdd82dae7dc971a8998d7679d9d6698105116c /pysnmp/entity | |
parent | df6d6a6efd7ec6810feb9edddf369264512612b2 (diff) | |
download | pysnmp-git-da4539e34cacdc0bd6ecfba98dc48caecc12b104.tar.gz |
Overhaul SMI/MIB instrumentation API (#161)
Overhaul SMI/MIB instrumentation API
SMI/MIB managed objects API overhauled for simplicity and
flexibility breaking backward compatibility.
This change would allow way more control over custom MIB
managed objects and also is the prerequisite for
asynchronous MIB instrumentation.
Diffstat (limited to 'pysnmp/entity')
-rw-r--r-- | pysnmp/entity/config.py | 209 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/cmdrsp.py | 151 |
2 files changed, 223 insertions, 137 deletions
diff --git a/pysnmp/entity/config.py b/pysnmp/entity/config.py index d34c3773..ce6e9b07 100644 --- a/pysnmp/entity/config.py +++ b/pysnmp/entity/config.py @@ -83,17 +83,19 @@ def addV1System(snmpEngine, communityIndex, communityName, contextName = null snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpCommunityEntry.name + (8,) + tblIdx, 'destroy'),) + (snmpCommunityEntry.name + (8,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpCommunityEntry.name + (1,) + tblIdx, communityIndex), - (snmpCommunityEntry.name + (2,) + tblIdx, communityName), - (snmpCommunityEntry.name + (3,) + tblIdx, securityName is not None and securityName or communityIndex), - (snmpCommunityEntry.name + (4,) + tblIdx, contextEngineId), - (snmpCommunityEntry.name + (5,) + tblIdx, contextName), - (snmpCommunityEntry.name + (6,) + tblIdx, transportTag), - (snmpCommunityEntry.name + (7,) + tblIdx, 'nonVolatile'), - (snmpCommunityEntry.name + (8,) + tblIdx, 'createAndGo')) + (snmpCommunityEntry.name + (1,) + tblIdx, communityIndex), + (snmpCommunityEntry.name + (2,) + tblIdx, communityName), + (snmpCommunityEntry.name + (3,) + tblIdx, securityName is not None and securityName or communityIndex), + (snmpCommunityEntry.name + (4,) + tblIdx, contextEngineId), + (snmpCommunityEntry.name + (5,) + tblIdx, contextName), + (snmpCommunityEntry.name + (6,) + tblIdx, transportTag), + (snmpCommunityEntry.name + (7,) + tblIdx, 'nonVolatile'), + (snmpCommunityEntry.name + (8,) + tblIdx, 'createAndGo'), + **dict(snmpEngine=snmpEngine) ) @@ -101,7 +103,8 @@ def delV1System(snmpEngine, communityIndex): (snmpCommunityEntry, tblIdx, snmpEngineID) = __cookV1SystemInfo(snmpEngine, communityIndex) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpCommunityEntry.name + (8,) + tblIdx, 'destroy'),) + (snmpCommunityEntry.name + (8,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) @@ -143,15 +146,17 @@ def addV3User(snmpEngine, userName, zeroDotZero, = mibBuilder.importSymbols('SNMPv2-SMI', 'zeroDotZero') snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((usmUserEntry.name + (13,) + tblIdx1, 'destroy'),) + (usmUserEntry.name + (13,) + tblIdx1, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((usmUserEntry.name + (2,) + tblIdx1, userName), - (usmUserEntry.name + (3,) + tblIdx1, securityName), - (usmUserEntry.name + (4,) + tblIdx1, zeroDotZero.name), - (usmUserEntry.name + (5,) + tblIdx1, authProtocol), - (usmUserEntry.name + (8,) + tblIdx1, privProtocol), - (usmUserEntry.name + (13,) + tblIdx1, 'createAndGo')) + (usmUserEntry.name + (2,) + tblIdx1, userName), + (usmUserEntry.name + (3,) + tblIdx1, securityName), + (usmUserEntry.name + (4,) + tblIdx1, zeroDotZero.name), + (usmUserEntry.name + (5,) + tblIdx1, authProtocol), + (usmUserEntry.name + (8,) + tblIdx1, privProtocol), + (usmUserEntry.name + (13,) + tblIdx1, 'createAndGo'), + **dict(snmpEngine=snmpEngine) ) # Localize keys @@ -177,22 +182,25 @@ def addV3User(snmpEngine, userName, # Commit localized keys snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((pysnmpUsmKeyEntry.name + (1,) + tblIdx1, localAuthKey), - (pysnmpUsmKeyEntry.name + (2,) + tblIdx1, localPrivKey), - (pysnmpUsmKeyEntry.name + (3,) + tblIdx1, hashedAuthPassphrase), - (pysnmpUsmKeyEntry.name + (4,) + tblIdx1, hashedPrivPassphrase)) + (pysnmpUsmKeyEntry.name + (1,) + tblIdx1, localAuthKey), + (pysnmpUsmKeyEntry.name + (2,) + tblIdx1, localPrivKey), + (pysnmpUsmKeyEntry.name + (3,) + tblIdx1, hashedAuthPassphrase), + (pysnmpUsmKeyEntry.name + (4,) + tblIdx1, hashedPrivPassphrase), + **dict(snmpEngine=snmpEngine) ) # Commit passphrases snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'),) + (pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((pysnmpUsmSecretEntry.name + (1,) + tblIdx2, userName), - (pysnmpUsmSecretEntry.name + (2,) + tblIdx2, authKey), - (pysnmpUsmSecretEntry.name + (3,) + tblIdx2, privKey), - (pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'createAndGo')) + (pysnmpUsmSecretEntry.name + (1,) + tblIdx2, userName), + (pysnmpUsmSecretEntry.name + (2,) + tblIdx2, authKey), + (pysnmpUsmSecretEntry.name + (3,) + tblIdx2, privKey), + (pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'createAndGo'), + **dict(snmpEngine=snmpEngine) ) @@ -202,10 +210,12 @@ def delV3User(snmpEngine, (snmpEngineID, usmUserEntry, tblIdx1, pysnmpUsmSecretEntry, tblIdx2) = __cookV3UserInfo(snmpEngine, userName, securityEngineId) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((usmUserEntry.name + (13,) + tblIdx1, 'destroy'),) + (usmUserEntry.name + (13,) + tblIdx1, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'),) + (pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'), + **dict(snmpEngine=snmpEngine) ) # Drop all derived rows @@ -216,7 +226,7 @@ def delV3User(snmpEngine, ) while varBinds: varBinds = snmpEngine.msgAndPduDsp.mibInstrumController.readNextVars( - varBinds + *varBinds, **dict(snmpEngine=snmpEngine) ) if varBinds[0][1].isSameTypeWith(rfc1905.endOfMibView): break @@ -249,22 +259,25 @@ def addTargetParams(snmpEngine, name, securityName, securityLevel, mpModel=3): snmpTargetParamsEntry, tblIdx = __cookTargetParamsInfo(snmpEngine, name) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpTargetParamsEntry.name + (7,) + tblIdx, 'destroy'),) + (snmpTargetParamsEntry.name + (7,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpTargetParamsEntry.name + (1,) + tblIdx, name), - (snmpTargetParamsEntry.name + (2,) + tblIdx, mpModel), - (snmpTargetParamsEntry.name + (3,) + tblIdx, securityModel), - (snmpTargetParamsEntry.name + (4,) + tblIdx, securityName), - (snmpTargetParamsEntry.name + (5,) + tblIdx, securityLevel), - (snmpTargetParamsEntry.name + (7,) + tblIdx, 'createAndGo')) + (snmpTargetParamsEntry.name + (1,) + tblIdx, name), + (snmpTargetParamsEntry.name + (2,) + tblIdx, mpModel), + (snmpTargetParamsEntry.name + (3,) + tblIdx, securityModel), + (snmpTargetParamsEntry.name + (4,) + tblIdx, securityName), + (snmpTargetParamsEntry.name + (5,) + tblIdx, securityLevel), + (snmpTargetParamsEntry.name + (7,) + tblIdx, 'createAndGo'), + **dict(snmpEngine=snmpEngine) ) def delTargetParams(snmpEngine, name): snmpTargetParamsEntry, tblIdx = __cookTargetParamsInfo(snmpEngine, name) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpTargetParamsEntry.name + (7,) + tblIdx, 'destroy'),) + (snmpTargetParamsEntry.name + (7,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) @@ -299,18 +312,20 @@ def addTargetAddr(snmpEngine, addrName, transportDomain, transportAddress, sourceAddress = TransportAddressIPv6(sourceAddress) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpTargetAddrEntry.name + (9,) + tblIdx, 'destroy'),) + (snmpTargetAddrEntry.name + (9,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpTargetAddrEntry.name + (1,) + tblIdx, addrName), - (snmpTargetAddrEntry.name + (2,) + tblIdx, transportDomain), - (snmpTargetAddrEntry.name + (3,) + tblIdx, transportAddress), - (snmpTargetAddrEntry.name + (4,) + tblIdx, timeout), - (snmpTargetAddrEntry.name + (5,) + tblIdx, retryCount), - (snmpTargetAddrEntry.name + (6,) + tblIdx, tagList), - (snmpTargetAddrEntry.name + (7,) + tblIdx, params), - (snmpSourceAddrEntry.name + (1,) + tblIdx, sourceAddress), - (snmpTargetAddrEntry.name + (9,) + tblIdx, 'createAndGo')) + (snmpTargetAddrEntry.name + (1,) + tblIdx, addrName), + (snmpTargetAddrEntry.name + (2,) + tblIdx, transportDomain), + (snmpTargetAddrEntry.name + (3,) + tblIdx, transportAddress), + (snmpTargetAddrEntry.name + (4,) + tblIdx, timeout), + (snmpTargetAddrEntry.name + (5,) + tblIdx, retryCount), + (snmpTargetAddrEntry.name + (6,) + tblIdx, tagList), + (snmpTargetAddrEntry.name + (7,) + tblIdx, params), + (snmpSourceAddrEntry.name + (1,) + tblIdx, sourceAddress), + (snmpTargetAddrEntry.name + (9,) + tblIdx, 'createAndGo'), + **dict(snmpEngine=snmpEngine) ) @@ -318,7 +333,8 @@ def delTargetAddr(snmpEngine, addrName): (snmpTargetAddrEntry, snmpSourceAddrEntry, tblIdx) = __cookTargetAddrInfo(snmpEngine, addrName) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpTargetAddrEntry.name + (9,) + tblIdx, 'destroy'),) + (snmpTargetAddrEntry.name + (9,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) @@ -386,7 +402,8 @@ def addContext(snmpEngine, contextName): vacmContextEntry, = mibBuilder.importSymbols('SNMP-VIEW-BASED-ACM-MIB', 'vacmContextEntry') tblIdx = vacmContextEntry.getInstIdFromIndices(contextName) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((vacmContextEntry.name + (1,) + tblIdx, contextName),) + (vacmContextEntry.name + (1,) + tblIdx, contextName), + ** dict(snmpEngine=snmpEngine) ) @@ -404,13 +421,15 @@ def addVacmGroup(snmpEngine, groupName, securityModel, securityName): (vacmSecurityToGroupEntry, tblIdx) = __cookVacmGroupInfo(snmpEngine, securityModel, securityName) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'destroy'),) + (vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((vacmSecurityToGroupEntry.name + (1,) + tblIdx, securityModel), - (vacmSecurityToGroupEntry.name + (2,) + tblIdx, securityName), - (vacmSecurityToGroupEntry.name + (3,) + tblIdx, groupName), - (vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'createAndGo')) + (vacmSecurityToGroupEntry.name + (1,) + tblIdx, securityModel), + (vacmSecurityToGroupEntry.name + (2,) + tblIdx, securityName), + (vacmSecurityToGroupEntry.name + (3,) + tblIdx, groupName), + (vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'createAndGo'), + **dict(snmpEngine=snmpEngine) ) @@ -419,7 +438,8 @@ def delVacmGroup(snmpEngine, securityModel, securityName): snmpEngine, securityModel, securityName ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'destroy'),) + (vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) @@ -442,17 +462,19 @@ def addVacmAccess(snmpEngine, groupName, contextName, securityModel, addContext(snmpEngine, contextName) # this is leaky snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((vacmAccessEntry.name + (9,) + tblIdx, 'destroy'),) + (vacmAccessEntry.name + (9,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((vacmAccessEntry.name + (1,) + tblIdx, contextName), - (vacmAccessEntry.name + (2,) + tblIdx, securityModel), - (vacmAccessEntry.name + (3,) + tblIdx, securityLevel), - (vacmAccessEntry.name + (4,) + tblIdx, prefix), - (vacmAccessEntry.name + (5,) + tblIdx, readView), - (vacmAccessEntry.name + (6,) + tblIdx, writeView), - (vacmAccessEntry.name + (7,) + tblIdx, notifyView), - (vacmAccessEntry.name + (9,) + tblIdx, 'createAndGo')) + (vacmAccessEntry.name + (1,) + tblIdx, contextName), + (vacmAccessEntry.name + (2,) + tblIdx, securityModel), + (vacmAccessEntry.name + (3,) + tblIdx, securityLevel), + (vacmAccessEntry.name + (4,) + tblIdx, prefix), + (vacmAccessEntry.name + (5,) + tblIdx, readView), + (vacmAccessEntry.name + (6,) + tblIdx, writeView), + (vacmAccessEntry.name + (7,) + tblIdx, notifyView), + (vacmAccessEntry.name + (9,) + tblIdx, 'createAndGo'), + **dict(snmpEngine=snmpEngine) ) @@ -462,7 +484,8 @@ def delVacmAccess(snmpEngine, groupName, contextName, securityModel, contextName, securityModel, securityLevel) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((vacmAccessEntry.name + (9,) + tblIdx, 'destroy'),) + (vacmAccessEntry.name + (9,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) @@ -480,14 +503,16 @@ def addVacmView(snmpEngine, viewName, viewType, subTree, mask): vacmViewTreeFamilyEntry, tblIdx = __cookVacmViewInfo(snmpEngine, viewName, subTree) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'destroy'),) + (vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((vacmViewTreeFamilyEntry.name + (1,) + tblIdx, viewName), - (vacmViewTreeFamilyEntry.name + (2,) + tblIdx, subTree), - (vacmViewTreeFamilyEntry.name + (3,) + tblIdx, mask), - (vacmViewTreeFamilyEntry.name + (4,) + tblIdx, viewType), - (vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'createAndGo')) + (vacmViewTreeFamilyEntry.name + (1,) + tblIdx, viewName), + (vacmViewTreeFamilyEntry.name + (2,) + tblIdx, subTree), + (vacmViewTreeFamilyEntry.name + (3,) + tblIdx, mask), + (vacmViewTreeFamilyEntry.name + (4,) + tblIdx, viewType), + (vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'createAndGo'), + **dict(snmpEngine=snmpEngine) ) @@ -495,7 +520,8 @@ def delVacmView(snmpEngine, viewName, subTree): vacmViewTreeFamilyEntry, tblIdx = __cookVacmViewInfo(snmpEngine, viewName, subTree) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'destroy'),) + (vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'destroy'), + **dict(snmpEngine=snmpEngine) ) @@ -586,33 +612,39 @@ def addNotificationTarget(snmpEngine, notificationName, paramsName, paramsName, filterSubtree) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpNotifyEntry.name + (5,) + tblIdx1, 'destroy'),) + (snmpNotifyEntry.name + (5,) + tblIdx1, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpNotifyEntry.name + (2,) + tblIdx1, transportTag), - (snmpNotifyEntry.name + (3,) + tblIdx1, notifyType), - (snmpNotifyEntry.name + (5,) + tblIdx1, 'createAndGo')) + (snmpNotifyEntry.name + (2,) + tblIdx1, transportTag), + (snmpNotifyEntry.name + (3,) + tblIdx1, notifyType), + (snmpNotifyEntry.name + (5,) + tblIdx1, 'createAndGo'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'destroy'),) + (snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpNotifyFilterProfileEntry.name + (1,) + tblIdx2, profileName), - (snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'createAndGo')) + (snmpNotifyFilterProfileEntry.name + (1,) + tblIdx2, profileName), + (snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'createAndGo'), + **dict(snmpEngine=snmpEngine) ) if not snmpNotifyFilterEntry: return snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'destroy'),) + (snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpNotifyFilterEntry.name + (1,) + tblIdx3, filterSubtree), - (snmpNotifyFilterEntry.name + (2,) + tblIdx3, filterMask), - (snmpNotifyFilterEntry.name + (3,) + tblIdx3, filterType), - (snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'createAndGo')) + (snmpNotifyFilterEntry.name + (1,) + tblIdx3, filterSubtree), + (snmpNotifyFilterEntry.name + (2,) + tblIdx3, filterMask), + (snmpNotifyFilterEntry.name + (3,) + tblIdx3, filterType), + (snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'createAndGo'), + **dict(snmpEngine=snmpEngine) ) @@ -624,18 +656,21 @@ def delNotificationTarget(snmpEngine, notificationName, paramsName, paramsName, filterSubtree) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpNotifyEntry.name + (5,) + tblIdx1, 'destroy'),) + (snmpNotifyEntry.name + (5,) + tblIdx1, 'destroy'), + **dict(snmpEngine=snmpEngine) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'destroy'),) + (snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'destroy'), + **dict(snmpEngine=snmpEngine) ) if not snmpNotifyFilterEntry: return snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'destroy'),) + (snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'destroy'), + **dict(snmpEngine=snmpEngine) ) diff --git a/pysnmp/entity/rfc3413/cmdrsp.py b/pysnmp/entity/rfc3413/cmdrsp.py index 94b4d45b..3d2cb5ab 100644 --- a/pysnmp/entity/rfc3413/cmdrsp.py +++ b/pysnmp/entity/rfc3413/cmdrsp.py @@ -17,15 +17,16 @@ class CommandResponderBase(object): acmID = 3 # default MIB access control method to use pduTypes = () - def __init__(self, snmpEngine, snmpContext): + def __init__(self, snmpEngine, snmpContext, cbCtx=None): snmpEngine.msgAndPduDsp.registerContextEngineId( snmpContext.contextEngineId, self.pduTypes, self.processPdu ) self.snmpContext = snmpContext + self.cbCtx = cbCtx self.__pendingReqs = {} - def handleMgmtOperation(self, snmpEngine, stateReference, contextName, - PDU, acInfo): + def handleMgmtOperation(self, snmpEngine, stateReference, + contextName, PDU, acCtx): pass def close(self, snmpEngine): @@ -36,9 +37,16 @@ class CommandResponderBase(object): def sendVarBinds(self, snmpEngine, stateReference, errorStatus, errorIndex, varBinds): - (messageProcessingModel, securityModel, securityName, - securityLevel, contextEngineId, contextName, - pduVersion, PDU, origPdu, maxSizeResponseScopedPDU, + (messageProcessingModel, + securityModel, + securityName, + securityLevel, + contextEngineId, + contextName, + pduVersion, + PDU, + origPdu, + maxSizeResponseScopedPDU, statusInformation) = self.__pendingReqs[stateReference] v2c.apiPDU.setErrorStatus(PDU, errorStatus) @@ -53,9 +61,16 @@ class CommandResponderBase(object): self.sendPdu(snmpEngine, stateReference, PDU) def sendPdu(self, snmpEngine, stateReference, PDU): - (messageProcessingModel, securityModel, securityName, - securityLevel, contextEngineId, contextName, - pduVersion, _, origPdu, maxSizeResponseScopedPDU, + (messageProcessingModel, + securityModel, + securityName, + securityLevel, + contextEngineId, + contextName, + pduVersion, + _, + origPdu, + maxSizeResponseScopedPDU, statusInformation) = self.__pendingReqs[stateReference] # Agent-side API complies with SMIv2 @@ -132,9 +147,8 @@ class CommandResponderBase(object): 'processPdu: stateReference %s, varBinds %s' % (stateReference, varBinds)) try: - self.handleMgmtOperation(snmpEngine, stateReference, - contextName, PDU, - (self.__verifyAccess, snmpEngine)) + self.handleMgmtOperation(snmpEngine, stateReference, contextName, PDU) + # SNMPv2 SMI exceptions except pysnmp.smi.error.GenError: errorIndication = sys.exc_info()[1] @@ -185,18 +199,29 @@ class CommandResponderBase(object): self.releaseStateInformation(stateReference) - def __verifyAccess(self, name, syntax, idx, viewType, acCtx): - snmpEngine = acCtx + @classmethod + def verifyAccess(cls, viewType, varBind, **context): + name, val = varBind + + snmpEngine = context['snmpEngine'] + execCtx = snmpEngine.observer.getExecutionContext('rfc3412.receiveMessage:request') - (securityModel, securityName, securityLevel, contextName, - pduType) = (execCtx['securityModel'], execCtx['securityName'], - execCtx['securityLevel'], execCtx['contextName'], + (securityModel, + securityName, + securityLevel, + contextName, + pduType) = (execCtx['securityModel'], + execCtx['securityName'], + execCtx['securityLevel'], + execCtx['contextName'], execCtx['pdu'].getTagSet()) + try: - snmpEngine.accessControlModel[self.acmID].isAccessAllowed( + snmpEngine.accessControlModel[cls.acmID].isAccessAllowed( snmpEngine, securityModel, securityName, securityLevel, viewType, contextName, name ) + # Map ACM errors onto SMI ones except error.StatusInformation: statusInformation = sys.exc_info()[1] @@ -207,41 +232,48 @@ class CommandResponderBase(object): if (errorIndication == errind.noSuchView or errorIndication == errind.noAccessEntry or errorIndication == errind.noGroupName): - raise pysnmp.smi.error.AuthorizationError(name=name, idx=idx) + raise pysnmp.smi.error.AuthorizationError(name=name, idx=context.get('idx')) + elif errorIndication == errind.otherError: - raise pysnmp.smi.error.GenError(name=name, idx=idx) + raise pysnmp.smi.error.GenError(name=name, idx=context.get('idx')) + elif errorIndication == errind.noSuchContext: snmpUnknownContexts, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols( '__SNMP-TARGET-MIB', 'snmpUnknownContexts') snmpUnknownContexts.syntax += 1 # Request REPORT generation - raise pysnmp.smi.error.GenError(name=name, idx=idx, + raise pysnmp.smi.error.GenError(name=name, idx=context.get('idx'), oid=snmpUnknownContexts.name, val=snmpUnknownContexts.syntax) + elif errorIndication == errind.notInView: - return 1 + return True + else: raise error.ProtocolError('Unknown ACM error %s' % errorIndication) else: # rfc2576: 4.1.2.1 - if (securityModel == 1 and syntax is not None and - self._counter64Type == syntax.getTagSet() and - self._getNextRequestType == pduType): + if (securityModel == 1 and val is not None and + cls._counter64Type == val.getTagSet() and + cls._getNextRequestType == pduType): # This will cause MibTree to skip this OID-value - raise pysnmp.smi.error.NoAccessError(name=name, idx=idx) + raise pysnmp.smi.error.NoAccessError(name=name, idx=context.get('idx')) class GetCommandResponder(CommandResponderBase): pduTypes = (rfc1905.GetRequestPDU.tagSet,) # rfc1905: 4.2.1 - def handleMgmtOperation(self, snmpEngine, stateReference, - contextName, PDU, acInfo): - (acFun, acCtx) = acInfo + def handleMgmtOperation(self, snmpEngine, stateReference, contextName, PDU): # rfc1905: 4.2.1.1 mgmtFun = self.snmpContext.getMibInstrum(contextName).readVars - self.sendVarBinds(snmpEngine, stateReference, 0, 0, - mgmtFun(v2c.apiPDU.getVarBinds(PDU), (acFun, acCtx))) + varBinds = v2c.apiPDU.getVarBinds(PDU) + + context = dict(snmpEngine=snmpEngine, acFun=self.verifyAccess, cbCtx=self.cbCtx) + + rspVarBinds = mgmtFun(*varBinds, **context) + + self.sendVarBinds(snmpEngine, stateReference, 0, 0, rspVarBinds) self.releaseStateInformation(stateReference) @@ -249,21 +281,26 @@ class NextCommandResponder(CommandResponderBase): pduTypes = (rfc1905.GetNextRequestPDU.tagSet,) # rfc1905: 4.2.2 - def handleMgmtOperation(self, snmpEngine, stateReference, - contextName, PDU, acInfo): - (acFun, acCtx) = acInfo + def handleMgmtOperation(self, snmpEngine, stateReference, contextName, PDU): # rfc1905: 4.2.2.1 mgmtFun = self.snmpContext.getMibInstrum(contextName).readNextVars + varBinds = v2c.apiPDU.getVarBinds(PDU) + + context = dict(snmpEngine=snmpEngine, acFun=self.verifyAccess, cbCtx=self.cbCtx) + while True: - rspVarBinds = mgmtFun(varBinds, (acFun, acCtx)) + rspVarBinds = mgmtFun(*varBinds, **context) + try: self.sendVarBinds(snmpEngine, stateReference, 0, 0, rspVarBinds) + except error.StatusInformation: idx = sys.exc_info()[1]['idx'] varBinds[idx] = (rspVarBinds[idx][0], varBinds[idx][1]) else: break + self.releaseStateInformation(stateReference) @@ -272,12 +309,11 @@ class BulkCommandResponder(CommandResponderBase): maxVarBinds = 64 # rfc1905: 4.2.3 - def handleMgmtOperation(self, snmpEngine, stateReference, - contextName, PDU, acInfo): - (acFun, acCtx) = acInfo + def handleMgmtOperation(self, snmpEngine, stateReference, contextName, PDU): nonRepeaters = v2c.apiBulkPDU.getNonRepeaters(PDU) if nonRepeaters < 0: nonRepeaters = 0 + maxRepetitions = v2c.apiBulkPDU.getMaxRepetitions(PDU) if maxRepetitions < 0: maxRepetitions = 0 @@ -295,14 +331,19 @@ class BulkCommandResponder(CommandResponderBase): mgmtFun = self.snmpContext.getMibInstrum(contextName).readNextVars + context = dict(snmpEngine=snmpEngine, acFun=self.verifyAccess, cbCtx=self.cbCtx) + if N: - rspVarBinds = mgmtFun(reqVarBinds[:N], (acFun, acCtx)) + # TODO(etingof): manage all PDU var-binds in a single call + rspVarBinds = mgmtFun(*reqVarBinds[:N], **context) + else: rspVarBinds = [] varBinds = reqVarBinds[-R:] + while M and R: - rspVarBinds.extend(mgmtFun(varBinds, (acFun, acCtx))) + rspVarBinds.extend(mgmtFun(*varBinds, **context)) varBinds = rspVarBinds[-R:] M -= 1 @@ -317,18 +358,28 @@ class SetCommandResponder(CommandResponderBase): pduTypes = (rfc1905.SetRequestPDU.tagSet,) # rfc1905: 4.2.5 - def handleMgmtOperation(self, snmpEngine, stateReference, - contextName, PDU, acInfo): - (acFun, acCtx) = acInfo + def handleMgmtOperation(self, snmpEngine, stateReference, contextName, PDU): mgmtFun = self.snmpContext.getMibInstrum(contextName).writeVars + + varBinds = v2c.apiPDU.getVarBinds(PDU) + + instrumError = None + + context = dict(snmpEngine=snmpEngine, acFun=self.verifyAccess, cbCtx=self.cbCtx) + # rfc1905: 4.2.5.1-13 try: - self.sendVarBinds(snmpEngine, stateReference, 0, 0, - mgmtFun(v2c.apiPDU.getVarBinds(PDU), - (acFun, acCtx))) - self.releaseStateInformation(stateReference) + rspVarBinds = mgmtFun(*varBinds, **context) + except (pysnmp.smi.error.NoSuchObjectError, pysnmp.smi.error.NoSuchInstanceError): - e = pysnmp.smi.error.NotWritableError() - e.update(sys.exc_info()[1]) - raise e + instrumError = pysnmp.smi.error.NotWritableError() + instrumError.update(sys.exc_info()[1]) + + else: + self.sendVarBinds(snmpEngine, stateReference, 0, 0, rspVarBinds) + + self.releaseStateInformation(stateReference) + + if instrumError: + raise instrumError |