Ejemplo n.º 1
0
 def prettyIn(self, value):
     if not has_ipv6:
         raise error.PySnmpError('IPv6 not supported by platform')
     if isinstance(value, tuple):
         value = inet_pton(socket.AF_INET6, value[0]) + int2oct((value[1] >> 8) & 0xff) + int2oct(value[1] & 0xff)
     return OctetString.prettyIn(self, value)
Ejemplo n.º 2
0
 def n_VersionInfo(self, cbCtx, node):
     raise error.PySnmpError()
Ejemplo n.º 3
0
 def verifyDispatcherCompatibility(self, snmpEngine):
     if not self.protoTransport.isCompatibleWithDispatcher(
             snmpEngine.transportDispatcher):
         raise error.PySnmpError(
             'Transport %r is not compatible with dispatcher %r' %
             (self.protoTransport, snmpEngine.transportDispatcher))
Ejemplo n.º 4
0
 def unregisterTransportDispatcher(self, recvId=None):
     if self.transportDispatcher is None:
         raise error.PySnmpError('Transport dispatcher not registered')
     self.transportDispatcher.unregisterRecvCbFun(recvId)
     self.transportDispatcher.unregisterTimerCbFun()
     self.transportDispatcher = None
Ejemplo n.º 5
0
    def configure(self, snmpEngine, authData, transportTarget, contextName,
                  **options):
        cache = self._getCache(snmpEngine)

        if isinstance(authData, CommunityData):
            if authData.communityIndex not in cache['auth']:
                config.addV1System(snmpEngine, authData.communityIndex,
                                   authData.communityName,
                                   authData.contextEngineId,
                                   authData.contextName, authData.tag,
                                   authData.securityName)

                cache['auth'][authData.communityIndex] = authData

        elif isinstance(authData, UsmUserData):
            authDataKey = authData.userName, authData.securityEngineId

            if authDataKey not in cache['auth']:
                config.addV3User(snmpEngine,
                                 authData.userName,
                                 authData.authProtocol,
                                 authData.authKey,
                                 authData.privProtocol,
                                 authData.privKey,
                                 authData.securityEngineId,
                                 securityName=authData.securityName)

                cache['auth'][authDataKey] = authData

        else:
            raise error.PySnmpError('Unsupported authentication object')

        paramsKey = (authData.securityName, authData.securityLevel,
                     authData.mpModel)

        if paramsKey in cache['parm']:
            paramsName, useCount = cache['parm'][paramsKey]

            cache['parm'][paramsKey] = paramsName, useCount + 1

        else:
            paramsName = 'p%s' % self.nextID()
            config.addTargetParams(snmpEngine, paramsName,
                                   authData.securityName,
                                   authData.securityLevel, authData.mpModel)

            cache['parm'][paramsKey] = paramsName, 1

        if transportTarget.TRANSPORT_DOMAIN in cache['tran']:
            transport, useCount = cache['tran'][
                transportTarget.TRANSPORT_DOMAIN]
            transportTarget.verifyDispatcherCompatibility(snmpEngine)

            cache['tran'][
                transportTarget.TRANSPORT_DOMAIN] = transport, useCount + 1

        elif config.getTransport(snmpEngine, transportTarget.TRANSPORT_DOMAIN):
            transportTarget.verifyDispatcherCompatibility(snmpEngine)

        else:
            transport = transportTarget.openClientMode()

            config.addTransport(snmpEngine, transportTarget.TRANSPORT_DOMAIN,
                                transport)

            cache['tran'][transportTarget.TRANSPORT_DOMAIN] = transport, 1

        transportKey = (paramsName, transportTarget.TRANSPORT_DOMAIN,
                        transportTarget.transportAddr, transportTarget.timeout,
                        transportTarget.retries, transportTarget.tagList,
                        transportTarget.iface)

        if transportKey in cache['addr']:
            addrName, useCount = cache['addr'][transportKey]
            cache['addr'][transportKey] = addrName, useCount + 1

        else:
            addrName = 'a%s' % self.nextID()

            config.addTargetAddr(snmpEngine, addrName,
                                 transportTarget.TRANSPORT_DOMAIN,
                                 transportTarget.transportAddr, paramsName,
                                 transportTarget.timeout * 100,
                                 transportTarget.retries,
                                 transportTarget.tagList)

            cache['addr'][transportKey] = addrName, 1

        return addrName, paramsName
Ejemplo n.º 6
0
        if len(node) > 2:
            opt = node[2].attr
        else:
            opt = node[1].attr
        for c in map(None, opt):
            if c == 'i':
                ctx['informMode'] = 1

    def n_EnterpriseOid(self, (snmpEngine, ctx), node):
        ctx['EnterpriseOid'] = node[0].attr

    def n_AgentName(self, (snmpEngine, ctx), node):
        try:
            ctx['AgentName'] = socket.gethostbyname(node[0].attr)
        except socket.error, why:
            raise error.PySnmpError('Bad agent name %s: %s' %
                                    (node[0].attr, why))

    def n_GenericTrap(self, (snmpEngine, ctx), node):
        ctx['GenericTrap'] = node[0].attr

    def n_SpecificTrap(self, (snmpEngine, ctx), node):
        ctx['SpecificTrap'] = node[0].attr

    def n_Uptime(self, (snmpEngine, ctx), node):
        ctx['Uptime'] = long(node[0].attr)

    def n_TrapV1Params_exit(self, (snmpEngine, ctx), node):
        v1Pdu = v1.TrapPDU()
        v1.apiTrapPDU.setDefaults(v1Pdu)
        if ctx.has_key('EnterpriseOid'):
            v1.apiTrapPDU.setEnterprise(v1Pdu, ctx['EnterpriseOid'])
Ejemplo n.º 7
0
    def __init__(self,
                 snmpEngineID=None,
                 maxMessageSize=65507,
                 msgAndPduDsp=None):
        self.cache = {}

        self.observer = observer.MetaObserver()

        if msgAndPduDsp is None:
            self.msgAndPduDsp = MsgAndPduDispatcher()
        else:
            self.msgAndPduDsp = msgAndPduDsp
        self.messageProcessingSubsystems = {
            SnmpV1MessageProcessingModel.messageProcessingModelID:
            SnmpV1MessageProcessingModel(),
            SnmpV2cMessageProcessingModel.messageProcessingModelID:
            SnmpV2cMessageProcessingModel(),
            SnmpV3MessageProcessingModel.messageProcessingModelID:
            SnmpV3MessageProcessingModel()
        }
        self.securityModels = {
            SnmpV1SecurityModel.securityModelID: SnmpV1SecurityModel(),
            SnmpV2cSecurityModel.securityModelID: SnmpV2cSecurityModel(),
            SnmpUSMSecurityModel.securityModelID: SnmpUSMSecurityModel()
        }
        self.accessControlModel = {
            void.Vacm.accessModelID: void.Vacm(),
            rfc3415.Vacm.accessModelID: rfc3415.Vacm()
        }

        self.transportDispatcher = None

        if self.msgAndPduDsp.mibInstrumController is None:
            raise error.PySnmpError('MIB instrumentation does not yet exist')
        snmpEngineMaxMessageSize, = self.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineMaxMessageSize')
        snmpEngineMaxMessageSize.syntax = snmpEngineMaxMessageSize.syntax.clone(
            maxMessageSize)
        snmpEngineBoots, = self.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineBoots')
        snmpEngineBoots.syntax += 1
        origSnmpEngineID, = self.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineID')

        if snmpEngineID is None:
            self.snmpEngineID = origSnmpEngineID.syntax
        else:
            origSnmpEngineID.syntax = origSnmpEngineID.syntax.clone(
                snmpEngineID)
            self.snmpEngineID = origSnmpEngineID.syntax

            debug.logger & debug.flagApp and debug.logger(
                'SnmpEngine: using custom SNMP Engine ID: %s' %
                self.snmpEngineID.prettyPrint())

            # Attempt to make some of snmp Engine settings persistent.
            # This should probably be generalized as a non-volatile MIB store.

            persistentPath = os.path.join(tempfile.gettempdir(), '__pysnmp',
                                          self.snmpEngineID.prettyPrint())

            debug.logger & debug.flagApp and debug.logger(
                'SnmpEngine: using persistent directory: %s' % persistentPath)

            if not os.path.exists(persistentPath):
                try:
                    os.makedirs(persistentPath)
                except OSError:
                    return

            f = os.path.join(persistentPath, 'boots')
            try:
                snmpEngineBoots.syntax = snmpEngineBoots.syntax.clone(
                    open(f).read())
            except Exception:
                pass

            try:
                snmpEngineBoots.syntax += 1
            except Exception:
                snmpEngineBoots.syntax = snmpEngineBoots.syntax.clone(1)

            try:
                fd, fn = tempfile.mkstemp(dir=persistentPath)
                os.write(fd, str2octs(snmpEngineBoots.syntax.prettyPrint()))
                os.close(fd)
                os.rename(fn, f)
            except Exception:
                debug.logger & debug.flagApp and debug.logger(
                    'SnmpEngine: could not stored SNMP Engine Boots: %s' %
                    sys.exc_info()[1])
            else:
                debug.logger & debug.flagApp and debug.logger(
                    'SnmpEngine: stored SNMP Engine Boots: %s' %
                    snmpEngineBoots.syntax.prettyPrint())
Ejemplo n.º 8
0
    def processResponsePdu(self, snmpEngine, messageProcessingModel,
                           securityModel, securityName, securityLevel,
                           contextEngineId, contextName, pduVersion, PDU,
                           statusInformation, sendPduHandle, cbCtx):
        origSendRequestHandle, cbFun, cbCtx = cbCtx

        # 3.1.1
        if sendPduHandle not in self.__pendingReqs:
            raise error.PySnmpError('Missing sendPduHandle %s' % sendPduHandle)

        (origTransportDomain, origTransportAddress, origMessageProcessingModel,
         origSecurityModel, origSecurityName, origSecurityLevel,
         origContextEngineId, origContextName, origPduVersion, origPdu,
         origTimeout, origRetryCount, origRetries,
         origDiscoveryRetries) = self.__pendingReqs.pop(sendPduHandle)

        snmpEngine.transportDispatcher.jobFinished(id(self))

        # 3.1.3
        if statusInformation:
            debug.logger & debug.flagApp and debug.logger(
                'processResponsePdu: sendPduHandle %s, statusInformation %s' %
                (sendPduHandle, statusInformation))

            errorIndication = statusInformation['errorIndication']

            if errorIndication in (errind.notInTimeWindow,
                                   errind.unknownEngineID):
                origDiscoveryRetries += 1
                origRetries = 0
            else:
                origDiscoveryRetries = 0
                origRetries += 1

            if origRetries > origRetryCount or origDiscoveryRetries > self.__options.get(
                    'discoveryRetries', 4):
                debug.logger & debug.flagApp and debug.logger(
                    'processResponsePdu: sendPduHandle %s, retry count %d exceeded'
                    % (sendPduHandle, origRetries))
                cbFun(snmpEngine, origSendRequestHandle, errorIndication, None,
                      cbCtx)
                return

            # User-side API assumes SMIv2
            if origMessageProcessingModel == 0:
                reqPDU = rfc2576.v2ToV1(origPdu)
                pduVersion = 0
            else:
                reqPDU = origPdu
                pduVersion = 1

            try:
                sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu(
                    snmpEngine, origTransportDomain, origTransportAddress,
                    origMessageProcessingModel, origSecurityModel,
                    origSecurityName, origSecurityLevel, origContextEngineId,
                    origContextName, pduVersion, reqPDU, True, origTimeout,
                    self.processResponsePdu,
                    (origSendRequestHandle, cbFun, cbCtx))

                snmpEngine.transportDispatcher.jobStarted(id(self))

                self.__pendingReqs[sendPduHandle] = (
                    origTransportDomain, origTransportAddress,
                    origMessageProcessingModel, origSecurityModel,
                    origSecurityName, origSecurityLevel, origContextEngineId,
                    origContextName, origPduVersion, origPdu, origTimeout,
                    origRetryCount, origRetries, origDiscoveryRetries)
                return

            except StatusInformation:
                statusInformation = sys.exc_info()[1]
                debug.logger & debug.flagApp and debug.logger(
                    'processResponsePdu: origSendRequestHandle %s, _sendPdu() failed with %r'
                    % (sendPduHandle, statusInformation))
                cbFun(snmpEngine, origSendRequestHandle,
                      statusInformation['errorIndication'], None, cbCtx)
                return

        if (origMessageProcessingModel != messageProcessingModel
                or origSecurityModel != securityModel
                or origSecurityName != origSecurityName or origContextEngineId
                and origContextEngineId != contextEngineId
                or origContextName and origContextName != contextName
                or origPduVersion != pduVersion):
            debug.logger & debug.flagApp and debug.logger(
                'processResponsePdu: sendPduHandle %s, request/response data mismatch'
                % sendPduHandle)

            cbFun(snmpEngine, origSendRequestHandle, 'badResponse', None,
                  cbCtx)
            return

        # User-side API assumes SMIv2
        if messageProcessingModel == 0:
            PDU = rfc2576.v1ToV2(PDU, origPdu)

        # 3.1.2
        if v2c.apiPDU.getRequestID(PDU) != v2c.apiPDU.getRequestID(origPdu):
            debug.logger & debug.flagApp and debug.logger(
                'processResponsePdu: sendPduHandle %s, request-id/response-id mismatch'
                % sendPduHandle)
            cbFun(snmpEngine, origSendRequestHandle, 'badResponse', None,
                  cbCtx)
            return

        cbFun(snmpEngine, origSendRequestHandle, None, PDU, cbCtx)
Ejemplo n.º 9
0
 def test__get_transport_err(self, mock_transport, mock_cmdgen):
     mock_transport.side_effect = snmp_error.PySnmpError()
     client = snmp.SNMPClient(self.address, self.port, snmp.SNMP_V3)
     self.assertRaises(snmp_error.PySnmpError, client._get_transport)
     mock_cmdgen.assert_called_once_with()
     mock_transport.assert_called_once_with((client.address, client.port))
Ejemplo n.º 10
0
def addV3User(snmpEngine,
              userName,
              authProtocol=USM_AUTH_NONE,
              authKey=None,
              privProtocol=USM_PRIV_NONE,
              privKey=None,
              securityEngineId=None,
              securityName=None,
              authKeyType=USM_KEY_TYPE_PASSPHRASE,
              privKeyType=USM_KEY_TYPE_PASSPHRASE):

    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

    if securityName is None:
        securityName = userName

    (securityEngineId, usmUserEntry, tblIdx1, pysnmpUsmSecretEntry,
     tblIdx2) = __cookV3UserInfo(snmpEngine, securityName, securityEngineId)

    # Load augmenting table before creating new row in base one
    pysnmpUsmKeyEntry, = mibBuilder.importSymbols('PYSNMP-USM-MIB',
                                                  'pysnmpUsmKeyEntry')

    # Load clone-from (may not be needed)
    zeroDotZero, = mibBuilder.importSymbols('SNMPv2-SMI', 'zeroDotZero')

    snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
        (usmUserEntry.name + (13, ) + tblIdx1, 'destroy'),
        snmpEngine=snmpEngine)

    snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
        (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'),
        snmpEngine=snmpEngine)

    if authProtocol not in AUTH_SERVICES:
        raise error.PySnmpError('Unknown auth protocol %s' % (authProtocol, ))

    if privProtocol not in PRIV_SERVICES:
        raise error.PySnmpError('Unknown privacy protocol %s' %
                                (privProtocol, ))

    pysnmpUsmKeyType, = mibBuilder.importSymbols('__PYSNMP-USM-MIB',
                                                 'pysnmpUsmKeyType')

    authKeyType = pysnmpUsmKeyType.syntax.clone(authKeyType)

    # Localize authentication key unless given

    authKey = authKey and rfc1902.OctetString(authKey)

    masterAuthKey = localAuthKey = authKey

    if authKeyType < USM_KEY_TYPE_MASTER:  # master key is not given
        masterAuthKey = AUTH_SERVICES[authProtocol].hashPassphrase(authKey
                                                                   or null)

    if authKeyType < USM_KEY_TYPE_LOCALIZED:  # localized key is not given
        localAuthKey = AUTH_SERVICES[authProtocol].localizeKey(
            masterAuthKey, securityEngineId)

    # Localize privacy key unless given

    privKeyType = pysnmpUsmKeyType.syntax.clone(privKeyType)

    privKey = privKey and rfc1902.OctetString(privKey)

    masterPrivKey = localPrivKey = privKey

    if privKeyType < USM_KEY_TYPE_MASTER:  # master key is not given
        masterPrivKey = PRIV_SERVICES[privProtocol].hashPassphrase(
            authProtocol, privKey or null)

    if privKeyType < USM_KEY_TYPE_LOCALIZED:  # localized key is not given
        localPrivKey = PRIV_SERVICES[privProtocol].localizeKey(
            authProtocol, masterPrivKey, securityEngineId)

    # Commit only the keys we have

    snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
        (pysnmpUsmKeyEntry.name + (1, ) + tblIdx1, localAuthKey),
        snmpEngine=snmpEngine)

    snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
        (pysnmpUsmKeyEntry.name + (2, ) + tblIdx1, localPrivKey),
        snmpEngine=snmpEngine)

    if authKeyType < USM_KEY_TYPE_LOCALIZED:
        snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
            (pysnmpUsmKeyEntry.name + (3, ) + tblIdx1, masterAuthKey),
            snmpEngine=snmpEngine)

    if privKeyType < USM_KEY_TYPE_LOCALIZED:
        snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
            (pysnmpUsmKeyEntry.name + (4, ) + tblIdx1, masterPrivKey),
            snmpEngine=snmpEngine)

    snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
        (pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'destroy'),
        snmpEngine=snmpEngine)

    # Commit plain-text pass-phrases if we have them

    snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
        (pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'createAndGo'),
        snmpEngine=snmpEngine)

    if authKeyType < USM_KEY_TYPE_MASTER:
        snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
            (pysnmpUsmSecretEntry.name + (1, ) + tblIdx2, userName),
            (pysnmpUsmSecretEntry.name + (2, ) + tblIdx2, authKey),
            snmpEngine=snmpEngine)

    if privKeyType < USM_KEY_TYPE_MASTER:
        snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
            (pysnmpUsmSecretEntry.name + (1, ) + tblIdx2, userName),
            (pysnmpUsmSecretEntry.name + (3, ) + tblIdx2, privKey),
            snmpEngine=snmpEngine)

    debug.logger & debug.FLAG_SM and debug.logger(
        'addV3User: added new table entries '
        'userName "%s" securityName "%s" authProtocol %s '
        'privProtocol %s localAuthKey "%s" localPrivKey "%s" '
        'masterAuthKey "%s" masterPrivKey "%s" authKey "%s" '
        'privKey "%s" by index securityName "%s" securityEngineId '
        '"%s"' % (userName, securityName, authProtocol, privProtocol,
                  localAuthKey and localAuthKey.prettyPrint(), localPrivKey
                  and localPrivKey.prettyPrint(), masterAuthKey
                  and masterAuthKey.prettyPrint(), masterPrivKey
                  and masterPrivKey.prettyPrint(), authKey
                  and authKey.prettyPrint(), privKey and privKey.prettyPrint(),
                  securityName, securityEngineId.prettyPrint()))
Ejemplo n.º 11
0
def addV3User(snmpEngine,
              userName,
              authProtocol=USM_AUTH_NONE,
              authKey=None,
              privProtocol=USM_PRIV_NONE,
              privKey=None,
              securityEngineId=None,
              securityName=None):

    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

    if securityName is None:
        securityName = userName

    (snmpEngineID, usmUserEntry, tblIdx1, pysnmpUsmSecretEntry,
     tblIdx2) = __cookV3UserInfo(snmpEngine, userName, securityEngineId)

    # Load augmenting table before creating new row in base one
    pysnmpUsmKeyEntry, = mibBuilder.importSymbols('PYSNMP-USM-MIB',
                                                  'pysnmpUsmKeyEntry')

    # Load clone-from (may not be needed)
    zeroDotZero, = mibBuilder.importSymbols('SNMPv2-SMI', 'zeroDotZero')

    snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
        (usmUserEntry.name + (13, ) + tblIdx1, 'destroy'),
        snmpEngine=snmpEngine)

    snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
        (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'),
        snmpEngine=snmpEngine)

    # Localize keys
    if authProtocol in AUTH_SERVICES:
        hashedAuthPassphrase = AUTH_SERVICES[authProtocol].hashPassphrase(
            authKey and authKey or null)

        localAuthKey = AUTH_SERVICES[authProtocol].localizeKey(
            hashedAuthPassphrase, snmpEngineID)

    else:
        raise error.PySnmpError('Unknown auth protocol %s' % (authProtocol, ))

    if privProtocol in PRIV_SERVICES:
        hashedPrivPassphrase = PRIV_SERVICES[privProtocol].hashPassphrase(
            authProtocol, privKey and privKey or null)

        localPrivKey = PRIV_SERVICES[privProtocol].localizeKey(
            authProtocol, hashedPrivPassphrase, snmpEngineID)

    else:
        raise error.PySnmpError('Unknown priv protocol %s' % (privProtocol, ))

    # Commit localized keys
    snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
        (pysnmpUsmKeyEntry.name + (1, ) + tblIdx1, localAuthKey),
        (pysnmpUsmKeyEntry.name + (2, ) + tblIdx1, localPrivKey),
        (pysnmpUsmKeyEntry.name + (3, ) + tblIdx1, hashedAuthPassphrase),
        (pysnmpUsmKeyEntry.name + (4, ) + tblIdx1, hashedPrivPassphrase),
        snmpEngine=snmpEngine)

    # Commit passphrases

    snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
        (pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'destroy'),
        snmpEngine=snmpEngine)

    snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
        (pysnmpUsmSecretEntry.name + (1, ) + tblIdx2, userName),
        (pysnmpUsmSecretEntry.name + (2, ) + tblIdx2, authKey),
        (pysnmpUsmSecretEntry.name + (3, ) + tblIdx2, privKey),
        (pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'createAndGo'),
        snmpEngine=snmpEngine)
Ejemplo n.º 12
0
    def n_OutputOption(self, cbCtx, node):
        snmpEngine, ctx = cbCtx

        mibViewProxy = ctx['mibViewProxy']

        opt = node[1].attr or node[2].attr

        for c in opt:
            if c == 'q':
                mibViewProxy.buildEqualSign = False
                mibViewProxy.buildTypeInfo = False

            elif c == 'Q':
                mibViewProxy.buildTypeInfo = False

            elif c == 'f':
                mibViewProxy.buildModInfo = False
                mibViewProxy.buildObjectDesc = False
                mibViewProxy.buildAbsoluteName = True

            elif c == 's':
                mibViewProxy.buildModInfo = False
                mibViewProxy.buildObjectDesc = True

            elif c == 'S':
                mibViewProxy.buildObjectDesc = True

            elif c == 'n':
                mibViewProxy.buildObjectDesc = False
                mibViewProxy.buildModInfo = False
                mibViewProxy.buildNumericName = True
                mibViewProxy.buildNumericIndices = True
                mibViewProxy.buildAbsoluteName = True

            elif c == 'e':
                mibViewProxy.buildEnums = False

            elif c == 'b':
                mibViewProxy.buildNumericIndices = True

            elif c == 'E':
                mibViewProxy.buildEscQuotes = True

            elif c == 'X':
                mibViewProxy.buildSquareBrackets = True

            elif c == 'T':
                mibViewProxy.buildHexVals = True

            elif c == 'v':
                mibViewProxy.buildObjectName = False

            elif c == 'U':
                mibViewProxy.buildUnits = False

            elif c == 't':
                mibViewProxy.buildRawTimeTicks = True
                pass

            elif c == 'R':
                mibViewProxy.buildRawVals = True

            else:
                raise error.PySnmpError('Unknown output option %s at %s' %
                                        (c, self))
Ejemplo n.º 13
0
def generator(cbCtx, ast):
    snmpEngine, ctx = cbCtx

    _SMGenerator().preorder(cbCtx, ast)

    # Commit collected data
    if ctx['versionId'] == 3:

        def _unhexKey(key):
            if key.lower().startswith('0x'):
                key = key[2:]

            return rfc1902.OctetString(hexValue=key)

        if 'securityName' not in ctx:
            raise error.PySnmpError('Security name not specified')

        if 'securityLevel' not in ctx:
            raise error.PySnmpError('Security level not specified')

        if 'securityEngineId' in ctx:
            securityEngineId = _unhexKey(ctx['securityEngineId'])

        else:
            securityEngineId = None

        if 'contextEngineId' in ctx:
            ctx['contextEngineId'] = _unhexKey(ctx['contextEngineId'])

        else:
            ctx['contextEngineId'] = None

        if 'localizedAuthKey' in ctx:
            ctx['authKey'] = _unhexKey(ctx.pop('localizedAuthKey'))
            authKeyType = config.usmKeyTypeLocalized

        elif 'masterAuthKey' in ctx:
            ctx['authKey'] = _unhexKey(ctx.pop('masterAuthKey'))
            authKeyType = config.usmKeyTypeMaster

        else:
            authKeyType = config.usmKeyTypePassphrase

        if 'localizedPrivKey' in ctx:
            ctx['privKey'] = _unhexKey(ctx.pop('localizedPrivKey'))
            privKeyType = config.usmKeyTypeLocalized

        elif 'masterPrivKey' in ctx:
            ctx['privKey'] = _unhexKey(ctx.pop('masterPrivKey'))
            privKeyType = config.usmKeyTypeMaster

        else:
            privKeyType = config.usmKeyTypePassphrase

        if (authKeyType == config.usmKeyTypeLocalized
                or privKeyType == config.usmKeyTypeLocalized):
            # Wildcard security engine ID assocciating localized keys
            # with any authoritative SNMP engine
            securityEngineId = rfc1902.OctetString(hexValue='0000000000')

        ctx['securityEngineId'] = securityEngineId

        if ctx['securityLevel'] == 'noAuthNoPriv':
            if 'authKey' in ctx:
                del ctx['authKey']

            if 'privKey' in ctx:
                del ctx['privKey']

        elif ctx['securityLevel'] == 'authNoPriv':
            if 'privKey' in ctx:
                del ctx['privKey']

        if 'authKey' in ctx:
            if 'authProtocol' not in ctx:
                ctx['authProtocol'] = config.usmHMACMD5AuthProtocol

        else:
            ctx['authProtocol'] = config.usmNoAuthProtocol
            ctx['authKey'] = None

        if 'privKey' in ctx:
            if 'privProtocol' not in ctx:
                ctx['privProtocol'] = config.usmDESPrivProtocol

        else:
            ctx['privProtocol'] = config.usmNoPrivProtocol
            ctx['privKey'] = None

        config.addV3User(snmpEngine,
                         ctx['securityName'],
                         ctx['authProtocol'],
                         ctx['authKey'],
                         ctx['privProtocol'],
                         ctx['privKey'],
                         securityEngineId=securityEngineId,
                         securityName=ctx['securityName'],
                         authKeyType=authKeyType,
                         privKeyType=privKeyType)

        # edit SNMP engine boots/uptime

        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        if 'engineBoots' in ctx:
            snmpEngineBoots, = mibBuilder.importSymbols(
                '__SNMP-FRAMEWORK-MIB', 'snmpEngineBoots')
            snmpEngineBoots.setSyntax(snmpEngineBoots.getSyntax().clone(
                ctx['engineBoots']))

        if 'engineTime' in ctx:
            snmpEngineTime, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB',
                                                       'snmpEngineTime')
            snmpEngineTime.setSyntax(snmpEngineTime.getSyntax().clone(
                ctx['engineTime']))

    else:  # SNMPv1/v2c
        if 'communityName' not in ctx:
            raise error.PySnmpError('Community name not specified')

        ctx['securityName'] = 'my-agent'
        ctx['securityLevel'] = 'noAuthNoPriv'

        config.addV1System(snmpEngine, ctx['securityName'],
                           ctx['communityName'])

    ctx['paramsName'] = ctx['securityName']

    config.addTargetParams(snmpEngine, ctx['paramsName'], ctx['securityName'],
                           ctx['securityLevel'], ctx['versionId'])
Ejemplo n.º 14
0
 def n_Help(self, cbCtx, node):
     raise error.PySnmpError()
Ejemplo n.º 15
0
 def getMibInstrum(self, contextName):
     if not self.contextNames.has_key(contextName):
         raise error.PySnmpError('Missing contextName %s' % contextName)
     else:
         return self.contextNames[contextName]
Ejemplo n.º 16
0
 def error(self, token):
     raise error.PySnmpError('Command-line parser error at token %s\n' %
                             token)
Ejemplo n.º 17
0
    def processResponsePdu(self, snmpEngine, messageProcessingModel,
                           securityModel, securityName, securityLevel,
                           contextEngineId, contextName, pduVersion, PDU,
                           statusInformation, sendPduHandle, cbInfo):
        (cbFun, cbCtx) = cbInfo
        # 3.1.1
        if sendPduHandle not in self.__pendingReqs:
            raise error.PySnmpError('Missing sendPduHandle %s' % sendPduHandle)

        (origTransportDomain, origTransportAddress, origMessageProcessingModel,
         origSecurityModel, origSecurityName, origSecurityLevel,
         origContextEngineId, origContextName, origPduVersion, origPdu,
         origTimeout, origRetryCount, origRetries,
         origSendRequestHandle) = self.__pendingReqs[sendPduHandle]

        del self.__pendingReqs[sendPduHandle]

        snmpEngine.transportDispatcher.jobFinished(id(self))

        # 3.1.3
        if statusInformation:
            debug.logger & debug.flagApp and debug.logger(
                'processResponsePdu: sendPduHandle %s, statusInformation %s' %
                (sendPduHandle, statusInformation))
            errorIndication = statusInformation['errorIndication']
            # SNMP engine discovery will take extra retries, allow that
            if errorIndication in (errind.notInTimeWindow,
                                   errind.unknownEngineID) and \
                                   origRetries == origRetryCount + 2 or \
               errorIndication not in (errind.notInTimeWindow,
                                       errind.unknownEngineID) and \
                                   origRetries == origRetryCount:
                debug.logger & debug.flagApp and debug.logger(
                    'processResponsePdu: sendPduHandle %s, retry count %d exceeded'
                    % (sendPduHandle, origRetries))
                cbFun(origSendRequestHandle,
                      statusInformation['errorIndication'], 0, 0, (), cbCtx)
                return
            try:
                self._sendPdu(snmpEngine, origTransportDomain,
                              origTransportAddress, origMessageProcessingModel,
                              origSecurityModel, origSecurityName,
                              origSecurityLevel, origContextEngineId,
                              origContextName, origPdu, origTimeout,
                              origRetryCount, origRetries + 1,
                              origSendRequestHandle, (self.processResponsePdu,
                                                      (cbFun, cbCtx)))
            except StatusInformation:
                statusInformation = sys.exc_info()[1]
                debug.logger & debug.flagApp and debug.logger(
                    'processResponsePdu: origSendRequestHandle %s, _sendPdu() failed with %r'
                    % (sendPduHandle, statusInformation))
                cbFun(origSendRequestHandle,
                      statusInformation['errorIndication'], 0, 0, (), cbCtx)
            return

        if origMessageProcessingModel != messageProcessingModel or \
           origSecurityModel != securityModel or \
           origSecurityName != origSecurityName or \
           origContextEngineId and origContextEngineId != contextEngineId or \
           origContextName and origContextName != contextName or \
           origPduVersion != pduVersion:
            debug.logger & debug.flagApp and debug.logger(
                'processResponsePdu: sendPduHandle %s, request/response data mismatch'
                % sendPduHandle)
            cbFun(origSendRequestHandle, 'badResponse', 0, 0, (), cbCtx)
            return

        # User-side API assumes SMIv2
        if messageProcessingModel == 0:
            PDU = rfc2576.v1ToV2(PDU, origPdu)

        # 3.1.2
        if v2c.apiPDU.getRequestID(PDU) != v2c.apiPDU.getRequestID(origPdu):
            debug.logger & debug.flagApp and debug.logger(
                'processResponsePdu: sendPduHandle %s, request-id/response-id mismatch'
                % sendPduHandle)
            cbFun(origSendRequestHandle, 'badResponse', 0, 0, (), cbCtx)
            return

        self._handleResponse(
            snmpEngine,
            origTransportDomain,
            origTransportAddress,
            origMessageProcessingModel,
            origSecurityModel,
            origSecurityName,
            origSecurityLevel,
            origContextEngineId,
            origContextName,
            origPdu,
            origTimeout,
            origRetryCount,
            PDU,
            origSendRequestHandle,
            (cbFun, cbCtx),
        )
Ejemplo n.º 18
0
    def unconfigure(self,
                    snmpEngine,
                    authData=None,
                    contextName=null,
                    **options):
        cache = self._getCache(snmpEngine)

        if authData:
            if isinstance(authData, CommunityData):
                authDataKey = authData.communityIndex

            elif isinstance(authData, UsmUserData):
                authDataKey = authData.userName, authData.securityEngineId

            else:
                raise error.PySnmpError('Unsupported authentication object')

            if authDataKey in cache['auth']:
                authDataKeys = (authDataKey, )

            else:
                raise error.PySnmpError('Unknown authData %s' % (authData, ))

        else:
            authDataKeys = list(cache['auth'].keys())

        addrNames, paramsNames = set(), set()

        for authDataKey in authDataKeys:
            authDataX = cache['auth'][authDataKey]

            del cache['auth'][authDataKey]

            if isinstance(authDataX, CommunityData):
                config.delV1System(snmpEngine, authDataX.communityIndex)

            elif isinstance(authDataX, UsmUserData):
                config.delV3User(snmpEngine, authDataX.userName,
                                 authDataX.securityEngineId)

            else:
                raise error.PySnmpError('Unsupported authentication object')

            paramsKey = (authDataX.securityName, authDataX.securityLevel,
                         authDataX.mpModel)

            if paramsKey in cache['parm']:
                paramsName, useCount = cache['parm'][paramsKey]

                useCount -= 1

                if useCount:
                    cache['parm'][paramsKey] = paramsName, useCount

                else:
                    del cache['parm'][paramsKey]

                    config.delTargetParams(snmpEngine, paramsName)

                    paramsNames.add(paramsName)

            else:
                raise error.PySnmpError('Unknown target %s' % (paramsKey, ))

            addrKeys = [x for x in cache['addr'] if x[0] == paramsName]

            for addrKey in addrKeys:
                addrName, useCount = cache['addr'][addrKey]

                useCount -= 1

                if useCount:
                    cache['addr'][addrKey] = addrName, useCount

                else:
                    config.delTargetAddr(snmpEngine, addrName)

                    del cache['addr'][addrKey]

                    addrNames.add(addrKey)

                    if addrKey[1] in cache['tran']:
                        transport, useCount = cache['tran'][addrKey[1]]

                        if useCount > 1:
                            useCount -= 1
                            cache['tran'][addrKey[1]] = transport, useCount

                        else:
                            config.delTransport(snmpEngine, addrKey[1])
                            transport.closeTransport()

                            del cache['tran'][addrKey[1]]

        return addrNames, paramsNames
Ejemplo n.º 19
0
def addV3User(
        snmpEngine,
        userName,
        authProtocol=usmNoAuthProtocol,
        authKey=None,
        privProtocol=usmNoPrivProtocol,
        privKey=None,
        securityEngineId=None,
        securityName=None,
        # deprecated parameters follow
        contextEngineId=None):
    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

    if securityName is None:
        securityName = userName
    if securityEngineId is None:  # backward compatibility
        securityEngineId = contextEngineId
    (snmpEngineID, usmUserEntry, tblIdx1, pysnmpUsmSecretEntry,
     tblIdx2) = __cookV3UserInfo(snmpEngine, userName, securityEngineId)

    # Load augmenting table before creating new row in base one
    pysnmpUsmKeyEntry, = mibBuilder.importSymbols('PYSNMP-USM-MIB',
                                                  'pysnmpUsmKeyEntry')

    # Load clone-from (may not be needed)
    zeroDotZero, = mibBuilder.importSymbols('SNMPv2-SMI', 'zeroDotZero')

    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
        ((usmUserEntry.name + (13, ) + tblIdx1, 'destroy'), ))
    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')))

    # Localize keys
    if authProtocol in authServices:
        hashedAuthPassphrase = authServices[authProtocol].hashPassphrase(
            authKey and authKey or null)
        localAuthKey = authServices[authProtocol].localizeKey(
            hashedAuthPassphrase, snmpEngineID)
    else:
        raise error.PySnmpError('Unknown auth protocol %s' % (authProtocol, ))

    if privProtocol in privServices:
        hashedPrivPassphrase = privServices[privProtocol].hashPassphrase(
            authProtocol, privKey and privKey or null)
        localPrivKey = privServices[privProtocol].localizeKey(
            authProtocol, hashedPrivPassphrase, snmpEngineID)
    else:
        raise error.PySnmpError('Unknown priv protocol %s' % (privProtocol, ))

    # 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)))

    # Commit passphrases

    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
        ((pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'destroy'), ))
    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
        ((pysnmpUsmSecretEntry.name + (1, ) + tblIdx2,
          userName), (pysnmpUsmSecretEntry.name + (2, ) + tblIdx2, authKey),
         (pysnmpUsmSecretEntry.name + (3, ) + tblIdx2, privKey),
         (pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'createAndGo')))
Ejemplo n.º 20
0
def bulkCmd(snmpDispatcher, authData, transportTarget, nonRepeaters,
            maxRepetitions, *varBinds, **options):
    """Initiate SNMP GETBULK query over SNMPv2c.

    Based on passed parameters, prepares SNMP GETBULK packet
    (:RFC:`1905#section-4.2.3`) and schedules its transmission by
    I/O framework at a later point of time.

    Parameters
    ----------
    snmpDispatcher: :py:class:`~pysnmp.hlapi.v1arch.asyncore.SnmpDispatcher`
        Class instance representing SNMP dispatcher.

    authData: :py:class:`~pysnmp.hlapi.v1arch.CommunityData` or :py:class:`~pysnmp.hlapi.v1arch.UsmUserData`
        Class instance representing SNMP credentials.

    transportTarget: :py:class:`~pysnmp.hlapi.v1arch.asyncore.UdpTransportTarget` or :py:class:`~pysnmp.hlapi.v1arch.asyncore.Udp6TransportTarget`
        Class instance representing transport type along with SNMP peer
        address.

    nonRepeaters: int
        One MIB variable is requested in response for the first
        `nonRepeaters` MIB variables in request.

    maxRepetitions: int
        `maxRepetitions` MIB variables are requested in response for each
        of the remaining MIB variables in the request (e.g. excluding
        `nonRepeaters`). Remote SNMP dispatcher may choose lesser value than
        requested.

    \*varBinds: :py:class:`~pysnmp.smi.rfc1902.ObjectType`
        One or more class instances representing MIB variables to place
        into SNMP request.

    Other Parameters
    ----------------
    \*\*options :
        Request options:

            * `lookupMib` - load MIB and resolve response MIB variables at
              the cost of slightly reduced performance. Default is `True`.
            * `cbFun` (callable) - user-supplied callable that is invoked
               to pass SNMP response data or error to user at a later point
               of time. Default is `None`.
            * `cbCtx` (object) - user-supplied object passing additional
               parameters to/from `cbFun`. Default is `None`.

    Notes
    -----
    User-supplied `cbFun` callable must have the following call
    signature:

    * snmpDispatcher (:py:class:`~pysnmp.hlapi.v1arch.snmpDispatcher`):
      Class instance representing SNMP dispatcher.
    * stateHandle (int): Unique request identifier. Can be used
      for matching multiple ongoing requests with received responses.
    * errorIndication (str): True value indicates SNMP dispatcher error.
    * errorStatus (str): True value indicates SNMP PDU error.
    * errorIndex (int): Non-zero value refers to `varBinds[errorIndex-1]`
    * varBindTable (tuple): A sequence of sequences (e.g. 2-D array) of
      variable-bindings represented as :class:`tuple` or
      :py:class:`~pysnmp.smi.rfc1902.ObjectType` class instances
      representing a table of MIB variables returned in SNMP response, with
      up to ``maxRepetitions`` rows, i.e. ``len(varBindTable) <= maxRepetitions``.

      For ``0 <= i < len(varBindTable)`` and ``0 <= j < len(varBinds)``,
      ``varBindTable[i][j]`` represents:

      - For non-repeaters (``j < nonRepeaters``), the first lexicographic
        successor of ``varBinds[j]``, regardless the value of ``i``, or an
        :py:class:`~pysnmp.smi.rfc1902.ObjectType` instance with the
        :py:obj:`~pysnmp.proto.rfc1905.endOfMibView` value if no such successor
        exists;
      - For repeaters (``j >= nonRepeaters``), the ``i``-th lexicographic
        successor of ``varBinds[j]``, or an
        :py:class:`~pysnmp.smi.rfc1902.ObjectType` instance with the
        :py:obj:`~pysnmp.proto.rfc1905.endOfMibView` value if no such successor
        exists.

      See :rfc:`3416#section-4.2.3` for details on the underlying
      ``GetBulkRequest-PDU`` and the associated ``GetResponse-PDU``, such as
      specific conditions under which the server may truncate the response,
      causing ``varBindTable`` to have less than ``maxRepetitions`` rows.
    * `cbCtx` (object): Original user-supplied object.

    Returns
    -------
    stateHandle : int
        Unique request identifier. Can be used for matching received
        responses with ongoing requests.

    Raises
    ------
    PySnmpError
        Or its derivative indicating that an error occurred while
        performing SNMP operation.

    Examples
    --------
    >>> from pysnmp.hlapi.v1arch.asyncore import *
    >>>
    >>> def cbFun(snmpDispatcher, stateHandle, errorIndication,
    >>>           errorStatus, errorIndex, varBinds, cbCtx):
    >>>     print(errorIndication, errorStatus, errorIndex, varBinds)
    >>>
    >>> snmpDispatcher = snmpDispatcher()
    >>>
    >>> stateHandle = bulkCmd(
    >>>     snmpDispatcher,
    >>>     CommunityData('public'),
    >>>     UdpTransportTarget(('demo.snmplabs.com', 161)),
    >>>     0, 2,
    >>>     ('1.3.6.1.2.1.1', None),
    >>>     cbFun=cbFun
    >>> )
    >>>
    >>> snmpDispatcher.transportDispatcher.runDispatcher()
    """
    def _cbFun(snmpDispatcher, stateHandle, errorIndication, rspPdu, _cbCtx):
        if not cbFun:
            return

        if errorIndication:
            cbFun(errorIndication,
                  pMod.Integer(0),
                  pMod.Integer(0),
                  None,
                  cbCtx=cbCtx,
                  snmpDispatcher=snmpDispatcher,
                  stateHandle=stateHandle)
            return

        errorStatus = pMod.apiBulkPDU.getErrorStatus(rspPdu)
        errorIndex = pMod.apiBulkPDU.getErrorIndex(rspPdu)

        varBindTable = pMod.apiBulkPDU.getVarBindTable(reqPdu, rspPdu)

        errorIndication, nextVarBinds = pMod.apiBulkPDU.getNextVarBinds(
            varBindTable[-1], errorIndex=errorIndex)

        if options.get('lookupMib'):
            varBindTable = [
                vbProcessor.unmakeVarBinds(snmpDispatcher.cache, vbs)
                for vbs in varBindTable
            ]

        nextStateHandle = pMod.getNextRequestID()

        nextVarBinds = cbFun(errorIndication,
                             errorStatus,
                             errorIndex,
                             varBindTable,
                             cbCtx=cbCtx,
                             snmpDispatcher=snmpDispatcher,
                             stateHandle=stateHandle,
                             nextStateHandle=nextStateHandle,
                             nextVarBinds=nextVarBinds)

        if not nextVarBinds:
            return

        pMod.apiBulkPDU.setRequestID(reqPdu, nextStateHandle)
        pMod.apiBulkPDU.setVarBinds(reqPdu, nextVarBinds)

        return snmpDispatcher.sendPdu(authData,
                                      transportTarget,
                                      reqPdu,
                                      cbFun=_cbFun)

    if authData.mpModel < 1:
        raise error.PySnmpError(
            'GETBULK PDU is only supported in SNMPv2c and SNMPv3')

    lookupMib, cbFun, cbCtx = [
        options.get(x) for x in ('lookupMib', 'cbFun', 'cbCtx')
    ]

    if lookupMib:
        varBinds = vbProcessor.makeVarBinds(snmpDispatcher.cache, varBinds)

    pMod = api.protoModules[authData.mpModel]

    reqPdu = pMod.GetBulkRequestPDU()
    pMod.apiBulkPDU.setDefaults(reqPdu)
    pMod.apiBulkPDU.setNonRepeaters(reqPdu, nonRepeaters)
    pMod.apiBulkPDU.setMaxRepetitions(reqPdu, maxRepetitions)
    pMod.apiBulkPDU.setVarBinds(reqPdu, varBinds)

    return snmpDispatcher.sendPdu(authData,
                                  transportTarget,
                                  reqPdu,
                                  cbFun=_cbFun)
Ejemplo n.º 21
0
    def n_VarName_exit(self, cbCtx, node):
        snmpEngine, ctx = cbCtx
        mibViewCtl = ctx['mibViewController']

        if 'modName' in ctx:
            mibViewCtl.mibBuilder.loadModules(ctx['modName'])

        if 'objectName' in ctx:
            objectName = ctx['objectName']

        else:
            objectName = None

        modName = ctx.get('modName', '')

        if objectName:
            oid, label, suffix = mibViewCtl.getNodeName(objectName, modName)

        else:
            oid, label, suffix = mibViewCtl.getFirstNodeName(modName)

        if sys.version_info[0] < 3:
            intTypes = (int, long)

        else:
            intTypes = (int, )

        if [x for x in suffix if not isinstance(x, intTypes)]:
            raise error.PySnmpError('Cant resolve object at: %s' % (suffix, ))

        modName, nodeDesc, _suffix = mibViewCtl.getNodeLocation(oid)

        mibNode, = mibViewCtl.mibBuilder.importSymbols(modName, nodeDesc)

        if not hasattr(self, '_MibTableColumn'):
            self._MibTableColumn, = mibViewCtl.mibBuilder.importSymbols(
                'SNMPv2-SMI', 'MibTableColumn')

        if isinstance(mibNode, self._MibTableColumn):
            # Table column
            if 'objectIndices' in ctx:
                modName, nodeDesc, _suffix = mibViewCtl.getNodeLocation(
                    mibNode.name[:-1])

                mibNode, = mibViewCtl.mibBuilder.importSymbols(
                    modName, nodeDesc)

                suffix = suffix + mibNode.getInstIdFromIndices(
                    *ctx['objectIndices'])

        else:
            if 'objectIndices' in ctx:
                raise error.PySnmpError('Cant resolve indices: %s' %
                                        (ctx['objectIndices'], ))

        ctx['varName'] = oid + suffix

        if 'objectName' in ctx:
            del ctx['objectName']

        if 'objectIndices' in ctx:
            del ctx['objectIndices']