Hello community, here is the log from the commit of package python-pysnmp for openSUSE:Factory checked in at 2019-08-05 10:36:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pysnmp (Old) and /work/SRC/openSUSE:Factory/.python-pysnmp.new.4126 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pysnmp" Mon Aug 5 10:36:20 2019 rev:13 rq:720140 version:4.4.10 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pysnmp/python-pysnmp.changes 2019-02-11 21:27:30.231012021 +0100 +++ /work/SRC/openSUSE:Factory/.python-pysnmp.new.4126/python-pysnmp.changes 2019-08-05 10:36:27.439334026 +0200 @@ -1,0 +2,30 @@ +Wed Jul 31 20:44:55 UTC 2019 - Martin Hauke <[email protected]> + +- Update to version 4.4.10 + * Reworked VACM access control function. Most important changes include: + + + Added subtree match negation support (vacmViewTreeFamilyType) + + Added subtree family mask support (vacmViewTreeFamilyMask) + + Added prefix content name matching support (vacmAccessContextMatch) + + Added key VACM tables caching for better `isAccessAllowed` lookup + performance + + One potential incompatibility may be caused by the `addContext()` call + which now needs to be made explicitly during low-level VACM configuration + rather than be a side effect of `addVacmAccess()` call. + + * Rebased MIB importing code onto `importlib` because `imp` is long + deprecated + * Received MIB objects resolution made more forgiving to errors, added + optional `ignoreErrors` parameter to `ObjectType.resolveWithMib()` to + control that behaviour. + * Fixed asyncore main loop to respect non-default timer resolution + * Fixed `.setTimerResolution()` behaviour of abstract main loop dispatcher + to update call intervals of the existing periodic dispatcher jobs + * Fixed `var-bindings` initialization to prevent pyasn1 encoder failures + with newer pyasn1 versions where `SequenceOf` type looses its default + initializer. + * Fixed crash on uninitialized component serialization left out in + SNMP v1 TRAP PDU to SNMPv2/3 TRAP PDU proxy translation routine. + +------------------------------------------------------------------- Old: ---- pysnmp-4.4.9.tar.gz New: ---- pysnmp-4.4.10.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pysnmp.spec ++++++ --- /var/tmp/diff_new_pack.i0ZeRD/_old 2019-08-05 10:36:28.163333943 +0200 +++ /var/tmp/diff_new_pack.i0ZeRD/_new 2019-08-05 10:36:28.167333943 +0200 @@ -12,13 +12,13 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-pysnmp -Version: 4.4.9 +Version: 4.4.10 Release: 0 Summary: A pure-Python SNMPv1/v2c/v3 library License: BSD-2-Clause ++++++ pysnmp-4.4.9.tar.gz -> pysnmp-4.4.10.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/CHANGES.txt new/pysnmp-4.4.10/CHANGES.txt --- old/pysnmp-4.4.9/CHANGES.txt 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/CHANGES.txt 2019-07-30 20:29:22.000000000 +0200 @@ -1,4 +1,33 @@ +Revision 4.4.10, released 2019-07-29 +------------------------------------ + +- Reworked VACM access control function. Most important changes include: + + * Added subtree match negation support (vacmViewTreeFamilyType) + * Added subtree family mask support (vacmViewTreeFamilyMask) + * Added prefix content name matching support (vacmAccessContextMatch) + * Added key VACM tables caching for better `isAccessAllowed` lookup + performance + + One potential incompatibility may be caused by the `addContext()` call + which now needs to be made explicitly during low-level VACM configuration + rather than be a side effect of `addVacmAccess()` call. + +- Rebased MIB importing code onto `importlib` because `imp` is long + deprecated +- Received MIB objects resolution made more forgiving to errors, added + optional `ignoreErrors` parameter to `ObjectType.resolveWithMib()` to + control that behaviour. +- Fixed asyncore main loop to respect non-default timer resolution +- Fixed `.setTimerResolution()` behaviour of abstract main loop dispatcher + to update call intervals of the existing periodic dispatcher jobs +- Fixed `var-bindings` initialization to prevent pyasn1 encoder failures + with newer pyasn1 versions where `SequenceOf` type looses its default + initializer. +- Fixed crash on uninitialized component serialization left out in + SNMP v1 TRAP PDU to SNMPv2/3 TRAP PDU proxy translation routine. + Revision 4.4.9, released 2019-02-09 ----------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/docs/source/examples/v3arch/asyncore/agent/cmdrsp/advanced-topics.rst new/pysnmp-4.4.10/docs/source/examples/v3arch/asyncore/agent/cmdrsp/advanced-topics.rst --- old/pysnmp-4.4.9/docs/source/examples/v3arch/asyncore/agent/cmdrsp/advanced-topics.rst 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/docs/source/examples/v3arch/asyncore/agent/cmdrsp/advanced-topics.rst 2019-07-30 20:29:22.000000000 +0200 @@ -37,4 +37,14 @@ :download:`Download</../../examples/v3arch/asyncore/agent/cmdrsp/multiple-snmp-engines.py>` script. +.. include:: /../../examples/v3arch/asyncore/agent/cmdrsp/detailed-vacm-configuration.py + :start-after: """ + :end-before: """# + +.. literalinclude:: /../../examples/v3arch/asyncore/agent/cmdrsp/detailed-vacm-configuration.py + :start-after: """# + :language: python + +:download:`Download</../../examples/v3arch/asyncore/agent/cmdrsp/detailed-vacm-configuration.py>` script. + See also: :doc:`library reference </docs/api-reference>`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/examples/v3arch/asyncore/agent/cmdrsp/detailed-vacm-configuration.py new/pysnmp-4.4.10/examples/v3arch/asyncore/agent/cmdrsp/detailed-vacm-configuration.py --- old/pysnmp-4.4.9/examples/v3arch/asyncore/agent/cmdrsp/detailed-vacm-configuration.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pysnmp-4.4.10/examples/v3arch/asyncore/agent/cmdrsp/detailed-vacm-configuration.py 2019-07-30 20:29:22.000000000 +0200 @@ -0,0 +1,117 @@ +""" +Detailed VACM configuration ++++++++++++++++++++++++++++ + +Serves MIB subtrees under different conditions: + +* Respond to SNMPv2c commands +* with SNMP community "public" +* over IPv4/UDP, listening at 127.0.0.1:161 +* Serve MIB under non-default contextName `abcd` +* Allow access to `SNMPv2-MIB::system` subtree +* Although deny access to `SNMPv2-MIB::sysUpTime` by a bit mask +* Use partial context name matching (`a`) + +This example demonstrates detailed VACM configuration performed via +low-level VACM calls: `addContext`, `addVacmGroup`, `addVacmAccess` +and `addVacmView`. Each function populates one of the tables +defined in `SNMP-VIEW-BASED-ACM-MIB` and used strictly as described +in the above mentioned MIB. + +The following Net-SNMP's commands will GET a value at this Agent: + +| $ snmpget -v2c -c public 127.0.0.1 SNMPv2-MIB::sysLocation.0 + +However this command will fail: + +| $ snmpget -v2c -c public 127.0.0.1 SNMPv2-MIB::sysUpTime.0 + +This command will not reveal `SNMPv2-MIB::sysUpTime.0` among other objects: + +| $ snmpwalk -v2c -c public 127.0.0.1 SNMPv2-MIB::system +"""# +from pysnmp.entity import engine, config +from pysnmp.entity.rfc3413 import cmdrsp, context +from pysnmp.carrier.asyncore.dgram import udp + +# Create SNMP engine with autogenernated engineID and pre-bound +# to socket transport dispatcher +snmpEngine = engine.SnmpEngine() + +# Transport setup + +# UDP over IPv4 +config.addTransport( + snmpEngine, + udp.domainName, + udp.UdpTransport().openServerMode(('127.0.0.1', 161)) +) + +# Register default MIB instrumentation controller with a new SNMP context + +contextName = 'abcd' + +snmpContext = context.SnmpContext(snmpEngine) + +snmpContext.registerContextName( + contextName, snmpEngine.msgAndPduDsp.mibInstrumController) + +# Add new SNMP community name, map it to a new security name and +# SNMP context + +securityName = 'my-area' +communityName = 'public' + +config.addV1System( + snmpEngine, securityName, communityName, + contextEngineId=snmpContext.contextEngineId, + contextName=contextName) + +# VACM configuration settings + +securityModel = 2 # SNMPv2c +securityLevel = 1 # noAuthNoPriv + +vacmGroup = 'my-group' +readViewName = 'my-read-view' + +# We will match by context name prefix +contextPrefix = contextName[:1] + +# Populate SNMP-VIEW-BASED-ACM-MIB::vacmContextTable +config.addContext(snmpEngine, contextName) + +# Populate SNMP-VIEW-BASED-ACM-MIB::vacmSecurityToGroupTable +config.addVacmGroup( + snmpEngine, vacmGroup, securityModel, securityName) + +# Populate SNMP-VIEW-BASED-ACM-MIB::vacmAccessTable +config.addVacmAccess( + snmpEngine, vacmGroup, contextPrefix, securityModel, securityLevel, + 'prefix', readViewName, '', '') + +# Populate SNMP-VIEW-BASED-ACM-MIB::vacmViewTreeFamilyTable + +# Allow the whole system subtree +config.addVacmView( + snmpEngine, readViewName, 'included', '1.3.6.1.2.1.1.1', '1.1.1.1.1.1.1.0') + +# ...but exclude one sub-branch (just one scalar OID) +config.addVacmView( + snmpEngine, readViewName, 'excluded', '1.3.6.1.2.1.1.3', '1.1.1.1.1.1.1.1') + +# Register SNMP Applications at the SNMP engine for particular SNMP context +cmdrsp.GetCommandResponder(snmpEngine, snmpContext) +cmdrsp.SetCommandResponder(snmpEngine, snmpContext) +cmdrsp.NextCommandResponder(snmpEngine, snmpContext) + +# Register an imaginary never-ending job to keep I/O dispatcher running forever +snmpEngine.transportDispatcher.jobStarted(1) + +# Run I/O dispatcher which would receive queries and send responses +try: + snmpEngine.transportDispatcher.runDispatcher() + +except Exception: + snmpEngine.transportDispatcher.closeDispatcher() + raise diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/pysnmp/__init__.py new/pysnmp-4.4.10/pysnmp/__init__.py --- old/pysnmp-4.4.9/pysnmp/__init__.py 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/pysnmp/__init__.py 2019-07-30 20:29:22.000000000 +0200 @@ -1,5 +1,5 @@ # http://www.python.org/dev/peps/pep-0396/ -__version__ = '4.4.9' +__version__ = '4.4.10' # backward compatibility version = tuple([int(x) for x in __version__.split('.')]) majorVersionId = version[0] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/pysnmp/carrier/asyncore/dispatch.py new/pysnmp-4.4.10/pysnmp/carrier/asyncore/dispatch.py --- old/pysnmp-4.4.9/pysnmp/carrier/asyncore/dispatch.py 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/pysnmp/carrier/asyncore/dispatch.py 2019-07-30 20:29:22.000000000 +0200 @@ -42,7 +42,7 @@ def runDispatcher(self, timeout=0.0): while self.jobsArePending() or self.transportsAreWorking(): try: - loop(timeout and timeout or self.timeout, + loop(timeout or self.getTimerResolution(), use_poll=True, map=self.__sockMap, count=1) except KeyboardInterrupt: raise diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/pysnmp/carrier/base.py new/pysnmp-4.4.10/pysnmp/carrier/base.py --- old/pysnmp-4.4.9/pysnmp/carrier/base.py 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/pysnmp/carrier/base.py 2019-07-30 20:29:22.000000000 +0200 @@ -4,19 +4,25 @@ # Copyright (c) 2005-2019, Ilya Etingof <[email protected]> # License: http://snmplabs.com/pysnmp/license.html # +import sys + from pysnmp.carrier import error class TimerCallable(object): def __init__(self, cbFun, callInterval): self.__cbFun = cbFun - self.__callInterval = callInterval self.__nextCall = 0 + if sys.version_info > (2, 6): + self.__callInterval = callInterval + else: + self.interval = callInterval + def __call__(self, timeNow): if self.__nextCall <= timeNow: self.__cbFun(timeNow) - self.__nextCall = timeNow + self.__callInterval + self.__nextCall = timeNow + self.interval def __eq__(self, cbFun): return self.__cbFun == cbFun @@ -36,6 +42,15 @@ def __ge__(self, cbFun): return self.__cbFun >= cbFun + if sys.version_info > (2, 6): + @property + def interval(self): + return self.__callInterval + + @interval.setter + def interval(self, callInterval): + self.__callInterval = callInterval + class AbstractTransportDispatcher(object): def __init__(self): @@ -151,6 +166,12 @@ def setTimerResolution(self, timerResolution): if timerResolution < 0.01 or timerResolution > 10: raise error.CarrierError('Impossible timer resolution') + + for timerCallable in self.__timerCallables: + if timerCallable.interval == self.__timerResolution: + # Update periodics for default resolutions + timerCallable.interval = timerResolution + self.__timerResolution = timerResolution self.__timerDelta = timerResolution * 0.05 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/pysnmp/entity/config.py new/pysnmp-4.4.10/pysnmp/entity/config.py --- old/pysnmp-4.4.9/pysnmp/entity/config.py 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/pysnmp/entity/config.py 2019-07-30 20:29:22.000000000 +0200 @@ -11,6 +11,7 @@ from pysnmp.proto.secmod.rfc3826.priv import aes from pysnmp.proto.secmod.rfc7860.auth import hmacsha2 from pysnmp.proto.secmod.eso.priv import des3, aes192, aes256 +from pysnmp.proto import rfc1902 from pysnmp.proto import rfc1905 from pysnmp import error @@ -461,22 +462,20 @@ return vacmAccessEntry, tblIdx -def addVacmAccess(snmpEngine, groupName, contextName, securityModel, - securityLevel, prefix, readView, writeView, notifyView): - vacmAccessEntry, tblIdx = __cookVacmAccessInfo(snmpEngine, groupName, - contextName, securityModel, - securityLevel) - - addContext(snmpEngine, contextName) +def addVacmAccess(snmpEngine, groupName, contextPrefix, securityModel, + securityLevel, contextMatch, readView, writeView, notifyView): + vacmAccessEntry, tblIdx = __cookVacmAccessInfo( + snmpEngine, groupName, contextPrefix, securityModel, + securityLevel) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( ((vacmAccessEntry.name + (9,) + tblIdx, 'destroy'),) ) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( - ((vacmAccessEntry.name + (1,) + tblIdx, contextName), + ((vacmAccessEntry.name + (1,) + tblIdx, contextPrefix), (vacmAccessEntry.name + (2,) + tblIdx, securityModel), (vacmAccessEntry.name + (3,) + tblIdx, securityLevel), - (vacmAccessEntry.name + (4,) + tblIdx, prefix), + (vacmAccessEntry.name + (4,) + tblIdx, contextMatch), (vacmAccessEntry.name + (5,) + tblIdx, readView), (vacmAccessEntry.name + (6,) + tblIdx, writeView), (vacmAccessEntry.name + (7,) + tblIdx, notifyView), @@ -484,13 +483,10 @@ ) -def delVacmAccess(snmpEngine, groupName, contextName, securityModel, +def delVacmAccess(snmpEngine, groupName, contextPrefix, securityModel, securityLevel): - vacmAccessEntry, tblIdx = __cookVacmAccessInfo(snmpEngine, groupName, - contextName, securityModel, - securityLevel) - - delContext(snmpEngine, contextName) + vacmAccessEntry, tblIdx = __cookVacmAccessInfo( + snmpEngine, groupName, contextPrefix, securityModel, securityLevel) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( ((vacmAccessEntry.name + (9,) + tblIdx, 'destroy'),) @@ -507,16 +503,30 @@ return vacmViewTreeFamilyEntry, tblIdx -def addVacmView(snmpEngine, viewName, viewType, subTree, mask): - vacmViewTreeFamilyEntry, tblIdx = __cookVacmViewInfo(snmpEngine, viewName, - subTree) +def addVacmView(snmpEngine, viewName, viewType, subTree, subTreeMask): + vacmViewTreeFamilyEntry, tblIdx = __cookVacmViewInfo( + snmpEngine, viewName, subTree) + + # Allow bitmask specification in form of an OID + if rfc1902.OctetString('.').asOctets() in rfc1902.OctetString(subTreeMask): + subTreeMask = rfc1902.ObjectIdentifier(subTreeMask) + + if isinstance(subTreeMask, rfc1902.ObjectIdentifier): + subTreeMask = tuple(subTreeMask) + if len(subTreeMask) < len(subTree): + subTreeMask += (1,) * (len(subTree) - len(subTreeMask)) + + subTreeMask = rfc1902.OctetString.fromBinaryString( + ''.join(str(x) for x in subTreeMask)) + snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( ((vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'destroy'),) ) + snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( ((vacmViewTreeFamilyEntry.name + (1,) + tblIdx, viewName), (vacmViewTreeFamilyEntry.name + (2,) + tblIdx, subTree), - (vacmViewTreeFamilyEntry.name + (3,) + tblIdx, mask), + (vacmViewTreeFamilyEntry.name + (3,) + tblIdx, subTreeMask), (vacmViewTreeFamilyEntry.name + (4,) + tblIdx, viewType), (vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'createAndGo')) ) @@ -548,15 +558,16 @@ (groupName, securityLevel, readView, writeView, notifyView) = __cookVacmUserInfo(snmpEngine, securityModel, securityName, securityLevel) + addContext(snmpEngine, contextName) addVacmGroup(snmpEngine, groupName, securityModel, securityName) addVacmAccess(snmpEngine, groupName, contextName, securityModel, - securityLevel, 1, readView, writeView, notifyView) + securityLevel, 'exact', readView, writeView, notifyView) if readSubTree: - addVacmView(snmpEngine, readView, "included", readSubTree, null) + addVacmView(snmpEngine, readView, 'included', readSubTree, null) if writeSubTree: - addVacmView(snmpEngine, writeView, "included", writeSubTree, null) + addVacmView(snmpEngine, writeView, 'included', writeSubTree, null) if notifySubTree: - addVacmView(snmpEngine, notifyView, "included", notifySubTree, null) + addVacmView(snmpEngine, notifyView, 'included', notifySubTree, null) def delVacmUser(snmpEngine, securityModel, securityName, securityLevel, @@ -565,6 +576,7 @@ (groupName, securityLevel, readView, writeView, notifyView) = __cookVacmUserInfo(snmpEngine, securityModel, securityName, securityLevel) + delContext(snmpEngine, contextName) delVacmGroup(snmpEngine, securityModel, securityName) delVacmAccess(snmpEngine, groupName, contextName, securityModel, securityLevel) if readSubTree: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/pysnmp/hlapi/varbinds.py new/pysnmp-4.4.10/pysnmp/hlapi/varbinds.py --- old/pysnmp-4.4.9/pysnmp/hlapi/varbinds.py 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/pysnmp/hlapi/varbinds.py 2019-07-30 20:29:22.000000000 +0200 @@ -36,14 +36,15 @@ else: varBind = ObjectType(ObjectIdentity(varBind[0]), varBind[1]) - __varBinds.append(varBind.resolveWithMib(mibViewController)) + __varBinds.append(varBind.resolveWithMib(mibViewController, ignoreErrors=False)) return __varBinds def unmakeVarBinds(self, snmpEngine, varBinds, lookupMib=True): if lookupMib: mibViewController = self.getMibViewController(snmpEngine) - varBinds = [ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController) for x in varBinds] + varBinds = [ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib( + mibViewController) for x in varBinds] return varBinds @@ -52,7 +53,8 @@ def makeVarBinds(self, snmpEngine, varBinds): mibViewController = self.getMibViewController(snmpEngine) if isinstance(varBinds, NotificationType): - varBinds.resolveWithMib(mibViewController) + varBinds.resolveWithMib( + mibViewController, ignoreErrors=False) __varBinds = [] for varBind in varBinds: if isinstance(varBind, ObjectType): @@ -61,11 +63,13 @@ varBind = ObjectType(*varBind) else: varBind = ObjectType(ObjectIdentity(varBind[0]), varBind[1]) - __varBinds.append(varBind.resolveWithMib(mibViewController)) + __varBinds.append(varBind.resolveWithMib( + mibViewController, ignoreErrors=False)) return __varBinds def unmakeVarBinds(self, snmpEngine, varBinds, lookupMib=False): if lookupMib: mibViewController = self.getMibViewController(snmpEngine) - varBinds = [ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController) for x in varBinds] + varBinds = [ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib( + mibViewController) for x in varBinds] return varBinds diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/pysnmp/proto/acmod/rfc3415.py new/pysnmp-4.4.10/pysnmp/proto/acmod/rfc3415.py --- old/pysnmp-4.4.9/pysnmp/proto/acmod/rfc3415.py 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/pysnmp/proto/acmod/rfc3415.py 2019-07-30 20:29:22.000000000 +0200 @@ -16,6 +16,117 @@ _powOfTwoSeq = (128, 64, 32, 16, 8, 4, 2, 1) + def __init__(self): + self._contextBranchId = -1 + self._groupNameBranchId = -1 + self._accessBranchId = -1 + self._viewTreeBranchId = -1 + + self._contextMap = {} + self._groupNameMap = {} + self._accessMap = {} + self._viewTreeMap = {} + + def _addAccessEntry(self, groupName, contextPrefix, securityModel, + securityLevel, prefixMatch, readView, writeView, + notifyView): + if not groupName: + return + + groups = self._accessMap + + try: + views = groups[groupName] + + except KeyError: + views = groups[groupName] = {} + + for viewType, viewName in ( + ('read', readView), ('write', writeView), + ('notify', notifyView)): + + try: + matches = views[viewType] + + except KeyError: + matches = views[viewType] = {} + + try: + contexts = matches[prefixMatch] + + except KeyError: + contexts = matches[prefixMatch] = {} + + try: + models = contexts[contextPrefix] + + except KeyError: + models = contexts[contextPrefix] = {} + + try: + levels = models[securityModel] + + except KeyError: + levels = models[securityModel] = {} + + levels[securityLevel] = viewName + + def _getFamilyViewName(self, groupName, contextName, securityModel, securityLevel, viewType): + groups = self._accessMap + + try: + views = groups[groupName] + + except KeyError: + raise error.StatusInformation(errorIndication=errind.noGroupName) + + try: + matches = views[viewType] + + except KeyError: + raise error.StatusInformation(errorIndication=errind.noAccessEntry) + + try: + # vacmAccessTable #2: exact match shortcut + return matches[1][contextName][securityModel][securityLevel] + + except KeyError: + pass + + # vacmAccessTable #2: fuzzy look-up + + candidates = [] + + for match, names in matches.items(): + + for context, models in names.items(): + + if match == 1 and contextName != context: + continue + + if match == 2 and contextName[:len(context)] != context: + continue + + for model, levels in models.items(): + for level, viewName in levels.items(): + + # priorities: + # - matching securityModel + # - exact context name match + # - longer partial match + # - highest securityLevel + rating = securityModel == model, match == 1, len(context), level + + candidates.append((rating, viewName)) + + if not candidates: + raise error.StatusInformation(errorIndication=errind.notInView) + + candidates.sort() + + rating, viewName = candidates[0] + return viewName + def isAccessAllowed(self, snmpEngine, securityModel, @@ -24,118 +135,245 @@ viewType, contextName, variableName): + mibInstrumController = snmpEngine.msgAndPduDsp.mibInstrumController debug.logger & debug.flagACL and debug.logger( - 'isAccessAllowed: securityModel %s, securityName %s, securityLevel %s, viewType %s, contextName %s for variableName %s' % ( - securityModel, securityName, securityLevel, viewType, contextName, variableName)) + 'isAccessAllowed: securityModel %s, securityName %s, ' + 'securityLevel %s, viewType %s, contextName %s for ' + 'variableName %s' % (securityModel, securityName, + securityLevel, viewType, contextName, + variableName)) - # 3.2.1 - vacmContextEntry, = mibInstrumController.mibBuilder.importSymbols( - 'SNMP-VIEW-BASED-ACM-MIB', 'vacmContextEntry') + # Rebuild contextName map if changed - tblIdx = vacmContextEntry.getInstIdFromIndices(contextName) - try: - vacmContextEntry.getNode( - vacmContextEntry.name + (1,) + tblIdx - ).syntax + vacmContextName, = mibInstrumController.mibBuilder.importSymbols( + 'SNMP-VIEW-BASED-ACM-MIB', 'vacmContextName') + + if self._contextBranchId != vacmContextName.branchVersionId: + + self._contextMap.clear() + + nextMibNode = vacmContextName + + while True: + try: + nextMibNode = vacmContextName.getNextNode(nextMibNode.name) + + except NoSuchInstanceError: + break + + self._contextMap[nextMibNode.syntax] = True - except NoSuchInstanceError: + self._contextBranchId = vacmContextName.branchVersionId + + # 3.2.1 + if contextName not in self._contextMap: raise error.StatusInformation(errorIndication=errind.noSuchContext) + # Rebuild groupName map if changed + + vacmGroupName, = mibInstrumController.mibBuilder.importSymbols( + 'SNMP-VIEW-BASED-ACM-MIB', 'vacmGroupName') + + if self._groupNameBranchId != vacmGroupName.branchVersionId: + + vacmSecurityToGroupEntry, = mibInstrumController.mibBuilder.importSymbols( + 'SNMP-VIEW-BASED-ACM-MIB', 'vacmSecurityToGroupEntry') + + self._groupNameMap.clear() + + nextMibNode = vacmGroupName + + while True: + try: + nextMibNode = vacmGroupName.getNextNode(nextMibNode.name) + + except NoSuchInstanceError: + break + + instId = nextMibNode.name[len(vacmGroupName.name):] + + indices = vacmSecurityToGroupEntry.getIndicesFromInstId(instId) + + self._groupNameMap[indices] = nextMibNode.syntax + + self._groupNameBranchId = vacmGroupName.branchVersionId + # 3.2.2 - vacmSecurityToGroupEntry, = mibInstrumController.mibBuilder.importSymbols( - 'SNMP-VIEW-BASED-ACM-MIB', 'vacmSecurityToGroupEntry') - tblIdx = vacmSecurityToGroupEntry.getInstIdFromIndices( - securityModel, securityName - ) + indices = securityModel, securityName try: - vacmGroupName = vacmSecurityToGroupEntry.getNode( - vacmSecurityToGroupEntry.name + (3,) + tblIdx - ).syntax + groupName = self._groupNameMap[indices] - except NoSuchInstanceError: + except KeyError: raise error.StatusInformation(errorIndication=errind.noGroupName) - # 3.2.3 - vacmAccessEntry, = mibInstrumController.mibBuilder.importSymbols( - 'SNMP-VIEW-BASED-ACM-MIB', 'vacmAccessEntry' - ) - - # XXX partial context name match - tblIdx = vacmAccessEntry.getInstIdFromIndices( - vacmGroupName, contextName, securityModel, securityLevel - ) - - # 3.2.4 - if viewType == 'read': - entryIdx = vacmAccessEntry.name + (5,) + tblIdx - elif viewType == 'write': - entryIdx = vacmAccessEntry.name + (6,) + tblIdx - elif viewType == 'notify': - entryIdx = vacmAccessEntry.name + (7,) + tblIdx - else: - raise error.ProtocolError('Unknown view type %s' % viewType) + # Rebuild access map if changed - try: - viewName = vacmAccessEntry.getNode(entryIdx).syntax + vacmAccessStatus, = mibInstrumController.mibBuilder.importSymbols( + 'SNMP-VIEW-BASED-ACM-MIB', 'vacmAccessStatus') - except NoSuchInstanceError: - raise error.StatusInformation(errorIndication=errind.noAccessEntry) + if self._accessBranchId != vacmAccessStatus.branchVersionId: + + (vacmAccessEntry, + vacmAccessContextPrefix, + vacmAccessSecurityModel, + vacmAccessSecurityLevel, + vacmAccessContextMatch, + vacmAccessReadViewName, + vacmAccessWriteViewName, + vacmAccessNotifyViewName) = mibInstrumController.mibBuilder.importSymbols( + 'SNMP-VIEW-BASED-ACM-MIB', + 'vacmAccessEntry', + 'vacmAccessContextPrefix', + 'vacmAccessSecurityModel', + 'vacmAccessSecurityLevel', + 'vacmAccessContextMatch', + 'vacmAccessReadViewName', + 'vacmAccessWriteViewName', + 'vacmAccessNotifyViewName') + + self._accessMap.clear() + + nextMibNode = vacmAccessStatus + + while True: + try: + nextMibNode = vacmAccessStatus.getNextNode(nextMibNode.name) + + except NoSuchInstanceError: + break + + if nextMibNode.syntax != 1: # active row + continue + + instId = nextMibNode.name[len(vacmAccessStatus.name):] + + indices = vacmAccessEntry.getIndicesFromInstId(instId) + + vacmGroupName = indices[0] + + self._addAccessEntry( + vacmGroupName, + vacmAccessContextPrefix.getNode( + vacmAccessContextPrefix.name + instId).syntax, + vacmAccessSecurityModel.getNode( + vacmAccessSecurityModel.name + instId).syntax, + vacmAccessSecurityLevel.getNode( + vacmAccessSecurityLevel.name + instId).syntax, + vacmAccessContextMatch.getNode( + vacmAccessContextMatch.name + instId).syntax, + vacmAccessReadViewName.getNode( + vacmAccessReadViewName.name + instId).syntax, + vacmAccessWriteViewName.getNode( + vacmAccessWriteViewName.name + instId).syntax, + vacmAccessNotifyViewName.getNode( + vacmAccessNotifyViewName.name + instId).syntax + ) + + self._accessBranchId = vacmAccessStatus.branchVersionId + + viewName = self._getFamilyViewName( + groupName, contextName, securityModel, securityLevel, viewType) + + # Rebuild family subtree map if changed + + vacmViewTreeFamilyViewName, = mibInstrumController.mibBuilder.importSymbols( + 'SNMP-VIEW-BASED-ACM-MIB', 'vacmViewTreeFamilyViewName') + + if self._viewTreeBranchId != vacmViewTreeFamilyViewName.branchVersionId: + + (vacmViewTreeFamilySubtree, + vacmViewTreeFamilyMask, + vacmViewTreeFamilyType) = mibInstrumController.mibBuilder.importSymbols( + 'SNMP-VIEW-BASED-ACM-MIB', + 'vacmViewTreeFamilySubtree', + 'vacmViewTreeFamilyMask', + 'vacmViewTreeFamilyType') + + self._viewTreeMap.clear() - if not viewName: - raise error.StatusInformation(errorIndication=errind.noSuchView) + powerOfTwo = [2 ** exp for exp in range(7, -1, -1)] - # XXX split onto object & instance ? + nextMibNode = vacmViewTreeFamilyViewName + + while True: + try: + nextMibNode = vacmViewTreeFamilyViewName.getNextNode( + nextMibNode.name) + + except NoSuchInstanceError: + break + + if nextMibNode.syntax not in self._viewTreeMap: + self._viewTreeMap[nextMibNode.syntax] = [] + + instId = nextMibNode.name[len(vacmViewTreeFamilyViewName.name):] + + subtree = vacmViewTreeFamilySubtree.getNode( + vacmViewTreeFamilySubtree.name + instId).syntax + + mask = vacmViewTreeFamilyMask.getNode( + vacmViewTreeFamilyMask.name + instId).syntax + + mode = vacmViewTreeFamilyType.getNode( + vacmViewTreeFamilyType.name + instId).syntax + + mask = mask.asNumbers() + maskLength = min(len(mask) * 8, len(subtree)) + + ignoredSubOids = [ + i * 8 + j for i, octet in enumerate(mask) + for j, bit in enumerate(powerOfTwo) + if not (bit & octet) and i * 8 + j < maskLength + ] + + if ignoredSubOids: + pattern = list(subtree) + + for ignoredSubOid in ignoredSubOids: + pattern[ignoredSubOid] = 0 + + subtree = subtree.clone(pattern) + + entry = subtree, ignoredSubOids, mode == 1 + + self._viewTreeMap[nextMibNode.syntax].append(entry) + + for entries in self._viewTreeMap.values(): + entries.sort(key=lambda x: (len(x[0]), x[0])) + + self._viewTreeBranchId = vacmViewTreeFamilyViewName.branchVersionId # 3.2.5a - vacmViewTreeFamilyEntry, = mibInstrumController.mibBuilder.importSymbols( - 'SNMP-VIEW-BASED-ACM-MIB', 'vacmViewTreeFamilyEntry') - tblIdx = vacmViewTreeFamilyEntry.getInstIdFromIndices(viewName) - - # Walk over entries - initialTreeName = treeName = vacmViewTreeFamilyEntry.name + (2,) + tblIdx - maskName = vacmViewTreeFamilyEntry.name + (3,) + tblIdx - - while True: - vacmViewTreeFamilySubtree = vacmViewTreeFamilyEntry.getNextNode( - treeName - ) - vacmViewTreeFamilyMask = vacmViewTreeFamilyEntry.getNextNode( - maskName - ) - - treeName = vacmViewTreeFamilySubtree.name - maskName = vacmViewTreeFamilyMask.name - - if initialTreeName != treeName[:len(initialTreeName)]: - # 3.2.5b - raise error.StatusInformation(errorIndication=errind.notInView) - - l = len(vacmViewTreeFamilySubtree.syntax) - if l > len(variableName): - continue - - if vacmViewTreeFamilyMask.syntax: - mask = [] - for c in vacmViewTreeFamilyMask.syntax.asNumbers(): - mask.extend([b & c for b in self._powOfTwoSeq]) - - m = len(mask) - 1 - idx = l - 1 - while idx: - if (idx > m or mask[idx] and - vacmViewTreeFamilySubtree.syntax[idx] != variableName[idx]): - break - idx -= 1 - - if idx: - continue # no match - - else: # no mask - if vacmViewTreeFamilySubtree.syntax != variableName[:l]: - continue # no match + indices = viewName + + try: + entries = self._viewTreeMap[indices] + + except KeyError: + return error.StatusInformation(errorIndication=errind.notInView) + + accessAllowed = False + + for entry in entries: + subtree, ignoredSubOids, included = entry + + if ignoredSubOids: + subOids = list(variableName) + + for ignoredSubOid in ignoredSubOids: + subOids[ignoredSubOid] = 0 + + normalizedVariableName = subtree.clone(subOids) + + else: + normalizedVariableName = variableName + + if subtree.isPrefixOf(normalizedVariableName): + accessAllowed = included - # 3.2.5c - return error.StatusInformation(errorIndication=errind.accessAllowed) + # 3.2.5c + if not accessAllowed: + raise error.StatusInformation(errorIndication=errind.notInView) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/pysnmp/proto/api/v1.py new/pysnmp-4.4.10/pysnmp/proto/api/v1.py --- old/pysnmp-4.4.9/pysnmp/proto/api/v1.py 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/pysnmp/proto/api/v1.py 2019-07-30 20:29:22.000000000 +0200 @@ -66,7 +66,8 @@ pdu.setComponentByPosition( 2, self._errorIndex, verifyConstraints=False, matchTags=False, matchConstraints=False ) - pdu.setComponentByPosition(3) + varBindList = pdu.setComponentByPosition(3).getComponentByPosition(3) + varBindList.clear() @staticmethod def getRequestID(pdu): @@ -170,7 +171,8 @@ pdu.setComponentByPosition(2, self._genericTrap, verifyConstraints=False, matchTags=False, matchConstraints=False) pdu.setComponentByPosition(3, self._zeroInt, verifyConstraints=False, matchTags=False, matchConstraints=False) pdu.setComponentByPosition(4, self._zeroTime, verifyConstraints=False, matchTags=False, matchConstraints=False) - pdu.setComponentByPosition(5) + varBindList = pdu.setComponentByPosition(5).getComponentByPosition(5) + varBindList.clear() @staticmethod def getEnterprise(pdu): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/pysnmp/proto/api/v2c.py new/pysnmp-4.4.10/pysnmp/proto/api/v2c.py --- old/pysnmp-4.4.9/pysnmp/proto/api/v2c.py 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/pysnmp/proto/api/v2c.py 2019-07-30 20:29:22.000000000 +0200 @@ -91,7 +91,8 @@ pdu.setComponentByPosition( 2, self._maxRepetitions, verifyConstraints=False, matchTags=False, matchConstraints=False ) - pdu.setComponentByPosition(3) + varBindList = pdu.setComponentByPosition(3).getComponentByPosition(3) + varBindList.clear() @staticmethod def getNonRepeaters(pdu): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/pysnmp/proto/proxy/rfc2576.py new/pysnmp-4.4.10/pysnmp/proto/proxy/rfc2576.py --- old/pysnmp-4.4.9/pysnmp/proto/proxy/rfc2576.py 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/pysnmp/proto/proxy/rfc2576.py 2019-07-30 20:29:22.000000000 +0200 @@ -142,15 +142,17 @@ (oid, __v1ToV2ValueMap[v1Val.tagSet].clone(v1Val)) ) - if pduType in rfc3411.responseClassPDUs: - # 4.1.2.2.1&2 + if pduType not in rfc3411.notificationClassPDUs: errorStatus = int(v1.apiPDU.getErrorStatus(v1Pdu)) errorIndex = int(v1.apiPDU.getErrorIndex(v1Pdu, muteErrors=True)) - if errorStatus == 2: # noSuchName - if origV2Pdu.tagSet == v2c.GetNextRequestPDU.tagSet: - v2VarBinds = [(o, rfc1905.endOfMibView) for o, v in v2VarBinds] - else: - v2VarBinds = [(o, rfc1905.noSuchObject) for o, v in v2VarBinds] + + if pduType in rfc3411.responseClassPDUs: + # 4.1.2.2.1&2 + if errorStatus == 2: # noSuchName + if origV2Pdu.tagSet == v2c.GetNextRequestPDU.tagSet: + v2VarBinds = [(o, rfc1905.endOfMibView) for o, v in v2VarBinds] + else: + v2VarBinds = [(o, rfc1905.noSuchObject) for o, v in v2VarBinds] # partial one-to-one mapping - 4.2.1 v2c.apiPDU.setErrorStatus(v2Pdu, errorStatus) @@ -158,13 +160,11 @@ # 4.1.2.1 --> no-op - elif pduType in rfc3411.confirmedClassPDUs: - v2c.apiPDU.setErrorStatus(v2Pdu, 0) - v2c.apiPDU.setErrorIndex(v2Pdu, 0) - - if pduType not in rfc3411.notificationClassPDUs: v2c.apiPDU.setRequestID(v2Pdu, int(v1.apiPDU.getRequestID(v1Pdu))) + else: + v2c.apiPDU.setDefaults(v2Pdu) + v2c.apiPDU.setVarBinds(v2Pdu, v2VarBinds) debug.logger & debug.flagPrx and debug.logger('v1ToV2: v2Pdu %s' % v2Pdu.prettyPrint()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/pysnmp/smi/builder.py new/pysnmp-4.4.10/pysnmp/smi/builder.py --- old/pysnmp-4.4.9/pysnmp/smi/builder.py 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/pysnmp/smi/builder.py 2019-07-30 20:29:22.000000000 +0200 @@ -6,16 +6,38 @@ # import os import sys -import imp import struct import marshal import time import traceback try: + import importlib + + try: + PY_MAGIC_NUMBER = importlib.util.MAGIC_NUMBER + SOURCE_SUFFIXES = importlib.machinery.SOURCE_SUFFIXES + BYTECODE_SUFFIXES = importlib.machinery.BYTECODE_SUFFIXES + + except Exception: + raise ImportError() + +except ImportError: + import imp + + PY_MAGIC_NUMBER = imp.get_magic() + SOURCE_SUFFIXES = [s[0] for s in imp.get_suffixes() + if s[2] == imp.PY_SOURCE] + BYTECODE_SUFFIXES = [s[0] for s in imp.get_suffixes() + if s[2] == imp.PY_COMPILED] + +PY_SUFFIXES = SOURCE_SUFFIXES + BYTECODE_SUFFIXES + +try: from errno import ENOENT except ImportError: ENOENT = -1 + from pysnmp import version as pysnmp_version from pysnmp.smi import error from pysnmp import debug @@ -31,13 +53,7 @@ class __AbstractMibSource(object): def __init__(self, srcName): self._srcName = srcName - self.__magic = imp.get_magic() - self.__sfx = {} self.__inited = None - for sfx, mode, typ in imp.get_suffixes(): - if typ not in self.__sfx: - self.__sfx[typ] = [] - self.__sfx[typ].append((sfx, len(sfx), mode)) debug.logger & debug.flagBld and debug.logger('trying %s' % self) def __repr__(self): @@ -45,13 +61,13 @@ def _uniqNames(self, files): u = set() + for f in files: if f.startswith('__init__.'): continue - for typ in (imp.PY_SOURCE, imp.PY_COMPILED): - for sfx, sfxLen, mode in self.__sfx[typ]: - if f[-sfxLen:] == sfx: - u.add(f[:-sfxLen]) + + u.update(f[:-len(sfx)] for sfx in PY_SUFFIXES if f.endswith(sfx)) + return tuple(u) # MibSource API follows @@ -76,9 +92,10 @@ def read(self, f): pycTime = pyTime = -1 - for pycSfx, pycSfxLen, pycMode in self.__sfx[imp.PY_COMPILED]: + for pycSfx in BYTECODE_SUFFIXES: + try: - pycData, pycPath = self._getData(f + pycSfx, pycMode) + pycData, pycPath = self._getData(f + pycSfx, 'rb') except IOError: why = sys.exc_info()[1] @@ -91,7 +108,7 @@ raise error.MibLoadError('MIB file %s access error: %s' % (f + pycSfx, why)) else: - if self.__magic == pycData[:4]: + if PY_MAGIC_NUMBER == pycData[:4]: pycData = pycData[4:] pycTime = struct.unpack('<L', pycData[:4])[0] pycData = pycData[4:] @@ -103,7 +120,8 @@ else: debug.logger & debug.flagBld and debug.logger('bad magic in %s' % pycPath) - for pySfx, pySfxLen, pyMode in self.__sfx[imp.PY_SOURCE]: + for pySfx in SOURCE_SUFFIXES: + try: pyTime = self._getTimestamp(f + pySfx) @@ -125,7 +143,7 @@ return marshal.loads(pycData), pycSfx if pyTime != -1: - modData, pyPath = self._getData(f + pySfx, pyMode) + modData, pyPath = self._getData(f + pySfx, 'r') return compile(modData, pyPath, 'exec'), pyPath raise IOError(ENOENT, 'No suitable module found', f) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysnmp-4.4.9/pysnmp/smi/rfc1902.py new/pysnmp-4.4.10/pysnmp/smi/rfc1902.py --- old/pysnmp-4.4.9/pysnmp/smi/rfc1902.py 2019-02-09 16:02:16.000000000 +0100 +++ new/pysnmp-4.4.10/pysnmp/smi/rfc1902.py 2019-07-30 20:29:22.000000000 +0200 @@ -805,7 +805,7 @@ self.__args[0].loadMibs(*modNames) return self - def resolveWithMib(self, mibViewController): + def resolveWithMib(self, mibViewController, ignoreErrors=True): """Perform MIB variable ID and associated value conversion. Parameters @@ -813,6 +813,12 @@ mibViewController : :py:class:`~pysnmp.smi.view.MibViewController` class instance representing MIB browsing functionality. + Other Parameters + ---------------- + ignoreErrors: :py:class:`bool` + If `True` (default), ignore MIB object name or value casting + failures if possible. + Returns ------- : :py:class:`~pysnmp.smi.rfc1902.ObjectType` @@ -851,7 +857,8 @@ if not isinstance(self.__args[0].getMibNode(), (MibScalar, MibTableColumn)): - if not isinstance(self.__args[1], AbstractSimpleAsn1Item): + if (ignoreErrors and + not isinstance(self.__args[1], AbstractSimpleAsn1Item)): raise SmiError('MIB object %r is not OBJECT-TYPE (MIB not loaded?)' % (self.__args[0],)) self.__state |= self.stClean return self @@ -866,9 +873,15 @@ try: self.__args[1] = self.__args[0].getMibNode().getSyntax().clone(self.__args[1]) except PyAsn1Error: - raise SmiError('MIB object %r having type %r failed to cast value %r: %s' % ( - self.__args[0].prettyPrint(), self.__args[0].getMibNode().getSyntax().__class__.__name__, self.__args[1], - sys.exc_info()[1])) + err = ('MIB object %r having type %r failed to cast value ' + '%r: %s' % (self.__args[0].prettyPrint(), + self.__args[0].getMibNode().getSyntax().__class__.__name__, + self.__args[1], + sys.exc_info()[1])) + + if (not ignoreErrors or + not isinstance(self.__args[1], AbstractSimpleAsn1Item)): + raise SmiError(err) if rfc1902.ObjectIdentifier().isSuperTypeOf(self.__args[1], matchConstraints=False): self.__args[1] = ObjectIdentity(self.__args[1]).resolveWithMib(mibViewController) @@ -1100,7 +1113,7 @@ def isFullyResolved(self): return self.__state & self.stClean - def resolveWithMib(self, mibViewController): + def resolveWithMib(self, mibViewController, ignoreErrors=True): """Perform MIB variable ID conversion and notification objects expansion. Parameters @@ -1108,6 +1121,12 @@ mibViewController : :py:class:`~pysnmp.smi.view.MibViewController` class instance representing MIB browsing functionality. + Other Parameters + ---------------- + ignoreErrors: :py:class:`bool` + If `True` (default), ignore MIB object name or value casting + failures if possible. + Returns ------- : :py:class:`~pysnmp.smi.rfc1902.NotificationType` @@ -1145,7 +1164,7 @@ self.__varBinds.append( ObjectType(ObjectIdentity(v2c.apiTrapPDU.snmpTrapOID), - self.__objectIdentity).resolveWithMib(mibViewController) + self.__objectIdentity).resolveWithMib(mibViewController, ignoreErrors) ) SmiNotificationType, = mibViewController.mibBuilder.importSymbols('SNMPv2-SMI', 'NotificationType') @@ -1157,11 +1176,11 @@ if isinstance(mibNode, SmiNotificationType): for notificationObject in mibNode.getObjects(): objectIdentity = ObjectIdentity(*notificationObject + self.__instanceIndex).resolveWithMib( - mibViewController) + mibViewController, ignoreErrors) self.__varBinds.append( ObjectType(objectIdentity, self.__objects.get(notificationObject, rfc1905.unSpecified)).resolveWithMib( - mibViewController) + mibViewController, ignoreErrors) ) varBindsLocation[objectIdentity] = len(self.__varBinds) - 1 else: @@ -1171,7 +1190,7 @@ for varBinds in self.__additionalVarBinds: if not isinstance(varBinds, ObjectType): varBinds = ObjectType(ObjectIdentity(varBinds[0]), varBinds[1]) - varBinds.resolveWithMib(mibViewController) + varBinds.resolveWithMib(mibViewController, ignoreErrors) if varBinds[0] in varBindsLocation: self.__varBinds[varBindsLocation[varBinds[0]]] = varBinds else:
