Esempio n. 1
0
class AbstractLcdConfigurator:
    nextID = nextid.Integer(0xffffffff)
    cacheKeys = []
    def _getCache(self, snmpEngine):
        cacheId = self.__class__.__name__
        cache = snmpEngine.getUserContext(cacheId)
        if cache is None:
            cache = dict([(x,{}) for x in self.cacheKeys])
            snmpEngine.setUserContext(**{cacheId: cache})
        return cache

    def configure(self, snmpEngine, authData, transportTarget): pass
    def unconfigure(self, snmpEngine, authData=None): pass
Esempio n. 2
0
class Cache(object):
    __stateReference = nextid.Integer(0xffffff)

    def __init__(self):
        self.__cacheEntries = {}

    def push(self, **securityData):
        stateReference = self.__stateReference()
        self.__cacheEntries[stateReference] = securityData
        return stateReference

    def pop(self, stateReference):
        if stateReference in self.__cacheEntries:
            return self.__cacheEntries.pop(stateReference)

        raise error.ProtocolError(
            'Cache miss for stateReference=%s at '
            '%s' % (stateReference, self))
Esempio n. 3
0
    def __init__(self, mibInstrumController=None):
        if mibInstrumController is None:
            self.mibInstrumController = instrum.MibInstrumController(
                builder.MibBuilder())
        else:
            self.mibInstrumController = mibInstrumController

        self.mibInstrumController.mibBuilder.loadModules(
            'SNMPv2-MIB', 'SNMP-MPD-MIB', 'SNMP-COMMUNITY-MIB',
            'SNMP-TARGET-MIB', 'SNMP-USER-BASED-SM-MIB')

        # Requests cache
        self.__cache = cache.Cache()

        # Registered context engine IDs
        self.__appsRegistration = {}

        # Source of sendPduHandle and cache of requesting apps
        self.__sendPduHandle = nextid.Integer(0xffffff)

        # To pass transport info to app (legacy)
        self.__transportInfo = {}
Esempio n. 4
0
import sys
from pyasn1.compat.octets import null
from pysnmp.entity.rfc3413 import config
from pysnmp.proto.proxy import rfc2576
from pysnmp.proto import rfc3411
from pysnmp.proto.api import v2c
from pysnmp.proto import error
from pysnmp.smi import view, rfc1902
from pysnmp import nextid
from pysnmp import debug

getNextHandle = nextid.Integer(0x7fffffff)

class NotificationOriginator:
    acmID = 3  # default MIB access control method to use
    def __init__(self, snmpContext=None):
        self.__pendingReqs = {}
        self.__pendingNotifications = {}
        self.snmpContext = snmpContext  # this is deprecated

    def processResponsePdu(self,
                           snmpEngine,
                           messageProcessingModel,
                           securityModel,
                           securityName,
                           securityLevel,
                           contextEngineId,
                           contextName,
                           pduVersion,
                           PDU,
                           statusInformation,
Esempio n. 5
0
            1).setComponentByType(val.getTagSet(),
                                  val,
                                  verifyConstraints=False,
                                  matchTags=False,
                                  matchConstraints=False,
                                  innerFlag=True)
        return varBind

    @staticmethod
    def getOIDVal(varBind):
        return varBind[0], varBind[1].getComponent(1)


apiVarBind = VarBindAPI()

getNextRequestID = nextid.Integer(0xffffff)


class PDUAPI(object):
    _errorStatus = rfc1157.errorStatus.clone(0)
    _errorIndex = Integer(0)

    def setDefaults(self, pdu):
        pdu.setComponentByPosition(0,
                                   getNextRequestID(),
                                   verifyConstraints=False,
                                   matchTags=False,
                                   matchConstraints=False)
        pdu.setComponentByPosition(1,
                                   self._errorStatus,
                                   verifyConstraints=False,
Esempio n. 6
0
from pysnmp.entity.rfc3413.oneliner import cmdgen

# Auth protocol
usmHMACMD5AuthProtocol = config.usmHMACMD5AuthProtocol
usmHMACSHAAuthProtocol = config.usmHMACSHAAuthProtocol
usmNoAuthProtocol = config.usmNoAuthProtocol

# Privacy protocol
usmDESPrivProtocol = config.usmDESPrivProtocol
usm3DESEDEPrivProtocol = config.usm3DESEDEPrivProtocol
usmAesCfb128Protocol = config.usmAesCfb128Protocol
usmAesCfb192Protocol = config.usmAesCfb192Protocol
usmAesCfb256Protocol = config.usmAesCfb256Protocol
usmNoPrivProtocol = config.usmNoPrivProtocol

nextID = nextid.Integer(0xffffffff)


class AsynNotificationOriginator(cmdgen.AsynCommandGenerator):
    def __init__(self, snmpEngine=None, snmpContext=None):
        cmdgen.AsynCommandGenerator.__init__(self, snmpEngine)
        self.snmpContext = snmpContext
        self.__knownNotifyNames = {}
        self.__knownAuths = {}

    def __del__(self):
        self.uncfgNtfOrg()

    def cfgNtfOrg(self, authData, transportTarget, notifyType):
        addrName, paramsName = self.cfgCmdGen(authData, transportTarget)
        tagList = transportTarget.tagList.split()
Esempio n. 7
0
class MibInstrumController(AbstractMibInstrumController):
    STATUS_OK = 'ok'
    STATUS_ERROR = 'err'
    
    STATE_START = 'start'
    STATE_STOP = 'stop'
    STATE_ANY = '*'
    # These states are actually methods of the MIB objects
    STATE_READ_TEST = 'readTest'
    STATE_READ_GET = 'readGet'
    STATE_READ_TEST_NEXT = 'readTestNext'
    STATE_READ_GET_NEXT = 'readGetNext'
    STATE_WRITE_TEST = 'writeTest'
    STATE_WRITE_COMMIT = 'writeCommit'
    STATE_WRITE_CLEANUP = 'writeCleanup'
    STATE_WRITE_UNDO = 'writeUndo'

    fsmReadVar = {
        # ( state, status ) -> newState
        (STATE_START, STATUS_OK): STATE_READ_TEST,
        (STATE_READ_TEST, STATUS_OK): STATE_READ_GET,
        (STATE_READ_GET, STATUS_OK): STATE_STOP,
        (STATE_ANY, STATUS_ERROR): STATE_STOP
    }
    fsmReadNextVar = {
        # ( state, status ) -> newState
        (STATE_START, STATUS_OK): STATE_READ_TEST_NEXT,
        (STATE_READ_TEST_NEXT, STATUS_OK): STATE_READ_GET_NEXT,
        (STATE_READ_GET_NEXT, STATUS_OK): STATE_STOP,
        (STATE_ANY, STATUS_ERROR): STATE_STOP
    }
    fsmWriteVar = {
        # ( state, status ) -> newState
        (STATE_START, STATUS_OK): STATE_WRITE_TEST,
        (STATE_WRITE_TEST, STATUS_OK): STATE_WRITE_COMMIT,
        (STATE_WRITE_COMMIT, STATUS_OK): STATE_WRITE_CLEANUP,
        (STATE_WRITE_CLEANUP, STATUS_OK): STATE_READ_TEST,
        # Do read after successful write
        (STATE_READ_TEST, STATUS_OK): STATE_READ_GET,
        (STATE_READ_GET, STATUS_OK): STATE_STOP,
        # Error handling
        (STATE_WRITE_TEST, STATUS_ERROR): STATE_WRITE_CLEANUP,
        (STATE_WRITE_COMMIT, STATUS_ERROR): STATE_WRITE_UNDO,
        (STATE_WRITE_UNDO, STATUS_OK): STATE_READ_TEST,
        # Ignore read errors (removed columns)
        (STATE_READ_TEST, STATUS_ERROR): STATE_STOP,
        (STATE_READ_GET, STATUS_ERROR): STATE_STOP,
        (STATE_ANY, STATUS_ERROR): STATE_STOP
    }

    FSM_CONTEXT = '_fsmContext'

    FSM_SESSION_ID = nextid.Integer(0xffffffff)

    def __init__(self, mibBuilder):
        self.mibBuilder = mibBuilder
        self.lastBuildId = -1
        self.lastBuildSyms = {}

    def getMibBuilder(self):
        return self.mibBuilder

    # MIB indexing

    def __indexMib(self):
        # Build a tree from MIB objects found at currently loaded modules
        if self.lastBuildId == self.mibBuilder.lastBuildId:
            return

        (MibScalarInstance, MibScalar, MibTableColumn, MibTableRow,
         MibTable) = self.mibBuilder.importSymbols(
            'SNMPv2-SMI', 'MibScalarInstance', 'MibScalar',
            'MibTableColumn', 'MibTableRow', 'MibTable'
        )

        mibTree, = self.mibBuilder.importSymbols('SNMPv2-SMI', 'iso')

        #
        # Management Instrumentation gets organized as follows:
        #
        # MibTree
        #   |
        #   +----MibScalar
        #   |        |
        #   |        +-----MibScalarInstance
        #   |
        #   +----MibTable
        #   |
        #   +----MibTableRow
        #          |
        #          +-------MibTableColumn
        #                        |
        #                        +------MibScalarInstance(s)
        #
        # Mind you, only Managed Objects get indexed here, various MIB defs and
        # constants can't be SNMP managed so we drop them.
        #
        scalars = {}
        instances = {}
        tables = {}
        rows = {}
        cols = {}

        # Sort by module name to give user a chance to slip-in
        # custom MIB modules (that would be sorted out first)
        mibSymbols = list(self.mibBuilder.mibSymbols.items())
        mibSymbols.sort(key=lambda x: x[0], reverse=True)

        for modName, mibMod in mibSymbols:
            for symObj in mibMod.values():
                if isinstance(symObj, MibTable):
                    tables[symObj.name] = symObj
                elif isinstance(symObj, MibTableRow):
                    rows[symObj.name] = symObj
                elif isinstance(symObj, MibTableColumn):
                    cols[symObj.name] = symObj
                elif isinstance(symObj, MibScalarInstance):
                    instances[symObj.name] = symObj
                elif isinstance(symObj, MibScalar):
                    scalars[symObj.name] = symObj

        # Detach items from each other
        for symName, parentName in self.lastBuildSyms.items():
            if parentName in scalars:
                scalars[parentName].unregisterSubtrees(symName)
            elif parentName in cols:
                cols[parentName].unregisterSubtrees(symName)
            elif parentName in rows:
                rows[parentName].unregisterSubtrees(symName)
            else:
                mibTree.unregisterSubtrees(symName)

        lastBuildSyms = {}

        # Attach Managed Objects Instances to Managed Objects
        for inst in instances.values():
            if inst.typeName in scalars:
                scalars[inst.typeName].registerSubtrees(inst)
            elif inst.typeName in cols:
                cols[inst.typeName].registerSubtrees(inst)
            else:
                raise error.SmiError(
                    'Orphan MIB scalar instance %r at %r' % (inst, self)
                )
            lastBuildSyms[inst.name] = inst.typeName

        # Attach Table Columns to Table Rows
        for col in cols.values():
            rowName = col.name[:-1]  # XXX
            if rowName in rows:
                rows[rowName].registerSubtrees(col)
            else:
                raise error.SmiError(
                    'Orphan MIB table column %r at %r' % (col, self)
                )
            lastBuildSyms[col.name] = rowName

        # Attach Table Rows to MIB tree
        for row in rows.values():
            mibTree.registerSubtrees(row)
            lastBuildSyms[row.name] = mibTree.name

        # Attach Tables to MIB tree
        for table in tables.values():
            mibTree.registerSubtrees(table)
            lastBuildSyms[table.name] = mibTree.name

        # Attach Scalars to MIB tree
        for scalar in scalars.values():
            mibTree.registerSubtrees(scalar)
            lastBuildSyms[scalar.name] = mibTree.name

        self.lastBuildSyms = lastBuildSyms

        self.lastBuildId = self.mibBuilder.lastBuildId

        debug.logger & debug.flagIns and debug.logger('__indexMib: rebuilt')

    # MIB instrumentation

    def _flipFlopFsmCb(self, varBind, **context):
        fsmContext = context[self.FSM_CONTEXT]

        varBinds = fsmContext['varBinds']

        idx = context.pop('idx')

        if idx >= 0:
            fsmContext['count'] += 1

            varBinds[idx] = varBind

            debug.logger & debug.flagIns and debug.logger(
                '_flipFlopFsmCb: var-bind %d, processed %d, expected %d' % (idx, fsmContext['count'], len(varBinds)))

            if fsmContext['count'] < len(varBinds):
                return

        debug.logger & debug.flagIns and debug.logger(
            '_flipFlopFsmCb: finished, output %r' % (varBinds,))

        fsmCallable = fsmContext['fsmCallable']

        fsmCallable(**context)

    def flipFlopFsm(self, fsmTable, *varBinds, **context):
        try:
            fsmContext = context[self.FSM_CONTEXT]

        except KeyError:
            self.__indexMib()

            fsmContext = context[self.FSM_CONTEXT] = dict(
                sessionId=self.FSM_SESSION_ID(),
                varBinds=list(varBinds[:]),
                fsmCallable=functools.partial(self.flipFlopFsm, fsmTable, *varBinds),
                state=self.STATE_START, status=self.STATUS_OK
            )

            debug.logger & debug.flagIns and debug.logger('flipFlopFsm: input var-binds %r' % (varBinds,))

        mibTree, = self.mibBuilder.importSymbols('SNMPv2-SMI', 'iso')

        state = fsmContext['state']
        status = fsmContext['status']

        debug.logger & debug.flagIns and debug.logger(
            'flipFlopFsm: current state %s, status %s' % (state, status))

        try:
            newState = fsmTable[(state, status)]

        except KeyError:
            try:
                newState = fsmTable[(self.STATE_ANY, status)]

            except KeyError:
                raise error.SmiError('Unresolved FSM state %s, %s' % (state, status))

        debug.logger & debug.flagIns and debug.logger(
            'flipFlopFsm: state %s status %s -> new state %s' % (state, status, newState))

        state = newState

        if state == self.STATE_STOP:
            context.pop(self.FSM_CONTEXT, None)

            cbFun = context.get('cbFun')
            if cbFun:
                varBinds = fsmContext['varBinds']
                cbFun(varBinds, **context)

            return

        fsmContext.update(state=state, count=0)

        # the case of no var-binds
        if not varBinds:
            return self._flipFlopFsmCb(None, idx=-1, **context)

        mgmtFun = getattr(mibTree, state, None)
        if not mgmtFun:
            raise error.SmiError(
                'Unsupported state handler %s at %s' % (state, self)
            )

        for idx, varBind in enumerate(varBinds):
            try:
                # TODO: managed objects to run asynchronously
                #mgmtFun(varBind, idx=idx, **context)
                self._flipFlopFsmCb(mgmtFun(varBind, idx=idx, **context), idx=idx, **context)

            except error.SmiError:
                exc = sys.exc_info()
                debug.logger & debug.flagIns and debug.logger(
                    'flipFlopFsm: fun %s exception %s for %r with traceback: %s' % (
                        mgmtFun, exc[0], varBind, traceback.format_exception(*exc)))

                varBind = varBind[0], exc

                fsmContext['status'] = self.STATUS_ERROR

                self._flipFlopFsmCb(varBind, idx=idx, **context)

                return

            else:
                debug.logger & debug.flagIns and debug.logger(
                    'flipFlopFsm: func %s initiated for %r' % (mgmtFun, varBind))

    def readVars(self, *varBinds, **context):
        self.flipFlopFsm(self.fsmReadVar, *varBinds, **context)

    def readNextVars(self, *varBinds, **context):
        self.flipFlopFsm(self.fsmReadNextVar, *varBinds, **context)

    def writeVars(self, *varBinds, **context):
        self.flipFlopFsm(self.fsmWriteVar, *varBinds, **context)
Esempio n. 8
0
class Cache(object):
    __stateReference = nextid.Integer(0xffffff)
    __msgID = nextid.Integer(0xffffff)

    def __init__(self):
        self.__msgIdIndex = {}
        self.__stateReferenceIndex = {}
        self.__sendPduHandleIdx = {}
        # Message expiration mechanics
        self.__expirationQueue = {}
        self.__expirationTimer = 0

    # Server mode cache handling

    def newStateReference(self):
        return self.__stateReference()

    def pushByStateRef(self, stateReference, **msgInfo):
        if stateReference in self.__stateReferenceIndex:
            raise error.ProtocolError('Cache dup for stateReference=%s at %s' %
                                      (stateReference, self))
        expireAt = self.__expirationTimer + 600
        self.__stateReferenceIndex[stateReference] = msgInfo, expireAt

        # Schedule to expire
        if expireAt not in self.__expirationQueue:
            self.__expirationQueue[expireAt] = {}
        if 'stateReference' not in self.__expirationQueue[expireAt]:
            self.__expirationQueue[expireAt]['stateReference'] = {}
        self.__expirationQueue[expireAt]['stateReference'][stateReference] = 1

    def popByStateRef(self, stateReference):
        if stateReference in self.__stateReferenceIndex:
            cacheInfo = self.__stateReferenceIndex[stateReference]
        else:
            raise error.ProtocolError(
                'Cache miss for stateReference=%s at %s' %
                (stateReference, self))
        del self.__stateReferenceIndex[stateReference]
        cacheEntry, expireAt = cacheInfo
        del self.__expirationQueue[expireAt]['stateReference'][stateReference]
        return cacheEntry

    # Client mode cache handling

    def newMsgID(self):
        return self.__msgID()

    def pushByMsgId(self, msgId, **msgInfo):
        if msgId in self.__msgIdIndex:
            raise error.ProtocolError('Cache dup for msgId=%s at %s' %
                                      (msgId, self))
        expireAt = self.__expirationTimer + 600
        self.__msgIdIndex[msgId] = msgInfo, expireAt

        self.__sendPduHandleIdx[msgInfo['sendPduHandle']] = msgId

        # Schedule to expire
        if expireAt not in self.__expirationQueue:
            self.__expirationQueue[expireAt] = {}
        if 'msgId' not in self.__expirationQueue[expireAt]:
            self.__expirationQueue[expireAt]['msgId'] = {}
        self.__expirationQueue[expireAt]['msgId'][msgId] = 1

    def popByMsgId(self, msgId):
        if msgId in self.__msgIdIndex:
            cacheInfo = self.__msgIdIndex[msgId]
        else:
            raise error.ProtocolError('Cache miss for msgId=%s at %s' %
                                      (msgId, self))
        msgInfo, expireAt = cacheInfo
        del self.__sendPduHandleIdx[msgInfo['sendPduHandle']]
        del self.__msgIdIndex[msgId]
        cacheEntry, expireAt = cacheInfo
        del self.__expirationQueue[expireAt]['msgId'][msgId]
        return cacheEntry

    def popBySendPduHandle(self, sendPduHandle):
        if sendPduHandle in self.__sendPduHandleIdx:
            self.popByMsgId(self.__sendPduHandleIdx[sendPduHandle])

    def expireCaches(self):
        # Uses internal clock to expire pending messages
        if self.__expirationTimer in self.__expirationQueue:
            cacheInfo = self.__expirationQueue[self.__expirationTimer]
            if 'stateReference' in cacheInfo:
                for stateReference in cacheInfo['stateReference']:
                    del self.__stateReferenceIndex[stateReference]
            if 'msgId' in cacheInfo:
                for msgId in cacheInfo['msgId']:
                    del self.__msgIdIndex[msgId]
            del self.__expirationQueue[self.__expirationTimer]
        self.__expirationTimer += 1