示例#1
0
    def prepareResponseMessage(self, snmpEngine, messageProcessingModel,
                               securityModel, securityName, securityLevel,
                               contextEngineId, contextName, pduVersion, pdu,
                               maxSizeResponseScopedPDU, stateReference,
                               statusInformation):
        snmpEngineID, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
        snmpEngineID = snmpEngineID.syntax

        # 7.1.2.b
        cachedParams = self._cache.popByStateRef(stateReference)
        msgID = cachedParams['msgID']
        contextEngineId = cachedParams['contextEngineId']
        contextName = cachedParams['contextName']
        securityModel = cachedParams['securityModel']
        securityName = cachedParams['securityName']
        securityLevel = cachedParams['securityLevel']
        securityStateReference = cachedParams['securityStateReference']
        reportableFlag = cachedParams['reportableFlag']
        maxMessageSize = cachedParams['msgMaxSize']
        transportDomain = cachedParams['transportDomain']
        transportAddress = cachedParams['transportAddress']

        debug.logger & debug.flagMP and debug.logger(
            'prepareResponseMessage: stateReference %s' % stateReference)

        # 7.1.3
        if statusInformation is not None and 'oid' in statusInformation:
            # 7.1.3a
            if pdu is None:
                pduType = None
            else:
                requestID = pdu.getComponentByPosition(0)
                pduType = pdu.tagSet

            # 7.1.3b
            if (pdu is None and not reportableFlag or pduType is not None
                    and pduType not in rfc3411.confirmedClassPDUs):
                raise error.StatusInformation(
                    errorIndication=errind.loopTerminated)

            # 7.1.3c
            reportPDU = rfc1905.ReportPDU()
            pMod.apiPDU.setVarBinds(
                reportPDU,
                ((statusInformation['oid'], statusInformation['val']), ))
            pMod.apiPDU.setErrorStatus(reportPDU, 0)
            pMod.apiPDU.setErrorIndex(reportPDU, 0)
            if pdu is None:
                pMod.apiPDU.setRequestID(reportPDU, 0)
            else:
                # noinspection PyUnboundLocalVariable
                pMod.apiPDU.setRequestID(reportPDU, requestID)

            # 7.1.3d.1
            if 'securityLevel' in statusInformation:
                securityLevel = statusInformation['securityLevel']
            else:
                securityLevel = 1

            # 7.1.3d.2
            if 'contextEngineId' in statusInformation:
                contextEngineId = statusInformation['contextEngineId']
            else:
                contextEngineId = snmpEngineID

            # 7.1.3d.3
            if 'contextName' in statusInformation:
                contextName = statusInformation['contextName']
            else:
                contextName = ""

            # 7.1.3e
            pdu = reportPDU

            debug.logger & debug.flagMP and debug.logger(
                'prepareResponseMessage: prepare report PDU for statusInformation %s'
                % statusInformation)
        # 7.1.4
        if not contextEngineId:
            contextEngineId = snmpEngineID  # XXX impl-dep manner

        # 7.1.5
        if not contextName:
            contextName = self._emptyStr

        debug.logger & debug.flagMP and debug.logger(
            'prepareResponseMessage: using contextEngineId %r, contextName %r'
            % (contextEngineId, contextName))

        # 7.1.6
        scopedPDU = self.__scopedPDU
        scopedPDU.setComponentByPosition(0, contextEngineId)
        scopedPDU.setComponentByPosition(1, contextName)
        scopedPDU.setComponentByPosition(2)
        scopedPDU.getComponentByPosition(2).setComponentByType(
            pdu.tagSet,
            pdu,
            verifyConstraints=False,
            matchTags=False,
            matchConstraints=False)

        # 7.1.7
        msg = self._snmpMsgSpec

        # 7.1.7a
        msg.setComponentByPosition(0,
                                   self.messageProcessingModelID,
                                   verifyConstraints=False,
                                   matchTags=False,
                                   matchConstraints=False)

        headerData = msg.setComponentByPosition(1).getComponentByPosition(1)

        # 7.1.7b
        headerData.setComponentByPosition(0,
                                          msgID,
                                          verifyConstraints=False,
                                          matchTags=False,
                                          matchConstraints=False)

        snmpEngineMaxMessageSize, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineMaxMessageSize')

        # 7.1.7c
        # XXX need to coerce MIB value as it has incompatible constraints set
        headerData.setComponentByPosition(1,
                                          snmpEngineMaxMessageSize.syntax,
                                          verifyConstraints=False,
                                          matchTags=False,
                                          matchConstraints=False)

        # 7.1.7d
        msgFlags = 0
        if securityLevel == 1:
            pass
        elif securityLevel == 2:
            msgFlags |= 0x01
        elif securityLevel == 3:
            msgFlags |= 0x03
        else:
            raise error.ProtocolError('Unknown securityLevel %s' %
                                      securityLevel)

        if pdu.tagSet in rfc3411.confirmedClassPDUs:  # XXX not needed?
            msgFlags |= 0x04

        headerData.setComponentByPosition(2,
                                          self._msgFlags[msgFlags],
                                          verifyConstraints=False,
                                          matchTags=False,
                                          matchConstraints=False)

        # 7.1.7e
        headerData.setComponentByPosition(3,
                                          securityModel,
                                          verifyConstraints=False,
                                          matchTags=False,
                                          matchConstraints=False)

        debug.logger & debug.flagMP and debug.logger(
            'prepareResponseMessage: %s' % (msg.prettyPrint(), ))

        if securityModel in snmpEngine.securityModels:
            smHandler = snmpEngine.securityModels[securityModel]
        else:
            raise error.StatusInformation(
                errorIndication=errind.unsupportedSecurityModel)

        debug.logger & debug.flagMP and debug.logger(
            'prepareResponseMessage: securityModel %r, securityEngineId %r, securityName %r, securityLevel %r'
            % (securityModel, snmpEngineID, securityName, securityLevel))

        # 7.1.8a
        try:
            (securityParameters, wholeMsg) = smHandler.generateResponseMsg(
                snmpEngine, self.messageProcessingModelID, msg,
                snmpEngineMaxMessageSize.syntax, securityModel, snmpEngineID,
                securityName, securityLevel, scopedPDU, securityStateReference)
        except error.StatusInformation:
            # 7.1.8.b
            raise

        debug.logger & debug.flagMP and debug.logger(
            'prepareResponseMessage: SM finished')

        # Message size constraint verification
        if len(wholeMsg) > min(snmpEngineMaxMessageSize.syntax,
                               maxMessageSize):
            raise error.StatusInformation(errorIndication=errind.tooBig)

        snmpEngine.observer.storeExecutionContext(
            snmpEngine, 'rfc3412.prepareResponseMessage',
            dict(transportDomain=transportDomain,
                 transportAddress=transportAddress,
                 securityModel=securityModel,
                 securityName=securityName,
                 securityLevel=securityLevel,
                 contextEngineId=contextEngineId,
                 contextName=contextName,
                 securityEngineId=snmpEngineID,
                 pdu=pdu))
        snmpEngine.observer.clearExecutionContext(
            snmpEngine, 'rfc3412.prepareResponseMessage')

        return transportDomain, transportAddress, wholeMsg
示例#2
0
    def prepareResponseMessage(self, snmpEngine, messageProcessingModel,
                               securityModel, securityName, securityLevel,
                               contextEngineId, contextName, pduVersion, pdu,
                               maxSizeResponseScopedPDU, stateReference,
                               statusInformation):
        snmpEngineID, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
        snmpEngineID = snmpEngineID.syntax

        # 7.1.2.b
        cachedParams = self._cachePopByStateRef(stateReference)
        msgID = cachedParams['msgID']
        contextEngineId = cachedParams['contextEngineId']
        contextName = cachedParams['contextName']
        securityModel = cachedParams['securityModel']
        securityName = cachedParams['securityName']
        securityLevel = cachedParams['securityLevel']
        securityStateReference = cachedParams['securityStateReference']
        reportableFlag = cachedParams['reportableFlag']
        maxMessageSize = cachedParams['msgMaxSize']
        transportDomain = cachedParams['transportDomain']
        transportAddress = cachedParams['transportAddress']

        debug.logger & debug.flagMP and debug.logger(
            'prepareResponseMessage: stateReference %s' % (stateReference))

        # 7.1.3
        if statusInformation is not None and statusInformation.has_key('oid'):
            # 7.1.3a
            if pdu is not None:
                requestID = pdu.getComponentByPosition(0)
                pduType = pdu.tagSet
            else:
                pduType = None

            # 7.1.3b
            if pdu is None and not reportableFlag or \
                   pduType is not None and \
                   not rfc3411.confirmedClassPDUs.has_key(pduType):
                raise error.StatusInformation(errorIndication='loopTerminated')

            # 7.1.3c
            reportPDU = rfc1905.ReportPDU()
            pMod.apiPDU.setVarBinds(
                reportPDU,
                ((statusInformation['oid'], statusInformation['val']), ))
            pMod.apiPDU.setErrorStatus(reportPDU, 0)
            pMod.apiPDU.setErrorIndex(reportPDU, 0)
            if pdu is None:
                pMod.apiPDU.setRequestID(reportPDU, 0)
            else:
                pMod.apiPDU.setRequestID(reportPDU, requestID)

            # 7.1.3d.1
            if statusInformation.has_key('securityLevel'):
                securityLevel = statusInformation['securityLevel']
            else:
                securityLevel = 1

            # 7.1.3d.2
            if statusInformation.has_key('contextEngineId'):
                contextEngineId = statusInformation['contextEngineId']
            else:
                contextEngineId = snmpEngineID

            # 7.1.3d.3
            if statusInformation.has_key('contextName'):
                contextName = statusInformation['contextName']
            else:
                contextName = ""

            # 7.1.3e
            pdu = reportPDU

            debug.logger & debug.flagMP and debug.logger(
                'prepareResponseMessage: prepare report PDU for statusInformation %s'
                % statusInformation)
        # 7.1.4
        if not contextEngineId:
            contextEngineId = snmpEngineID  # XXX impl-dep manner

        # 7.1.5
        if not contextName:
            contextName = ''

        debug.logger & debug.flagMP and debug.logger(
            'prepareResponseMessage: using contextEngineId %s, contextName %s'
            % (contextEngineId, contextName))

        # 7.1.6
        scopedPDU = ScopedPDU()
        scopedPDU.setComponentByPosition(0, contextEngineId)
        scopedPDU.setComponentByPosition(1, contextName)
        scopedPDU.setComponentByPosition(2)
        scopedPDU.getComponentByPosition(2).setComponentByType(pdu.tagSet, pdu)

        # 7.1.7
        msg = SNMPv3Message()

        # 7.1.7a
        msg.setComponentByPosition(0, 3)  # version

        headerData = msg.setComponentByPosition(1).getComponentByPosition(1)

        # 7.1.7b
        headerData.setComponentByPosition(0, msgID)

        snmpEngineMaxMessageSize, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineMaxMessageSize')

        # 7.1.7c
        # XXX need to coerce MIB value as it has incompatible constraints set
        headerData.setComponentByPosition(1,
                                          int(snmpEngineMaxMessageSize.syntax))

        # 7.1.7d
        msgFlags = 0
        if securityLevel == 1:
            pass
        elif securityLevel == 2:
            msgFlags = msgFlags | 0x01
        elif securityLevel == 3:
            msgFlags = msgFlags | 0x03
        else:
            raise error.ProtocolError('Unknown securityLevel %s' %
                                      securityLevel)

        if rfc3411.confirmedClassPDUs.has_key(pdu.tagSet):  # XXX not needed?
            msgFlags = msgFlags | 0x04

        headerData.setComponentByPosition(2, chr(msgFlags))

        # 7.1.7e
        headerData.setComponentByPosition(3, securityModel)

        debug.logger & debug.flagMP and debug.logger(
            'prepareResponseMessage: %s' % (msg.prettyPrint(), ))

        smHandler = snmpEngine.securityModels.get(securityModel)
        if smHandler is None:
            raise error.StatusInformation(
                errorIndication='unsupportedSecurityModel')

        # 7.1.8a
        try:
            (securityParameters, wholeMsg) = smHandler.generateResponseMsg(
                snmpEngine, self.messageProcessingModelID, msg,
                snmpEngineMaxMessageSize.syntax, securityModel, snmpEngineID,
                securityName, securityLevel, scopedPDU, securityStateReference)
        except error.StatusInformation as statusInformation:
            # 7.1.8.b
            raise

        debug.logger & debug.flagMP and debug.logger(
            'prepareResponseMessage: SM finished')

        # Message size constraint verification
        if len(wholeMsg) > min(snmpEngineMaxMessageSize.syntax,
                               maxMessageSize):
            raise error.StatusInformation(errorIndication='tooBig')

        return (transportDomain, transportAddress, wholeMsg)