コード例 #1
0
    def sendPdu(self, snmpEngine, transportDomain, transportAddress,
                messageProcessingModel, securityModel, securityName,
                securityLevel, contextEngineId, contextName, pduVersion, PDU,
                expectResponse):
        """PDU dispatcher -- prepare and serialize a request or notification"""
        # 4.1.1.2
        mpHandler = snmpEngine.messageProcessingSubsystems.get(
            int(messageProcessingModel))
        if mpHandler is None:
            raise error.StatusInformation(
                errorIndication='unsupportedMsgProcessingModel')

        debug.logger & debug.flagDsp and debug.logger(
            'sendPdu: PDU %s' % PDU.prettyPrint())

        # 4.1.1.3
        sendPduHandle = self.__newSendPduHandle()
        if expectResponse:
            self.__cacheAdd(sendPduHandle,
                            messageProcessingModel=messageProcessingModel,
                            sendPduHandle=sendPduHandle,
                            expectResponse=expectResponse)

        debug.logger & debug.flagDsp and debug.logger(
            'sendPdu: new sendPduHandle %s' % sendPduHandle)

        # 4.1.1.4 & 4.1.1.5
        try:
            (destTransportDomain, destTransportAddress,
             outgoingMessage) = mpHandler.prepareOutgoingMessage(
                 snmpEngine, transportDomain, transportAddress,
                 messageProcessingModel, securityModel, securityName,
                 securityLevel, contextEngineId, contextName, pduVersion, PDU,
                 expectResponse, sendPduHandle)
            debug.logger & debug.flagDsp and debug.logger(
                'sendPdu: MP succeeded')
        except error.StatusInformation as statusInformation:
            # XXX is it still needed here?
            #            self.releaseStateInformation(snmpEngine, sendPduHandle, messageProcessingModel)
            raise

        # 4.1.1.6
        if snmpEngine.transportDispatcher is None:
            raise error.PySnmpError('Transport dispatcher not set')
        snmpEngine.transportDispatcher.sendMessage(outgoingMessage,
                                                   destTransportDomain,
                                                   destTransportAddress)

        # Update cache with orignal req params (used for retrying)
        if expectResponse:
            self.__cacheUpdate(sendPduHandle,
                               transportDomain=transportDomain,
                               transportAddress=transportAddress,
                               securityModel=securityModel,
                               securityName=securityName,
                               securityLevel=securityLevel,
                               contextEngineId=contextEngineId,
                               contextName=contextName,
                               pduVersion=pduVersion,
                               PDU=PDU)

        return sendPduHandle
コード例 #2
0
ファイル: rfc2576.py プロジェクト: zxx1819/pysnmp
    def prepareDataElements(self, snmpEngine, transportDomain,
                            transportAddress, wholeMsg):

        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        # rfc3412: 7.2.2
        msg, restOfWholeMsg = decoder.decode(wholeMsg,
                                             asn1Spec=self._snmpMsgSpec)

        debug.logger & debug.FLAG_MP and debug.logger(
            'prepareDataElements: %s' % (msg.prettyPrint(), ))

        if eoo.endOfOctets.isSameTypeWith(msg):
            raise error.StatusInformation(errorIndication=errind.parseError)

        # rfc3412: 7.2.3
        msgVersion = msg.getComponentByPosition(0)

        # rfc2576: 5.2.1
        snmpEngineMaxMessageSize, = mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineMaxMessageSize')
        communityName = msg.getComponentByPosition(1)

        # transportDomain identifies local endpoint
        securityParameters = (communityName, (transportDomain,
                                              transportAddress))
        messageProcessingModel = int(msg.getComponentByPosition(0))
        securityModel = messageProcessingModel + 1
        securityLevel = 1

        # rfc3412: 7.2.4 -- 7.2.5 -> no-op

        try:

            try:
                smHandler = snmpEngine.securityModels[securityModel]

            except KeyError:
                raise error.StatusInformation(
                    errorIndication=errind.unsupportedSecurityModel)

            # rfc3412: 7.2.6
            (securityEngineId, securityName, scopedPDU,
             maxSizeResponseScopedPDU,
             securityStateReference) = smHandler.processIncomingMsg(
                 snmpEngine, messageProcessingModel,
                 snmpEngineMaxMessageSize.syntax, securityParameters,
                 securityModel, securityLevel, wholeMsg, msg)

            debug.logger & debug.FLAG_MP and debug.logger(
                'prepareDataElements: SM returned securityEngineId %r '
                'securityName %r' % (securityEngineId, securityName))

        except error.StatusInformation as exc:
            statusInformation = exc

            snmpEngine.observer.storeExecutionContext(
                snmpEngine, 'rfc2576.prepareDataElements:sm-failure',
                dict(transportDomain=transportDomain,
                     transportAddress=transportAddress,
                     securityModel=securityModel,
                     securityLevel=securityLevel,
                     securityParameters=securityParameters,
                     statusInformation=statusInformation))

            snmpEngine.observer.clearExecutionContext(
                snmpEngine, 'rfc2576.prepareDataElements:sm-failure')

            raise

        # rfc3412: 7.2.6a --> no-op

        # rfc3412: 7.2.7
        contextEngineId, contextName, pdu = scopedPDU

        # rfc2576: 5.2.1
        pduVersion = msgVersion
        pduType = pdu.tagSet

        # rfc3412: 7.2.8, 7.2.9 -> no-op

        # rfc3412: 7.2.10
        if pduType in rfc3411.RESPONSE_CLASS_PDUS:
            # get unique PDU request-id
            msgID = pdu.getComponentByPosition(0)

            # 7.2.10a
            try:
                cachedReqParams = self._cache.popByMsgId(int(msgID))

            except error.ProtocolError:
                smHandler.releaseStateInformation(securityStateReference)
                raise error.StatusInformation(
                    errorIndication=errind.dataMismatch)

            # recover original PDU request-id to return to app
            pdu.setComponentByPosition(0, cachedReqParams['reqID'])

            debug.logger & debug.FLAG_MP and debug.logger(
                'prepareDataElements: unique PDU request-id %s replaced with '
                'original ID %s' % (msgID, cachedReqParams['reqID']))

            # 7.2.10b
            sendPduHandle = cachedReqParams['sendPduHandle']

        else:
            sendPduHandle = None

        # no error by default
        statusInformation = None

        # rfc3412: 7.2.11 -> no-op

        # rfc3412: 7.2.12
        if pduType in rfc3411.RESPONSE_CLASS_PDUS:
            # rfc3412: 7.2.12a -> no-op
            # rfc3412: 7.2.12b
            # noinspection PyUnboundLocalVariable
            if (securityModel != cachedReqParams['securityModel']
                    or securityName != cachedReqParams['securityName']
                    or securityLevel != cachedReqParams['securityLevel']
                    or contextEngineId != cachedReqParams['contextEngineId']
                    or contextName != cachedReqParams['contextName']):

                smHandler.releaseStateInformation(securityStateReference)

                raise error.StatusInformation(
                    errorIndication=errind.dataMismatch)

            stateReference = None

            snmpEngine.observer.storeExecutionContext(
                snmpEngine, 'rfc2576.prepareDataElements:response',
                dict(transportDomain=transportDomain,
                     transportAddress=transportAddress,
                     securityModel=securityModel,
                     securityName=securityName,
                     securityLevel=securityLevel,
                     contextEngineId=contextEngineId,
                     contextName=contextName,
                     securityEngineId=securityEngineId,
                     communityName=communityName,
                     pdu=pdu))

            snmpEngine.observer.clearExecutionContext(
                snmpEngine, 'rfc2576.prepareDataElements:response')

            # rfc3412: 7.2.12c
            smHandler.releaseStateInformation(securityStateReference)

            # rfc3412: 7.2.12d
            return (messageProcessingModel, securityModel, securityName,
                    securityLevel, contextEngineId, contextName, pduVersion,
                    pdu, pduType, sendPduHandle, maxSizeResponseScopedPDU,
                    statusInformation, stateReference)

        # rfc3412: 7.2.13
        if pduType in rfc3411.CONFIRMED_CLASS_PDUS:
            # store original PDU request-id and replace it with a unique one
            reqID = pdu.getComponentByPosition(0)
            msgID = self._cache.newMsgID()
            pdu.setComponentByPosition(0, msgID)

            debug.logger & debug.FLAG_MP and debug.logger(
                'prepareDataElements: received PDU request-id %s replaced with '
                'unique ID %s' % (reqID, msgID))

            # rfc3412: 7.2.13a
            snmpEngineId, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB',
                                                     'snmpEngineID')

            if securityEngineId != snmpEngineId.syntax:
                smHandler.releaseStateInformation(securityStateReference)
                raise error.StatusInformation(
                    errorIndication=errind.engineIDMismatch)

            # rfc3412: 7.2.13b
            stateReference = self._cache.newStateReference()

            self._cache.pushByStateRef(
                stateReference,
                msgVersion=messageProcessingModel,
                msgID=msgID,
                reqID=reqID,
                contextEngineId=contextEngineId,
                contextName=contextName,
                securityModel=securityModel,
                securityName=securityName,
                securityLevel=securityLevel,
                securityStateReference=securityStateReference,
                msgMaxSize=snmpEngineMaxMessageSize.syntax,
                maxSizeResponseScopedPDU=maxSizeResponseScopedPDU,
                transportDomain=transportDomain,
                transportAddress=transportAddress)

            snmpEngine.observer.storeExecutionContext(
                snmpEngine, 'rfc2576.prepareDataElements:confirmed',
                dict(transportDomain=transportDomain,
                     transportAddress=transportAddress,
                     securityModel=securityModel,
                     securityName=securityName,
                     securityLevel=securityLevel,
                     contextEngineId=contextEngineId,
                     contextName=contextName,
                     securityEngineId=securityEngineId,
                     communityName=communityName,
                     pdu=pdu))

            snmpEngine.observer.clearExecutionContext(
                snmpEngine, 'rfc2576.prepareDataElements:confirmed')

            debug.logger & debug.FLAG_MP and debug.logger(
                'prepareDataElements: cached by new stateReference '
                '%s' % stateReference)

            # rfc3412: 7.2.13c
            return (messageProcessingModel, securityModel, securityName,
                    securityLevel, contextEngineId, contextName, pduVersion,
                    pdu, pduType, sendPduHandle, maxSizeResponseScopedPDU,
                    statusInformation, stateReference)

        # rfc3412: 7.2.14
        if pduType in rfc3411.UNCONFIRMED_CLASS_PDUS:
            # Pass new stateReference to let app browse request details
            stateReference = self._cache.newStateReference()

            snmpEngine.observer.storeExecutionContext(
                snmpEngine, 'rfc2576.prepareDataElements:unconfirmed',
                dict(transportDomain=transportDomain,
                     transportAddress=transportAddress,
                     securityModel=securityModel,
                     securityName=securityName,
                     securityLevel=securityLevel,
                     contextEngineId=contextEngineId,
                     contextName=contextName,
                     securityEngineId=securityEngineId,
                     communityName=communityName,
                     pdu=pdu))

            snmpEngine.observer.clearExecutionContext(
                snmpEngine, 'rfc2576.prepareDataElements:unconfirmed')

            # This is not specified explicitly in RFC
            smHandler.releaseStateInformation(securityStateReference)

            return (messageProcessingModel, securityModel, securityName,
                    securityLevel, contextEngineId, contextName, pduVersion,
                    pdu, pduType, sendPduHandle, maxSizeResponseScopedPDU,
                    statusInformation, stateReference)

        smHandler.releaseStateInformation(securityStateReference)

        raise error.StatusInformation(
            errorIndication=errind.unsupportedPDUtype)
コード例 #3
0
ファイル: rfc2576.py プロジェクト: fyfdoc/IntegrateTest
    def _com2sec(self, snmpEngine, communityName, transportInformation):
        snmpTargetAddrTAddress, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            'SNMP-TARGET-MIB', 'snmpTargetAddrTAddress')
        if self.__transportBranchId != snmpTargetAddrTAddress.branchVersionId:
            (
                SnmpTagValue, snmpTargetAddrTDomain, snmpTargetAddrTagList
            ) = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                'SNMP-TARGET-MIB', 'SnmpTagValue', 'snmpTargetAddrTDomain',
                'snmpTargetAddrTagList')

            self.__emptyTag = SnmpTagValue('')

            self.__transportToTagMap = {}

            nextMibNode = snmpTargetAddrTagList
            while True:
                try:
                    nextMibNode = snmpTargetAddrTagList.getNextNode(
                        nextMibNode.name)
                except NoSuchInstanceError:
                    break
                instId = nextMibNode.name[len(snmpTargetAddrTagList.name):]
                targetAddrTDomain = snmpTargetAddrTDomain.getNode(
                    snmpTargetAddrTDomain.name + instId).syntax
                targetAddrTAddress = snmpTargetAddrTAddress.getNode(
                    snmpTargetAddrTAddress.name + instId).syntax

                targetAddrTDomain = tuple(targetAddrTDomain)

                if targetAddrTDomain[:len(udp.snmpUDPDomain
                                          )] == udp.snmpUDPDomain:
                    SnmpUDPAddress, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                        'SNMPv2-TM', 'SnmpUDPAddress')
                    targetAddrTAddress = tuple(
                        SnmpUDPAddress(targetAddrTAddress))
                elif targetAddrTDomain[:len(udp6.snmpUDP6Domain
                                            )] == udp6.snmpUDP6Domain:
                    TransportAddressIPv6, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                        'TRANSPORT-ADDRESS-MIB', 'TransportAddressIPv6')
                    targetAddrTAddress = tuple(
                        TransportAddressIPv6(targetAddrTAddress))
                elif targetAddrTDomain[:len(unix.snmpLocalDomain
                                            )] == unix.snmpLocalDomain:
                    targetAddrTAddress = str(targetAddrTAddress)
                targetAddr = targetAddrTDomain, targetAddrTAddress
                targetAddrTagList = snmpTargetAddrTagList.getNode(
                    snmpTargetAddrTagList.name + instId).syntax
                if targetAddr not in self.__transportToTagMap:
                    self.__transportToTagMap[targetAddr] = set()
                if targetAddrTagList:
                    self.__transportToTagMap[targetAddr].update([
                        SnmpTagValue(x)
                        for x in targetAddrTagList.asOctets().split()
                    ])
                else:
                    self.__transportToTagMap[targetAddr].add(self.__emptyTag)

            self.__transportBranchId = snmpTargetAddrTAddress.branchVersionId

            debug.logger & debug.flagSM and debug.logger(
                '_com2sec: built transport-to-tag map version %s: %s' %
                (self.__transportBranchId, self.__transportToTagMap))

        snmpTargetParamsSecurityName, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            'SNMP-TARGET-MIB', 'snmpTargetParamsSecurityName')
        if self.__paramsBranchId != snmpTargetParamsSecurityName.branchVersionId:
            snmpTargetParamsSecurityModel, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                'SNMP-TARGET-MIB', 'snmpTargetParamsSecurityModel')

            self.__nameToModelMap = {}

            nextMibNode = snmpTargetParamsSecurityName

            while True:
                try:
                    nextMibNode = snmpTargetParamsSecurityName.getNextNode(
                        nextMibNode.name)

                except NoSuchInstanceError:
                    break

                instId = nextMibNode.name[len(snmpTargetParamsSecurityName.name
                                              ):]

                mibNode = snmpTargetParamsSecurityModel.getNode(
                    snmpTargetParamsSecurityModel.name + instId)

                if nextMibNode.syntax not in self.__nameToModelMap:
                    self.__nameToModelMap[nextMibNode.syntax] = set()

                self.__nameToModelMap[nextMibNode.syntax].add(mibNode.syntax)

            self.__paramsBranchId = snmpTargetParamsSecurityName.branchVersionId

            # invalidate next map as it include this one
            self.__communityBranchId = -1

            debug.logger & debug.flagSM and debug.logger(
                '_com2sec: built securityName to securityModel map, version %s: %s'
                % (self.__paramsBranchId, self.__nameToModelMap))

        snmpCommunityName, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            'SNMP-COMMUNITY-MIB', 'snmpCommunityName')
        if self.__communityBranchId != snmpCommunityName.branchVersionId:
            (
                snmpCommunitySecurityName, snmpCommunityContextEngineId,
                snmpCommunityContextName, snmpCommunityTransportTag
            ) = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                'SNMP-COMMUNITY-MIB', 'snmpCommunitySecurityName',
                'snmpCommunityContextEngineID', 'snmpCommunityContextName',
                'snmpCommunityTransportTag')

            self.__communityToTagMap = {}
            self.__tagAndCommunityToSecurityMap = {}

            nextMibNode = snmpCommunityName
            while True:
                try:
                    nextMibNode = snmpCommunityName.getNextNode(
                        nextMibNode.name)

                except NoSuchInstanceError:
                    break

                instId = nextMibNode.name[len(snmpCommunityName.name):]

                securityName = snmpCommunitySecurityName.getNode(
                    snmpCommunitySecurityName.name + instId).syntax

                contextEngineId = snmpCommunityContextEngineId.getNode(
                    snmpCommunityContextEngineId.name + instId).syntax

                contextName = snmpCommunityContextName.getNode(
                    snmpCommunityContextName.name + instId).syntax

                transportTag = snmpCommunityTransportTag.getNode(
                    snmpCommunityTransportTag.name + instId).syntax

                _tagAndCommunity = transportTag, nextMibNode.syntax

                if _tagAndCommunity not in self.__tagAndCommunityToSecurityMap:
                    self.__tagAndCommunityToSecurityMap[
                        _tagAndCommunity] = set()

                self.__tagAndCommunityToSecurityMap[_tagAndCommunity].add(
                    (securityName, contextEngineId, contextName))

                if nextMibNode.syntax not in self.__communityToTagMap:
                    self.__communityToTagMap[nextMibNode.syntax] = set()

                self.__communityToTagMap[nextMibNode.syntax].add(transportTag)

            self.__communityBranchId = snmpCommunityName.branchVersionId

            debug.logger & debug.flagSM and debug.logger(
                '_com2sec: built communityName to tag map (securityModel %s), version %s: %s'
                % (self.securityModelID, self.__communityBranchId,
                   self.__communityToTagMap))

            debug.logger & debug.flagSM and debug.logger(
                '_com2sec: built tag & community to securityName map (securityModel %s), version %s: %s'
                % (self.securityModelID, self.__communityBranchId,
                   self.__tagAndCommunityToSecurityMap))

        if communityName in self.__communityToTagMap:
            if transportInformation in self.__transportToTagMap:
                tags = self.__transportToTagMap[
                    transportInformation].intersection(
                        self.__communityToTagMap[communityName])
            elif self.__emptyTag in self.__communityToTagMap[communityName]:
                tags = [self.__emptyTag]
            else:
                raise error.StatusInformation(
                    errorIndication=errind.unknownCommunityName)

            candidateSecurityNames = []

            for x in [
                    self.__tagAndCommunityToSecurityMap[(t, communityName)]
                    for t in tags
            ]:
                candidateSecurityNames.extend(list(x))

            # 5.2.1 (row selection in snmpCommunityTable)
            # Picks first match but favors entries already in targets table
            if candidateSecurityNames:
                candidateSecurityNames.sort(
                    key=lambda x, m=self.__nameToModelMap, v=self.
                    securityModelID:
                    (not int(x[0] in m and v in m[x[0]]), str(x[0])))
                chosenSecurityName = candidateSecurityNames[0]  # min()
                debug.logger & debug.flagSM and debug.logger(
                    '_com2sec: securityName candidates for communityName \'%s\' are %s; choosing securityName \'%s\''
                    % (communityName, candidateSecurityNames,
                       chosenSecurityName[0]))
                return chosenSecurityName

        raise error.StatusInformation(
            errorIndication=errind.unknownCommunityName)
コード例 #4
0
    def __cloneUserInfo(self, mibInstrumController, securityEngineID,
                        userName):
        snmpEngineID, = mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
        # Proto entry
        usmUserEntry, = mibInstrumController.mibBuilder.importSymbols(
            'SNMP-USER-BASED-SM-MIB', 'usmUserEntry')
        tblIdx1 = usmUserEntry.getInstIdFromIndices(snmpEngineID.syntax,
                                                    userName)
        # Get proto protocols
        usmUserName = usmUserEntry.getNode(usmUserEntry.name + (2, ) + tblIdx1)
        usmUserSecurityName = usmUserEntry.getNode(usmUserEntry.name + (3, ) +
                                                   tblIdx1)
        usmUserCloneFrom = usmUserEntry.getNode(usmUserEntry.name + (4, ) +
                                                tblIdx1)
        usmUserAuthProtocol = usmUserEntry.getNode(usmUserEntry.name + (5, ) +
                                                   tblIdx1)
        usmUserPrivProtocol = usmUserEntry.getNode(usmUserEntry.name + (8, ) +
                                                   tblIdx1)
        # Get proto keys
        pysnmpUsmKeyEntry, = mibInstrumController.mibBuilder.importSymbols(
            'PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry')
        pysnmpUsmKeyAuth = pysnmpUsmKeyEntry.getNode(pysnmpUsmKeyEntry.name +
                                                     (3, ) + tblIdx1)
        pysnmpUsmKeyPriv = pysnmpUsmKeyEntry.getNode(pysnmpUsmKeyEntry.name +
                                                     (4, ) + tblIdx1)

        # Create new row from proto values

        tblIdx2 = usmUserEntry.getInstIdFromIndices(securityEngineID, userName)

        # New row
        mibInstrumController.writeVars(
            ((usmUserEntry.name + (13, ) + tblIdx2, 4), ))

        # Set user&securityNames
        usmUserEntry.getNode(usmUserEntry.name + (2, ) +
                             tblIdx2).syntax = usmUserName.syntax
        usmUserEntry.getNode(usmUserEntry.name + (3, ) +
                             tblIdx2).syntax = usmUserSecurityName.syntax

        # Store a reference to original row
        usmUserEntry.getNode(usmUserEntry.name + (
            4, ) + tblIdx2).syntax = usmUserCloneFrom.syntax.clone(tblIdx1)

        # Set protocols
        usmUserEntry.getNode(usmUserEntry.name + (5, ) +
                             tblIdx2).syntax = usmUserAuthProtocol.syntax
        usmUserEntry.getNode(usmUserEntry.name + (8, ) +
                             tblIdx2).syntax = usmUserPrivProtocol.syntax

        # Localize and set keys
        pysnmpUsmKeyEntry, = mibInstrumController.mibBuilder.importSymbols(
            'PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry')
        pysnmpUsmKeyAuthLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (1, ) + tblIdx2)
        if usmUserAuthProtocol.syntax in self.authServices:
            localizeKey = self.authServices[
                usmUserAuthProtocol.syntax].localizeKey
            localAuthKey = localizeKey(pysnmpUsmKeyAuth.syntax,
                                       securityEngineID)
        else:
            raise error.StatusInformation(
                errorIndication=errind.unsupportedAuthProtocol)
        if localAuthKey is not None:
            pysnmpUsmKeyAuthLocalized.syntax = pysnmpUsmKeyAuthLocalized.syntax.clone(
                localAuthKey)
        pysnmpUsmKeyPrivLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (2, ) + tblIdx2)
        if usmUserPrivProtocol.syntax in self.privServices:
            localizeKey = self.privServices[
                usmUserPrivProtocol.syntax].localizeKey
            localPrivKey = localizeKey(usmUserAuthProtocol.syntax,
                                       pysnmpUsmKeyPriv.syntax,
                                       securityEngineID)
        else:
            raise error.StatusInformation(
                errorIndication=errind.unsupportedPrivProtocol)
        if localPrivKey is not None:
            pysnmpUsmKeyPrivLocalized.syntax = pysnmpUsmKeyPrivLocalized.syntax.clone(
                localPrivKey)
        return (usmUserName.syntax, usmUserSecurityName.syntax,
                usmUserAuthProtocol.syntax, pysnmpUsmKeyAuthLocalized.syntax,
                usmUserPrivProtocol.syntax, pysnmpUsmKeyPrivLocalized.syntax)
コード例 #5
0
    def processIncomingMsg(
            self,
            snmpEngine,
            messageProcessingModel,
            maxMessageSize,
            securityParameters,
            securityModel,
            securityLevel,
            wholeMsg,
            msg  # XXX 
    ):
        # 3.2.9 -- moved up here to be able to report
        # maxSizeResponseScopedPDU on error
        # (48 - maximum SNMPv3 header length)
        maxSizeResponseScopedPDU = int(maxMessageSize) - len(
            securityParameters) - 48

        debug.logger & debug.flagSM and debug.logger(
            'processIncomingMsg: securityParameters %s' %
            debug.hexdump(securityParameters))

        # 3.2.1
        try:
            securityParameters, rest = decoder.decode(
                securityParameters, asn1Spec=self.__securityParametersSpec)
        except PyAsn1Error:
            debug.logger & debug.flagSM and debug.logger(
                'processIncomingMsg: %s' % (sys.exc_info()[1], ))
            snmpInASNParseErrs, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                '__SNMPv2-MIB', 'snmpInASNParseErrs')
            snmpInASNParseErrs.syntax = snmpInASNParseErrs.syntax + 1
            raise error.StatusInformation(errorIndication=errind.parseError)

        debug.logger & debug.flagSM and debug.logger(
            'processIncomingMsg: %s' % (securityParameters.prettyPrint(), ))

        if eoo.endOfOctets.isSameTypeWith(securityParameters):
            raise error.StatusInformation(errorIndication=errind.parseError)

        # 3.2.2
        msgAuthoritativeEngineID = securityParameters.getComponentByPosition(0)
        securityStateReference = self._cache.push(
            msgUserName=securityParameters.getComponentByPosition(3))

        debug.logger & debug.flagSM and debug.logger(
            'processIncomingMsg: cache write securityStateReference %s by msgUserName %s'
            % (securityStateReference,
               securityParameters.getComponentByPosition(3)))

        scopedPduData = msg.getComponentByPosition(3)

        # Used for error reporting
        contextEngineId = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineID')[0].syntax
        contextName = null

        # 3.2.3
        if msgAuthoritativeEngineID not in self.__timeline:
            debug.logger & debug.flagSM and debug.logger(
                'processIncomingMsg: unknown securityEngineID %r' %
                (msgAuthoritativeEngineID, ))
            if not msgAuthoritativeEngineID or  \
                    not 4 < len(msgAuthoritativeEngineID) < 33:
                # 3.2.3b
                usmStatsUnknownEngineIDs, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownEngineIDs')
                usmStatsUnknownEngineIDs.syntax = usmStatsUnknownEngineIDs.syntax + 1
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: null or malformed msgAuthoritativeEngineID'
                )
                pysnmpUsmDiscoverable, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__PYSNMP-USM-MIB', 'pysnmpUsmDiscoverable')
                if pysnmpUsmDiscoverable.syntax:
                    debug.logger & debug.flagSM and debug.logger(
                        'processIncomingMsg: starting snmpEngineID discovery procedure'
                    )

                    # Report original contextName
                    if scopedPduData.getName() != 'plaintext':
                        debug.logger & debug.flagSM and debug.logger(
                            'processIncomingMsg: scopedPduData not plaintext %s'
                            % scopedPduData.prettyPrint())
                        raise error.StatusInformation(
                            errorIndication=errind.unknownEngineID)

                    # 7.2.6.a.1
                    scopedPdu = scopedPduData.getComponent()
                    contextEngineId = scopedPdu.getComponentByPosition(0)
                    contextName = scopedPdu.getComponentByPosition(1)

                    raise error.StatusInformation(
                        errorIndication=errind.unknownEngineID,
                        oid=usmStatsUnknownEngineIDs.name,
                        val=usmStatsUnknownEngineIDs.syntax,
                        securityStateReference=securityStateReference,
                        securityLevel=securityLevel,
                        contextEngineId=contextEngineId,
                        contextName=contextName,
                        scopedPDU=scopedPdu,
                        maxSizeResponseScopedPDU=maxSizeResponseScopedPDU)
                else:
                    debug.logger & debug.flagSM and debug.logger(
                        'processIncomingMsg: will not discover EngineID')
                    # free securityStateReference XXX
                    raise error.StatusInformation(
                        errorIndication=errind.unknownEngineID)

        snmpEngineID = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineID')[0].syntax

        msgUserName = securityParameters.getComponentByPosition(3)

        debug.logger & debug.flagSM and debug.logger(
            'processIncomingMsg: read from securityParams msgAuthoritativeEngineID %r msgUserName %r'
            % (msgAuthoritativeEngineID, msgUserName))

        if msgUserName:
            # 3.2.4
            try:
                (usmUserName, usmUserSecurityName, usmUserAuthProtocol,
                 usmUserAuthKeyLocalized, usmUserPrivProtocol,
                 usmUserPrivKeyLocalized) = self.__getUserInfo(
                     snmpEngine.msgAndPduDsp.mibInstrumController,
                     msgAuthoritativeEngineID, msgUserName)
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: read user info from LCD')
            except NoSuchInstanceError:
                pysnmpUsmDiscoverable, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__PYSNMP-USM-MIB', 'pysnmpUsmDiscoverable')
                __reportUnknownName = not pysnmpUsmDiscoverable.syntax
                if not __reportUnknownName:
                    try:
                        (usmUserName, usmUserSecurityName, usmUserAuthProtocol,
                         usmUserAuthKeyLocalized, usmUserPrivProtocol,
                         usmUserPrivKeyLocalized) = self.__cloneUserInfo(
                             snmpEngine.msgAndPduDsp.mibInstrumController,
                             msgAuthoritativeEngineID, msgUserName)
                        debug.logger & debug.flagSM and debug.logger(
                            'processIncomingMsg: cloned user info')
                    except NoSuchInstanceError:
                        __reportUnknownName = 1
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: unknown securityEngineID %r msgUserName %r'
                    % (msgAuthoritativeEngineID, msgUserName))
                if __reportUnknownName:
                    usmStatsUnknownUserNames, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                        '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownUserNames')
                    usmStatsUnknownUserNames.syntax = usmStatsUnknownUserNames.syntax + 1
                    raise error.StatusInformation(
                        errorIndication=errind.unknownSecurityName,
                        oid=usmStatsUnknownUserNames.name,
                        val=usmStatsUnknownUserNames.syntax,
                        securityStateReference=securityStateReference,
                        securityLevel=securityLevel,
                        contextEngineId=contextEngineId,
                        contextName=contextName,
                        maxSizeResponseScopedPDU=maxSizeResponseScopedPDU)
            except PyAsn1Error:
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: %s' % (sys.exc_info()[1], ))
                snmpInGenErrs, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__SNMPv2-MIB', 'snmpInGenErrs')
                snmpInGenErrs.syntax = snmpInGenErrs.syntax + 1
                raise error.StatusInformation(
                    errorIndication=errind.invalidMsg)
        else:
            # empty username used for engineID discovery
            usmUserName = usmUserSecurityName = null
            usmUserAuthProtocol = noauth.NoAuth.serviceID
            usmUserPrivProtocol = nopriv.NoPriv.serviceID
            usmUserAuthKeyLocalized = usmUserPrivKeyLocalized = None

        debug.logger & debug.flagSM and debug.logger(
            'processIncomingMsg: now have usmUserName %r usmUserSecurityName %r usmUserAuthProtocol %r usmUserPrivProtocol %r for msgUserName %r'
            % (usmUserName, usmUserSecurityName, usmUserAuthProtocol,
               usmUserPrivProtocol, msgUserName))

        # 3.2.11 (moved up here to let Reports be authenticated & encrypted)
        self._cache.pop(securityStateReference)
        securityStateReference = self._cache.push(
            msgUserName=securityParameters.getComponentByPosition(3),
            usmUserSecurityName=usmUserSecurityName,
            usmUserAuthProtocol=usmUserAuthProtocol,
            usmUserAuthKeyLocalized=usmUserAuthKeyLocalized,
            usmUserPrivProtocol=usmUserPrivProtocol,
            usmUserPrivKeyLocalized=usmUserPrivKeyLocalized)

        msgAuthoritativeEngineBoots = securityParameters.getComponentByPosition(
            1)
        msgAuthoritativeEngineTime = securityParameters.getComponentByPosition(
            2)

        # 3.2.5
        if msgAuthoritativeEngineID == snmpEngineID:
            # Authoritative SNMP engine: make sure securityLevel is sufficient
            __badSecIndication = None
            if securityLevel == 3:
                if usmUserAuthProtocol == noauth.NoAuth.serviceID:
                    __badSecIndication = 'authPriv wanted while auth not expected'
                if usmUserPrivProtocol == nopriv.NoPriv.serviceID:
                    __badSecIndication = 'authPriv wanted while priv not expected'
            elif securityLevel == 2:
                if usmUserAuthProtocol == noauth.NoAuth.serviceID:
                    __badSecIndication = 'authNoPriv wanted while auth not expected'
                if usmUserPrivProtocol != nopriv.NoPriv.serviceID:
                    # 4 (discovery phase always uses authenticated messages)
                    if msgAuthoritativeEngineBoots or msgAuthoritativeEngineTime:
                        __badSecIndication = 'authNoPriv wanted while priv expected'

            elif securityLevel == 1:
                if usmUserAuthProtocol != noauth.NoAuth.serviceID:
                    __badSecIndication = 'noAuthNoPriv wanted while auth expected'
                if usmUserPrivProtocol != nopriv.NoPriv.serviceID:
                    __badSecIndication = 'noAuthNoPriv wanted while priv expected'
            if __badSecIndication:
                usmStatsUnsupportedSecLevels, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnsupportedSecLevels')
                usmStatsUnsupportedSecLevels.syntax = usmStatsUnsupportedSecLevels.syntax + 1
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: reporting inappropriate security level for user %s: %s'
                    % (msgUserName, __badSecIndication))
                raise error.StatusInformation(
                    errorIndication=errind.unsupportedSecurityLevel,
                    oid=usmStatsUnsupportedSecLevels.name,
                    val=usmStatsUnsupportedSecLevels.syntax,
                    securityStateReference=securityStateReference,
                    securityLevel=securityLevel,
                    contextEngineId=contextEngineId,
                    contextName=contextName,
                    maxSizeResponseScopedPDU=maxSizeResponseScopedPDU)

        # 3.2.6
        if securityLevel == 3 or securityLevel == 2:
            if usmUserAuthProtocol in self.authServices:
                authHandler = self.authServices[usmUserAuthProtocol]
            else:
                raise error.StatusInformation(
                    errorIndication=errind.authenticationFailure)
            try:
                authenticatedWholeMsg = authHandler.authenticateIncomingMsg(
                    usmUserAuthKeyLocalized,
                    securityParameters.getComponentByPosition(4), wholeMsg)
            except error.StatusInformation:
                usmStatsWrongDigests, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__SNMP-USER-BASED-SM-MIB', 'usmStatsWrongDigests')
                usmStatsWrongDigests.syntax = usmStatsWrongDigests.syntax + 1
                raise error.StatusInformation(
                    errorIndication=errind.authenticationFailure,
                    oid=usmStatsWrongDigests.name,
                    val=usmStatsWrongDigests.syntax,
                    securityStateReference=securityStateReference,
                    securityLevel=securityLevel,
                    contextEngineId=contextEngineId,
                    contextName=contextName,
                    maxSizeResponseScopedPDU=maxSizeResponseScopedPDU)

            debug.logger & debug.flagSM and debug.logger(
                'processIncomingMsg: incoming msg authenticated')

            if msgAuthoritativeEngineID:
                # 3.2.3a moved down here to execute only for authed msg
                self.__timeline[msgAuthoritativeEngineID] = (
                    securityParameters.getComponentByPosition(1),
                    securityParameters.getComponentByPosition(2),
                    securityParameters.getComponentByPosition(2),
                    int(time.time()))

                expireAt = int(
                    self.__expirationTimer +
                    300 / snmpEngine.transportDispatcher.getTimerResolution())
                if expireAt not in self.__timelineExpQueue:
                    self.__timelineExpQueue[expireAt] = []
                self.__timelineExpQueue[expireAt].append(
                    msgAuthoritativeEngineID)

                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: store timeline for securityEngineID %r'
                    % (msgAuthoritativeEngineID, ))

        # 3.2.7
        if securityLevel == 3 or securityLevel == 2:
            if msgAuthoritativeEngineID == snmpEngineID:
                # Authoritative SNMP engine: use local notion (SF bug #1649032)
                (
                    snmpEngineBoots, snmpEngineTime
                ) = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__SNMP-FRAMEWORK-MIB', 'snmpEngineBoots',
                    'snmpEngineTime')
                snmpEngineBoots = snmpEngineBoots.syntax
                snmpEngineTime = snmpEngineTime.syntax.clone()
                idleTime = 0
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: read snmpEngineBoots (%s), snmpEngineTime (%s) from LCD'
                    % (snmpEngineBoots, snmpEngineTime))
            else:
                # Non-authoritative SNMP engine: use cached estimates
                if msgAuthoritativeEngineID in self.__timeline:
                    (snmpEngineBoots, snmpEngineTime, latestReceivedEngineTime,
                     latestUpdateTimestamp
                     ) = self.__timeline[msgAuthoritativeEngineID]
                    # time passed since last talk with this SNMP engine
                    idleTime = int(time.time()) - latestUpdateTimestamp
                    debug.logger & debug.flagSM and debug.logger(
                        'processIncomingMsg: read timeline snmpEngineBoots %s snmpEngineTime %s for msgAuthoritativeEngineID %r, idle time %s secs'
                        % (snmpEngineBoots, snmpEngineTime,
                           msgAuthoritativeEngineID, idleTime))
                else:
                    raise error.ProtocolError('Peer SNMP engine info missing')

            # 3.2.7a
            if msgAuthoritativeEngineID == snmpEngineID:
                if snmpEngineBoots == 2147483647 or \
                   snmpEngineBoots != msgAuthoritativeEngineBoots or \
                   abs(idleTime + int(snmpEngineTime) - \
                       int(msgAuthoritativeEngineTime)) > 150:
                    usmStatsNotInTimeWindows, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                        '__SNMP-USER-BASED-SM-MIB', 'usmStatsNotInTimeWindows')
                    usmStatsNotInTimeWindows.syntax = usmStatsNotInTimeWindows.syntax + 1
                    raise error.StatusInformation(
                        errorIndication=errind.notInTimeWindow,
                        oid=usmStatsNotInTimeWindows.name,
                        val=usmStatsNotInTimeWindows.syntax,
                        securityStateReference=securityStateReference,
                        securityLevel=2,
                        contextEngineId=contextEngineId,
                        contextName=contextName,
                        maxSizeResponseScopedPDU=maxSizeResponseScopedPDU)
            # 3.2.7b
            else:
                # 3.2.7b.1
                if msgAuthoritativeEngineBoots > snmpEngineBoots or \
                   msgAuthoritativeEngineBoots == snmpEngineBoots and \
                   msgAuthoritativeEngineTime > latestReceivedEngineTime:
                    self.__timeline[msgAuthoritativeEngineID] = (
                        msgAuthoritativeEngineBoots,
                        msgAuthoritativeEngineTime, msgAuthoritativeEngineTime,
                        int(time.time()))
                    expireAt = int(
                        self.__expirationTimer + 300 /
                        snmpEngine.transportDispatcher.getTimerResolution())
                    if expireAt not in self.__timelineExpQueue:
                        self.__timelineExpQueue[expireAt] = []
                    self.__timelineExpQueue[expireAt].append(
                        msgAuthoritativeEngineID)

                    debug.logger & debug.flagSM and debug.logger(
                        'processIncomingMsg: stored timeline msgAuthoritativeEngineBoots %s msgAuthoritativeEngineTime %s for msgAuthoritativeEngineID %r'
                        %
                        (msgAuthoritativeEngineBoots,
                         msgAuthoritativeEngineTime, msgAuthoritativeEngineID))

                # 3.2.7b.2
                if snmpEngineBoots == 2147483647 or \
                   msgAuthoritativeEngineBoots < snmpEngineBoots or \
                   msgAuthoritativeEngineBoots == snmpEngineBoots and \
                   abs(idleTime + int(snmpEngineTime) - \
                       int(msgAuthoritativeEngineTime)) > 150:
                    raise error.StatusInformation(
                        errorIndication=errind.notInTimeWindow)

        # 3.2.8a
        if securityLevel == 3:
            if usmUserPrivProtocol in self.privServices:
                privHandler = self.privServices[usmUserPrivProtocol]
            else:
                raise error.StatusInformation(
                    errorIndication=errind.decryptionError)
            encryptedPDU = scopedPduData.getComponentByPosition(1)
            if encryptedPDU is None:  # no ciphertext
                raise error.StatusInformation(
                    errorIndication=errind.decryptionError)

            try:
                decryptedData = privHandler.decryptData(
                    usmUserPrivKeyLocalized,
                    (securityParameters.getComponentByPosition(1),
                     securityParameters.getComponentByPosition(2),
                     securityParameters.getComponentByPosition(5)),
                    encryptedPDU)
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: PDU deciphered into %s' %
                    debug.hexdump(decryptedData))
            except error.StatusInformation:
                usmStatsDecryptionErrors, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__SNMP-USER-BASED-SM-MIB', 'usmStatsDecryptionErrors')
                usmStatsDecryptionErrors.syntax = usmStatsDecryptionErrors.syntax + 1
                raise error.StatusInformation(
                    errorIndication=errind.decryptionError,
                    oid=usmStatsDecryptionErrors.name,
                    val=usmStatsDecryptionErrors.syntax,
                    securityStateReference=securityStateReference,
                    securityLevel=securityLevel,
                    contextEngineId=contextEngineId,
                    contextName=contextName,
                    maxSizeResponseScopedPDU=maxSizeResponseScopedPDU)
            scopedPduSpec = scopedPduData.setComponentByPosition(
                0).getComponentByPosition(0)
            try:
                scopedPDU, rest = decoder.decode(decryptedData,
                                                 asn1Spec=scopedPduSpec)
            except PyAsn1Error:
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: scopedPDU decoder failed %s' %
                    sys.exc_info()[0])
                raise error.StatusInformation(
                    errorIndication=errind.decryptionError)

            if eoo.endOfOctets.isSameTypeWith(scopedPDU):
                raise error.StatusInformation(
                    errorIndication=errind.decryptionError)
        else:
            # 3.2.8b
            scopedPDU = scopedPduData.getComponentByPosition(0)
            if scopedPDU is None:  # no plaintext
                raise error.StatusInformation(
                    errorIndication=errind.decryptionError)

        debug.logger & debug.flagSM and debug.logger(
            'processIncomingMsg: scopedPDU decoded %s' %
            scopedPDU.prettyPrint())

        # 3.2.10
        securityName = usmUserSecurityName

        debug.logger & debug.flagSM and debug.logger(
            'processIncomingMsg: cached msgUserName %s info by securityStateReference %s'
            % (msgUserName, securityStateReference))

        # Delayed to include details
        if not msgUserName and not msgAuthoritativeEngineID:
            usmStatsUnknownUserNames, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownUserNames')
            usmStatsUnknownUserNames.syntax = usmStatsUnknownUserNames.syntax + 1
            raise error.StatusInformation(
                errorIndication=errind.unknownSecurityName,
                oid=usmStatsUnknownUserNames.name,
                val=usmStatsUnknownUserNames.syntax,
                securityStateReference=securityStateReference,
                securityEngineID=msgAuthoritativeEngineID,
                securityLevel=securityLevel,
                contextEngineId=contextEngineId,
                contextName=contextName,
                maxSizeResponseScopedPDU=maxSizeResponseScopedPDU,
                PDU=scopedPDU)

        # 3.2.12
        return (msgAuthoritativeEngineID, securityName, scopedPDU,
                maxSizeResponseScopedPDU, securityStateReference)
コード例 #6
0
ファイル: rfc2576.py プロジェクト: ithek/pysnmp
def v2ToV1(v2Pdu, origV1Pdu=None):
    debug.logger & debug.flagPrx and debug.logger(
        'v2ToV1: v2Pdu %s' % v2Pdu.prettyPrint())

    pduType = v2Pdu.tagSet

    if pduType in __v2ToV1PduMap:
        v1Pdu = __v2ToV1PduMap[pduType].clone()
    else:
        raise error.ProtocolError('Unsupported PDU type')

    v2VarBinds = v2c.apiPDU.getVarBinds(v2Pdu)
    v1VarBinds = []

    # 3.2
    if pduType in rfc3411.notificationClassPDUs:
        # 3.2.1
        (snmpTrapOID, snmpTrapOIDParam) = v2VarBinds[1]
        if snmpTrapOID != v2c.apiTrapPDU.snmpTrapOID:
            raise error.ProtocolError('Second OID not snmpTrapOID')

        if snmpTrapOIDParam in __v2ToV1TrapMap:
            for oid, val in v2VarBinds:
                if oid == v2c.apiTrapPDU.snmpTrapEnterprise:
                    v1.apiTrapPDU.setEnterprise(v1Pdu, val)
                    break
            else:
                # snmpTraps
                v1.apiTrapPDU.setEnterprise(v1Pdu, (1, 3, 6, 1, 6, 3, 1, 1, 5))
        else:
            if snmpTrapOIDParam[-2] == 0:
                v1.apiTrapPDU.setEnterprise(v1Pdu, snmpTrapOIDParam[:-2])
            else:
                v1.apiTrapPDU.setEnterprise(v1Pdu, snmpTrapOIDParam[:-1])

        # 3.2.2
        for oid, val in v2VarBinds:
            # snmpTrapAddress
            if oid == v2c.apiTrapPDU.snmpTrapAddress:
                v1.apiTrapPDU.setAgentAddr(v1Pdu, val)
                break
        else:
            v1.apiTrapPDU.setAgentAddr(v1Pdu, v1.apiTrapPDU.agentAddress)

        # 3.2.3
        if snmpTrapOIDParam in __v2ToV1TrapMap:
            v1.apiTrapPDU.setGenericTrap(v1Pdu,
                                         __v2ToV1TrapMap[snmpTrapOIDParam])
        else:
            v1.apiTrapPDU.setGenericTrap(v1Pdu, 6)

        # 3.2.4
        if snmpTrapOIDParam in __v2ToV1TrapMap:
            v1.apiTrapPDU.setSpecificTrap(v1Pdu, __zeroInt)
        else:
            v1.apiTrapPDU.setSpecificTrap(v1Pdu, snmpTrapOIDParam[-1])

        # 3.2.5
        v1.apiTrapPDU.setTimeStamp(v1Pdu, v2VarBinds[0][1])

        __v2VarBinds = []
        for oid, val in v2VarBinds[2:]:
            if oid in __v2ToV1TrapMap or \
                   oid in (v2c.apiTrapPDU.sysUpTime,
                           v2c.apiTrapPDU.snmpTrapAddress,
                           v2c.apiTrapPDU.snmpTrapEnterprise):
                continue
            __v2VarBinds.append((oid, val))
        v2VarBinds = __v2VarBinds

        # 3.2.6 --> done below

    else:
        v1.apiPDU.setErrorStatus(v1Pdu, __zeroInt)
        v1.apiPDU.setErrorIndex(v1Pdu, __zeroInt)

    if pduType in rfc3411.responseClassPDUs:
        idx = len(v2VarBinds) - 1
        while idx >= 0:
            # 4.1.2.1
            oid, val = v2VarBinds[idx]
            if v2c.Counter64.tagSet == val.tagSet:
                if origV1Pdu.tagSet == v1.GetRequestPDU.tagSet:
                    v1.apiPDU.setErrorStatus(v1Pdu, 2)
                    v1.apiPDU.setErrorIndex(v1Pdu, idx + 1)
                    break
                elif origV1Pdu.tagSet == v1.GetNextRequestPDU.tagSet:
                    raise error.StatusInformation(idx=idx, pdu=v2Pdu)
                else:
                    raise error.ProtocolError('Counter64 on the way')

            # 4.1.2.2.1&2
            if val.tagSet in (v2c.NoSuchObject.tagSet,
                              v2c.NoSuchInstance.tagSet,
                              v2c.EndOfMibView.tagSet):
                v1.apiPDU.setErrorStatus(v1Pdu, 2)
                v1.apiPDU.setErrorIndex(v1Pdu, idx + 1)

            idx = idx - 1

        # 4.1.2.3.1
        v2ErrorStatus = v2c.apiPDU.getErrorStatus(v2Pdu)
        if v2ErrorStatus:
            v1.apiPDU.setErrorStatus(v1Pdu, __v2ToV1ErrorMap[v2ErrorStatus])
            v1.apiPDU.setErrorIndex(v1Pdu, v2c.apiPDU.getErrorIndex(v2Pdu))

    # Translate Var-Binds
    if pduType in rfc3411.responseClassPDUs and \
           v1.apiPDU.getErrorStatus(v1Pdu):
        v1VarBinds = v1.apiPDU.getVarBinds(origV1Pdu)
    else:
        for oid, v2Val in v2VarBinds:
            v1VarBinds.append(
                (oid, __v2ToV1ValueMap[v2Val.tagSet].clone(v2Val)))

    if pduType in rfc3411.notificationClassPDUs:
        v1.apiTrapPDU.setVarBinds(v1Pdu, v1VarBinds)
    else:
        v1.apiPDU.setVarBinds(v1Pdu, v1VarBinds)

        v1.apiPDU.setRequestID(v1Pdu, v2c.apiPDU.getRequestID(v2Pdu))

    debug.logger & debug.flagPrx and debug.logger(
        'v2ToV1: v1Pdu %s' % v1Pdu.prettyPrint())

    return v1Pdu
コード例 #7
0
ファイル: rfc3412.py プロジェクト: rsmetana/Python
    def returnResponsePdu(self, snmpEngine, messageProcessingModel,
                          securityModel, securityName, securityLevel,
                          contextEngineId, contextName, pduVersion, PDU,
                          maxSizeResponseScopedPDU, stateReference,
                          statusInformation):
        # Extract input values and initialize defaults
        k = int(messageProcessingModel)
        if k in snmpEngine.messageProcessingSubsystems:
            mpHandler = snmpEngine.messageProcessingSubsystems[k]
        else:
            raise error.StatusInformation(
                errorIndication=errind.unsupportedMsgProcessingModel)

        debug.logger & debug.flagDsp and debug.logger(
            'returnResponsePdu: PDU %s' %
            (PDU and PDU.prettyPrint() or "<empty>", ))

        # 4.1.2.2
        try:
            (transportDomain, transportAddress,
             outgoingMessage) = mpHandler.prepareResponseMessage(
                 snmpEngine, messageProcessingModel, securityModel,
                 securityName, securityLevel, contextEngineId, contextName,
                 pduVersion, PDU, maxSizeResponseScopedPDU, stateReference,
                 statusInformation)

            debug.logger & debug.flagDsp and debug.logger(
                'returnResponsePdu: MP suceeded')

        except error.StatusInformation:
            # 4.1.2.3
            raise

        # Handle oversized messages XXX transport constrains?
        snmpEngineMaxMessageSize, = self.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineMaxMessageSize')
        if (snmpEngineMaxMessageSize.syntax
                and len(outgoingMessage) > snmpEngineMaxMessageSize.syntax):
            snmpSilentDrops, = self.mibInstrumController.mibBuilder.importSymbols(
                '__SNMPv2-MIB', 'snmpSilentDrops')
            snmpSilentDrops.syntax += 1
            raise error.StatusInformation(errorIndication=errind.tooBig)

        snmpEngine.observer.storeExecutionContext(
            snmpEngine, 'rfc3412.returnResponsePdu',
            dict(transportDomain=transportDomain,
                 transportAddress=transportAddress,
                 outgoingMessage=outgoingMessage,
                 messageProcessingModel=messageProcessingModel,
                 securityModel=securityModel,
                 securityName=securityName,
                 securityLevel=securityLevel,
                 contextEngineId=contextEngineId,
                 contextName=contextName,
                 pdu=PDU))

        # 4.1.2.4
        snmpEngine.transportDispatcher.sendMessage(outgoingMessage,
                                                   transportDomain,
                                                   transportAddress)

        snmpEngine.observer.clearExecutionContext(snmpEngine,
                                                  'rfc3412.returnResponsePdu')
コード例 #8
0
ファイル: rfc3412.py プロジェクト: rishie/testerman
        # 7.2.8
        pduVersion = api.protoVersion2c

        # 7.2.9
        pduType = pdu.tagSet

        # 7.2.10
        if rfc3411.responseClassPDUs.has_key(pduType) or \
               rfc3411.internalClassPDUs.has_key(pduType):
            # 7.2.10a
            try:
                cachedReqParams = self._cachePopByMsgId(msgID)
            except error.ProtocolError:
                smHandler.releaseStateInformation(securityStateReference)
                raise error.StatusInformation(errorIndication='dataMismatch')
            # 7.2.10b
            sendPduHandle = cachedReqParams['sendPduHandle']
        else:
            sendPduHandle = None

        debug.logger & debug.flagMP and debug.logger(
            'prepareDataElements: using sendPduHandle %s for msgID %s' %
            (sendPduHandle, msgID))

        # 7.2.11
        if rfc3411.internalClassPDUs.has_key(pduType):
            # 7.2.11a
            varBinds = pMod.apiPDU.getVarBinds(pdu)
            if varBinds:
                statusInformation = error.StatusInformation(
コード例 #9
0
ファイル: rfc3412.py プロジェクト: rishie/testerman
    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, statusInformation:
            # 7.1.8.b
            raise
コード例 #10
0
    def prepareResponseMessage(self, snmpEngine, messageProcessingModel,
                               securityModel, securityName, securityLevel,
                               contextEngineId, contextName, pduVersion, pdu,
                               maxSizeResponseScopedPDU, stateReference,
                               statusInformation):

        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        snmpEngineID, = 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.FLAG_MP 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.CONFIRMED_CLASS_PDUS):
                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.FLAG_MP 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.FLAG_MP 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.MESSAGE_PROCESSING_MODEL_ID,
                                   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, = 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.CONFIRMED_CLASS_PDUS:  # 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.FLAG_MP 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.FLAG_MP 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.MESSAGE_PROCESSING_MODEL_ID, msg,
                snmpEngineMaxMessageSize.syntax, securityModel, snmpEngineID,
                securityName, securityLevel, scopedPDU, securityStateReference)

        except error.StatusInformation:
            # 7.1.8.b
            raise

        debug.logger & debug.FLAG_MP 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
コード例 #11
0
    def prepareDataElements(self, snmpEngine, transportDomain,
                            transportAddress, wholeMsg):
        # 7.2.2
        msg, restOfwholeMsg = decoder.decode(wholeMsg,
                                             asn1Spec=self._snmpMsgSpec)

        debug.logger & debug.FLAG_MP and debug.logger(
            'prepareDataElements: %s' % (msg.prettyPrint(), ))

        if eoo.endOfOctets.isSameTypeWith(msg):
            raise error.StatusInformation(errorIndication=errind.parseError)

        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        # 7.2.3
        headerData = msg.getComponentByPosition(1)
        msgVersion = messageProcessingModel = msg.getComponentByPosition(0)
        msgID = headerData.getComponentByPosition(0)
        msgFlags, = headerData.getComponentByPosition(2).asNumbers()
        maxMessageSize = headerData.getComponentByPosition(1)
        securityModel = headerData.getComponentByPosition(3)
        securityParameters = msg.getComponentByPosition(2)

        debug.logger & debug.FLAG_MP and debug.logger(
            'prepareDataElements: msg data msgVersion %s msgID %s '
            'securityModel %s' % (msgVersion, msgID, securityModel))

        # 7.2.4
        if securityModel not in snmpEngine.securityModels:
            snmpUnknownSecurityModels, = mibBuilder.importSymbols(
                '__SNMP-MPD-MIB', 'snmpUnknownSecurityModels')
            snmpUnknownSecurityModels.syntax += 1
            raise error.StatusInformation(
                errorIndication=errind.unsupportedSecurityModel)

        # 7.2.5
        if msgFlags & 0x03 == 0x00:
            securityLevel = 1

        elif (msgFlags & 0x03) == 0x01:
            securityLevel = 2

        elif (msgFlags & 0x03) == 0x03:
            securityLevel = 3

        else:
            snmpInvalidMsgs, = mibBuilder.importSymbols(
                '__SNMP-MPD-MIB', 'snmpInvalidMsgs')
            snmpInvalidMsgs.syntax += 1
            raise error.StatusInformation(errorIndication=errind.invalidMsg)

        if msgFlags & 0x04:
            reportableFlag = 1

        else:
            reportableFlag = 0

        # 7.2.6
        smHandler = snmpEngine.securityModels[securityModel]

        try:
            (securityEngineId, securityName, scopedPDU,
             maxSizeResponseScopedPDU,
             securityStateReference) = smHandler.processIncomingMsg(
                 snmpEngine, messageProcessingModel, maxMessageSize,
                 securityParameters, securityModel, securityLevel, wholeMsg,
                 msg)

            debug.logger & debug.FLAG_MP and debug.logger(
                'prepareDataElements: SM succeeded')

        except error.StatusInformation as exc:
            statusInformation = exc

            debug.logger & debug.FLAG_MP and debug.logger(
                'prepareDataElements: SM failed, statusInformation '
                '%s' % statusInformation)

            snmpEngine.observer.storeExecutionContext(
                snmpEngine, 'rfc3412.prepareDataElements:sm-failure',
                dict(transportDomain=transportDomain,
                     transportAddress=transportAddress,
                     securityModel=securityModel,
                     securityLevel=securityLevel,
                     securityParameters=securityParameters,
                     statusInformation=statusInformation))

            snmpEngine.observer.clearExecutionContext(
                snmpEngine, 'rfc3412.prepareDataElements:sm-failure')

            if 'errorIndication' in statusInformation:
                # 7.2.6a
                if 'oid' in statusInformation:
                    # 7.2.6a1
                    securityStateReference = statusInformation[
                        'securityStateReference']
                    contextEngineId = statusInformation['contextEngineId']
                    contextName = statusInformation['contextName']

                    if 'scopedPDU' in statusInformation:
                        scopedPDU = statusInformation['scopedPDU']
                        pdu = scopedPDU.getComponentByPosition(
                            2).getComponent()

                    else:
                        pdu = None

                    maxSizeResponseScopedPDU = statusInformation[
                        'maxSizeResponseScopedPDU']
                    securityName = None  # XXX secmod cache used

                    # 7.2.6a2
                    stateReference = self._cache.newStateReference()

                    self._cache.pushByStateRef(
                        stateReference,
                        msgVersion=messageProcessingModel,
                        msgID=msgID,
                        contextEngineId=contextEngineId,
                        contextName=contextName,
                        securityModel=securityModel,
                        securityName=securityName,
                        securityLevel=securityLevel,
                        securityStateReference=securityStateReference,
                        reportableFlag=reportableFlag,
                        msgMaxSize=maxMessageSize,
                        maxSizeResponseScopedPDU=maxSizeResponseScopedPDU,
                        transportDomain=transportDomain,
                        transportAddress=transportAddress)

                    # 7.2.6a3
                    try:
                        snmpEngine.msgAndPduDsp.returnResponsePdu(
                            snmpEngine, 3, securityModel, securityName,
                            securityLevel, contextEngineId, contextName, 1,
                            pdu, maxSizeResponseScopedPDU, stateReference,
                            statusInformation)

                    except error.StatusInformation:
                        pass

                    debug.logger & debug.FLAG_MP and debug.logger(
                        'prepareDataElements: error reported')

            # 7.2.6b
            if sys.version_info[0] <= 2:
                raise statusInformation

            else:
                origTraceback = sys.exc_info()[2]

                try:
                    raise statusInformation.with_traceback(origTraceback)

                finally:
                    # Break cycle between locals and traceback object
                    # (seems to be irrelevant on Py3 but just in case)
                    del origTraceback
        else:
            # Sniff for engineIdCache
            k = transportDomain, transportAddress
            if k not in self._engineIdCache:
                contextEngineId = scopedPDU[0]
                contextName = scopedPDU[1]

                pdus = scopedPDU[2]
                pdu = pdus.getComponent()

                # Here we assume that authentic/default EngineIDs
                # come only in the course of engine-to-engine communication.
                if pdu.tagSet in rfc3411.INTERNAL_CLASS_PDUS:
                    self._engineIdCache[k] = {
                        'securityEngineId': securityEngineId,
                        'contextEngineId': contextEngineId,
                        'contextName': contextName
                    }

                    timerResolution = snmpEngine.transportDispatcher.getTimerResolution(
                    )
                    expireAt = int(self._expirationTimer +
                                   300 / timerResolution)

                    if expireAt not in self._engineIdCacheExpQueue:
                        self._engineIdCacheExpQueue[expireAt] = []

                    self._engineIdCacheExpQueue[expireAt].append(k)

                    debug.logger & debug.FLAG_MP and debug.logger(
                        'prepareDataElements: cache securityEngineId %r for %r %r'
                        %
                        (securityEngineId, transportDomain, transportAddress))

        snmpEngineID, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB',
                                                 'snmpEngineID')
        snmpEngineID = snmpEngineID.syntax

        # 7.2.7 XXX PDU would be parsed here?
        contextEngineId = scopedPDU[0]
        contextName = scopedPDU[1]
        pdu = scopedPDU[2]

        pdu = pdu.getComponent()  # PDUs

        # 7.2.8
        pduVersion = api.SNMP_VERSION_2C

        # 7.2.9
        pduType = pdu.tagSet

        # 7.2.10
        if (pduType in rfc3411.RESPONSE_CLASS_PDUS
                or pduType in rfc3411.INTERNAL_CLASS_PDUS):
            # 7.2.10a
            try:
                cachedReqParams = self._cache.popByMsgId(msgID)

            except error.ProtocolError:
                smHandler.releaseStateInformation(securityStateReference)
                raise error.StatusInformation(
                    errorIndication=errind.dataMismatch)

            # 7.2.10b
            sendPduHandle = cachedReqParams['sendPduHandle']

        else:
            sendPduHandle = None

        debug.logger & debug.FLAG_MP and debug.logger(
            'prepareDataElements: using sendPduHandle %s for msgID '
            '%s' % (sendPduHandle, msgID))

        # 7.2.11
        if pduType in rfc3411.INTERNAL_CLASS_PDUS:
            # 7.2.11a
            varBinds = pMod.apiPDU.getVarBinds(pdu)

            if varBinds:
                errorIndication = _snmpErrors.get(
                    varBinds[0][0],
                    errind.ReportPduReceived(varBinds[0][0].prettyPrint()))

                statusInformation = error.StatusInformation(
                    errorIndication=errorIndication,
                    oid=varBinds[0][0],
                    val=varBinds[0][1],
                    sendPduHandle=sendPduHandle)

            else:
                statusInformation = error.StatusInformation(
                    sendPduHandle=sendPduHandle)

            # 7.2.11b (incomplete implementation)

            snmpEngine.observer.storeExecutionContext(
                snmpEngine, 'rfc3412.prepareDataElements:internal',
                dict(transportDomain=transportDomain,
                     transportAddress=transportAddress,
                     securityModel=securityModel,
                     securityName=securityName,
                     securityLevel=securityLevel,
                     contextEngineId=contextEngineId,
                     contextName=contextName,
                     securityEngineId=securityEngineId,
                     pdu=pdu))

            snmpEngine.observer.clearExecutionContext(
                snmpEngine, 'rfc3412.prepareDataElements:internal')

            # 7.2.11c
            smHandler.releaseStateInformation(securityStateReference)

            # 7.2.11d
            # no-op

            # 7.2.11e XXX may need to pass Reports up to app in some cases...
            raise statusInformation

        statusInformation = None  # no errors ahead

        # 7.2.12
        if pduType in rfc3411.RESPONSE_CLASS_PDUS:
            # 7.2.12a -> no-op

            # 7.2.12b
            # noinspection PyUnboundLocalVariable
            if (securityModel != cachedReqParams['securityModel']
                    or securityName != cachedReqParams['securityName']
                    or securityLevel != cachedReqParams['securityLevel']
                    or contextEngineId != cachedReqParams['contextEngineId']
                    or contextName != cachedReqParams['contextName']):

                smHandler.releaseStateInformation(securityStateReference)

                raise error.StatusInformation(
                    errorIndication=errind.dataMismatch)

            snmpEngine.observer.storeExecutionContext(
                snmpEngine, 'rfc3412.prepareDataElements:response',
                dict(transportDomain=transportDomain,
                     transportAddress=transportAddress,
                     securityModel=securityModel,
                     securityName=securityName,
                     securityLevel=securityLevel,
                     contextEngineId=contextEngineId,
                     contextName=contextName,
                     securityEngineId=securityEngineId,
                     pdu=pdu))

            snmpEngine.observer.clearExecutionContext(
                snmpEngine, 'rfc3412.prepareDataElements:response')

            # 7.2.12c
            smHandler.releaseStateInformation(securityStateReference)
            stateReference = None

            # 7.2.12d
            return (messageProcessingModel, securityModel, securityName,
                    securityLevel, contextEngineId, contextName, pduVersion,
                    pdu, pduType, sendPduHandle, maxSizeResponseScopedPDU,
                    statusInformation, stateReference)

        # 7.2.13
        if pduType in rfc3411.CONFIRMED_CLASS_PDUS:
            # 7.2.13a
            if securityEngineId != snmpEngineID:
                smHandler.releaseStateInformation(securityStateReference)
                raise error.StatusInformation(
                    errorIndication=errind.engineIDMismatch)

            # 7.2.13b
            stateReference = self._cache.newStateReference()

            self._cache.pushByStateRef(
                stateReference,
                msgVersion=messageProcessingModel,
                msgID=msgID,
                contextEngineId=contextEngineId,
                contextName=contextName,
                securityModel=securityModel,
                securityName=securityName,
                securityLevel=securityLevel,
                securityStateReference=securityStateReference,
                reportableFlag=reportableFlag,
                msgMaxSize=maxMessageSize,
                maxSizeResponseScopedPDU=maxSizeResponseScopedPDU,
                transportDomain=transportDomain,
                transportAddress=transportAddress)

            debug.logger & debug.FLAG_MP and debug.logger(
                'prepareDataElements: new stateReference %s' % stateReference)

            snmpEngine.observer.storeExecutionContext(
                snmpEngine, 'rfc3412.prepareDataElements:confirmed',
                dict(transportDomain=transportDomain,
                     transportAddress=transportAddress,
                     securityModel=securityModel,
                     securityName=securityName,
                     securityLevel=securityLevel,
                     contextEngineId=contextEngineId,
                     contextName=contextName,
                     securityEngineId=securityEngineId,
                     pdu=pdu))

            snmpEngine.observer.clearExecutionContext(
                snmpEngine, 'rfc3412.prepareDataElements:confirmed')

            # 7.2.13c
            return (messageProcessingModel, securityModel, securityName,
                    securityLevel, contextEngineId, contextName, pduVersion,
                    pdu, pduType, sendPduHandle, maxSizeResponseScopedPDU,
                    statusInformation, stateReference)

        # 7.2.14
        if pduType in rfc3411.UNCONFIRMED_CLASS_PDUS:

            # Pass new stateReference to let app browse request details
            stateReference = self._cache.newStateReference()

            snmpEngine.observer.storeExecutionContext(
                snmpEngine, 'rfc3412.prepareDataElements:unconfirmed',
                dict(transportDomain=transportDomain,
                     transportAddress=transportAddress,
                     securityModel=securityModel,
                     securityName=securityName,
                     securityLevel=securityLevel,
                     contextEngineId=contextEngineId,
                     contextName=contextName,
                     securityEngineId=securityEngineId,
                     pdu=pdu))

            snmpEngine.observer.clearExecutionContext(
                snmpEngine, 'rfc3412.prepareDataElements:unconfirmed')

            # This is not specified explicitly in RFC
            smHandler.releaseStateInformation(securityStateReference)

            return (messageProcessingModel, securityModel, securityName,
                    securityLevel, contextEngineId, contextName, pduVersion,
                    pdu, pduType, sendPduHandle, maxSizeResponseScopedPDU,
                    statusInformation, stateReference)

        smHandler.releaseStateInformation(securityStateReference)

        raise error.StatusInformation(
            errorIndication=errind.unsupportedPDUtype)
コード例 #12
0
    def prepareOutgoingMessage(self, snmpEngine, transportDomain,
                               transportAddress, messageProcessingModel,
                               securityModel, securityName, securityLevel,
                               contextEngineId, contextName, pduVersion, pdu,
                               expectResponse, sendPduHandle):

        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        snmpEngineID, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB',
                                                 'snmpEngineID')
        snmpEngineID = snmpEngineID.syntax

        # 7.1.1b
        msgID = self._cache.newMsgID()

        debug.logger & debug.FLAG_MP and debug.logger(
            'prepareOutgoingMessage: new msgID %s' % msgID)

        k = transportDomain, transportAddress
        if k in self._engineIdCache:
            peerSnmpEngineData = self._engineIdCache[k]

        else:
            peerSnmpEngineData = None

        debug.logger & debug.FLAG_MP and debug.logger(
            'prepareOutgoingMessage: peer SNMP engine data %s '
            'for transport %s, address '
            '%s' % (peerSnmpEngineData, transportDomain, transportAddress))

        # 7.1.4
        if contextEngineId is None:
            if peerSnmpEngineData is None:
                contextEngineId = snmpEngineID

            else:
                contextEngineId = peerSnmpEngineData['contextEngineId']
                # Defaulting contextEngineID to securityEngineId should
                # probably be done on Agent side (see 7.1.3.d.2,) so this
                # is a sort of workaround.
                if not contextEngineId:
                    contextEngineId = peerSnmpEngineData['securityEngineId']
        # 7.1.5
        if not contextName:
            contextName = self._emptyStr

        debug.logger & debug.FLAG_MP and debug.logger(
            'prepareOutgoingMessage: 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.MESSAGE_PROCESSING_MODEL_ID,
                                   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, = 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.CONFIRMED_CLASS_PDUS:
            msgFlags |= 0x04

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

        # 7.1.7e
        # XXX need to coerce MIB value as it has incompatible constraints set
        headerData.setComponentByPosition(3, int(securityModel))

        debug.logger & debug.FLAG_MP and debug.logger(
            'prepareOutgoingMessage: %s' % (msg.prettyPrint(), ))

        if securityModel in snmpEngine.securityModels:
            smHandler = snmpEngine.securityModels[securityModel]

        else:
            raise error.StatusInformation(
                errorIndication=errind.unsupportedSecurityModel)

        # 7.1.9.a
        if pdu.tagSet in rfc3411.UNCONFIRMED_CLASS_PDUS:
            securityEngineId = snmpEngineID

        else:
            if peerSnmpEngineData is None:
                # Force engineID discovery (rfc3414, 4)
                securityEngineId = securityName = self._emptyStr
                securityLevel = 1

                # Clear possible auth&priv flags
                headerData.setComponentByPosition(2,
                                                  self._msgFlags[msgFlags
                                                                 & 0xfc],
                                                  verifyConstraints=False,
                                                  matchTags=False,
                                                  matchConstraints=False)

                # XXX
                scopedPDU = self._scopedPDU
                scopedPDU.setComponentByPosition(0,
                                                 self._emptyStr,
                                                 verifyConstraints=False,
                                                 matchTags=False,
                                                 matchConstraints=False)
                scopedPDU.setComponentByPosition(1, contextName)
                scopedPDU.setComponentByPosition(2)

                # Use dead-empty PDU for engine-discovery report
                emptyPdu = pdu.clone()
                pMod.apiPDU.setDefaults(emptyPdu)

                scopedPDU.getComponentByPosition(2).setComponentByType(
                    emptyPdu.tagSet,
                    emptyPdu,
                    verifyConstraints=False,
                    matchTags=False,
                    matchConstraints=False)

                debug.logger & debug.FLAG_MP and debug.logger(
                    'prepareOutgoingMessage: force engineID discovery')

            else:
                securityEngineId = peerSnmpEngineData['securityEngineId']

        debug.logger & debug.FLAG_MP and debug.logger(
            'prepareOutgoingMessage: securityModel %r, securityEngineId %r, '
            'securityName %r, securityLevel '
            '%r' %
            (securityModel, securityEngineId, securityName, securityLevel))

        # 7.1.9.b
        securityParameters, wholeMsg = smHandler.generateRequestMsg(
            snmpEngine, self.MESSAGE_PROCESSING_MODEL_ID, msg,
            snmpEngineMaxMessageSize.syntax, securityModel, securityEngineId,
            securityName, securityLevel, scopedPDU)

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

        # 7.1.9.c
        if pdu.tagSet in rfc3411.CONFIRMED_CLASS_PDUS:
            # XXX rfc bug? why stateReference should be created?
            self._cache.pushByMsgId(msgID,
                                    sendPduHandle=sendPduHandle,
                                    msgID=msgID,
                                    snmpEngineID=snmpEngineID,
                                    securityModel=securityModel,
                                    securityName=securityName,
                                    securityLevel=securityLevel,
                                    contextEngineId=contextEngineId,
                                    contextName=contextName,
                                    transportDomain=transportDomain,
                                    transportAddress=transportAddress)

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

        return transportDomain, transportAddress, wholeMsg
コード例 #13
0
ファイル: noauth.py プロジェクト: zxx1819/pysnmp
 def authenticateIncomingMsg(self, authKey, authParameters, wholeMsg):
     raise error.StatusInformation(errorIndication=errind.noAuthentication)
コード例 #14
0
ファイル: noauth.py プロジェクト: zxx1819/pysnmp
 def authenticateOutgoingMsg(self, authKey, wholeMsg):
     raise error.StatusInformation(errorIndication=errind.noAuthentication)
コード例 #15
0
ファイル: rfc2576.py プロジェクト: rishie/testerman
    def prepareOutgoingMessage(
        self,
        snmpEngine,
        transportDomain,
        transportAddress,
        messageProcessingModel,
        securityModel,
        securityName,
        securityLevel,
        contextEngineId,
        contextName,
        pduVersion,
        pdu,
        expectResponse,
        sendPduHandle
        ):
        snmpEngineID, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
        snmpEngineID = snmpEngineID.syntax
        
        # rfc3412: 7.1.1b
        if rfc3411.confirmedClassPDUs.has_key(pdu.tagSet):
            pdu.setComponentByPosition(1)
            msgID = pdu.getComponentByPosition(0)
            
        # rfc3412: 7.1.4
        # Since there's no SNMP engine identification in v1/2c,
        # set destination contextEngineId to ours
        if not contextEngineId:
            contextEngineId = snmpEngineID

        # rfc3412: 7.1.5
        if not contextName:
            contextName = ''

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

        # rfc3412: 7.1.6
        scopedPDU = ( contextEngineId, contextName, pdu )

        msg = self._snmpMsgSpec.clone()
        msg.setComponentByPosition(0, self.messageProcessingModelID)
        msg.setComponentByPosition(2)
        msg.getComponentByPosition(2).setComponentByType(pdu.tagSet, pdu)

        # rfc3412: 7.1.7
        globalData = ( msg, )

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

        # rfc3412: 7.1.9.a & rfc2576: 5.2.1 --> no-op

        snmpEngineMaxMessageSize, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineMaxMessageSize')
            
        # rfc3412: 7.1.9.b
        ( securityParameters,
          wholeMsg ) = smHandler.generateRequestMsg(
            snmpEngine,
            self.messageProcessingModelID,
            globalData,
            snmpEngineMaxMessageSize.syntax,
            securityModel,
            snmpEngineID,
            securityName,
            securityLevel,
            scopedPDU
            )

        # rfc3412: 7.1.9.c
        if rfc3411.confirmedClassPDUs.has_key(pdu.tagSet):
            # XXX rfc bug? why stateReference should be created?
            self._cachePushByMsgId(
                long(msgID),
                sendPduHandle=sendPduHandle,
                msgID=msgID,
                snmpEngineID=snmpEngineID,
                securityModel=securityModel,
                securityName=securityName,
                securityLevel=securityLevel,
                contextEngineId=contextEngineId,
                contextName=contextName,
                transportDomain=transportDomain,
                transportAddress=transportAddress
                )

        return ( transportDomain, transportAddress, wholeMsg )
コード例 #16
0
ファイル: rfc3412.py プロジェクト: rishie/testerman
    def prepareDataElements(self, snmpEngine, transportDomain,
                            transportAddress, wholeMsg):
        # 7.2.2
        try:
            msg, restOfwholeMsg = decoder.decode(wholeMsg,
                                                 asn1Spec=self._snmpMsgSpec)
        except PyAsn1Error:
            snmpInASNParseErrs, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                '__SNMPv2-MIB', 'snmpInASNParseErrs')
            snmpInASNParseErrs.syntax = snmpInASNParseErrs.syntax + 1
            raise error.StatusInformation(errorIndication='parseError')

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

        # 7.2.3
        headerData = msg.getComponentByPosition(1)
        msgVersion = messageProcessingModel = msg.getComponentByPosition(0)
        msgID = headerData.getComponentByPosition(0)
        msgFlags = ord(str(headerData.getComponentByPosition(2)))
        maxMessageSize = headerData.getComponentByPosition(1)
        securityModel = headerData.getComponentByPosition(3)
        securityParameters = msg.getComponentByPosition(2)

        debug.logger & debug.flagMP and debug.logger(
            'prepareDataElements: msg data msgVersion %s msgID %s securityModel %s'
            % (msgVersion, msgID, securityModel))

        # 7.2.4
        if not snmpEngine.securityModels.has_key(securityModel):
            snmpUnknownSecurityModels, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                '__SNMPv2-MIB', 'snmpUnknownSecurityModels')
            snmpUnknownSecurityModels.syntax = snmpUnknownSecurityModels.syntax + 1
            raise error.StatusInformation(
                errorIndication='unsupportedSecurityModel')

        # 7.2.5
        if msgFlags & 0x03 == 0x00:
            securityLevel = 1
        elif (msgFlags & 0x03) == 0x01:
            securityLevel = 2
        elif (msgFlags & 0x03) == 0x03:
            securityLevel = 3
        else:
            snmpInvalidMsgs = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                '__SNMPv2-MIB', 'snmpInvalidMsgs')
            snmpInvalidMsgs.syntax = snmpInvalidMsgs.syntax + 1
            raise error.StatusInformation(errorIndication='invalidMsg')

        if msgFlags & 0x04:
            reportableFlag = 1
        else:
            reportableFlag = 0

        # 7.2.6
        smHandler = snmpEngine.securityModels[securityModel]
        try:
            (securityEngineID, securityName, scopedPDU,
             maxSizeResponseScopedPDU,
             securityStateReference) = smHandler.processIncomingMsg(
                 snmpEngine, messageProcessingModel, maxMessageSize,
                 securityParameters, securityModel, securityLevel, wholeMsg,
                 msg)
            debug.logger & debug.flagMP and debug.logger(
                'prepareDataElements: SM succeeded')
        except error.StatusInformation, statusInformation:
            debug.logger & debug.flagMP and debug.logger(
                'prepareDataElements: SM failed, statusInformation %s' %
                statusInformation)
            if statusInformation.has_key('errorIndication'):
                # 7.2.6a
                if statusInformation.has_key('oid'):
                    # 7.2.6a1
                    securityStateReference = statusInformation[
                        'securityStateReference']
                    contextEngineId = statusInformation['contextEngineId']
                    contextName = statusInformation['contextName']
                    scopedPDU = statusInformation.get('scopedPDU')
                    if scopedPDU is not None:
                        pdu = scopedPDU.getComponentByPosition(
                            2).getComponent()
                    else:
                        pdu = None
                    maxSizeResponseScopedPDU = statusInformation[
                        'maxSizeResponseScopedPDU']
                    securityName = None  # XXX secmod cache used

                    # 7.2.6a2
                    stateReference = self._newStateReference()
                    self._cachePushByStateRef(
                        stateReference,
                        msgVersion=messageProcessingModel,
                        msgID=msgID,
                        contextEngineId=contextEngineId,
                        contextName=contextName,
                        securityModel=securityModel,
                        securityName=securityName,
                        securityLevel=securityLevel,
                        securityStateReference=securityStateReference,
                        reportableFlag=reportableFlag,
                        msgMaxSize=maxMessageSize,
                        maxSizeResponseScopedPDU=maxSizeResponseScopedPDU,
                        transportDomain=transportDomain,
                        transportAddress=transportAddress)

                    # 7.2.6a3
                    try:
                        snmpEngine.msgAndPduDsp.returnResponsePdu(
                            snmpEngine, 3, securityModel, securityName,
                            securityLevel, contextEngineId, contextName, 1,
                            pdu, maxSizeResponseScopedPDU, stateReference,
                            statusInformation)
                    except error.StatusInformation:
                        pass

                    debug.logger & debug.flagMP and debug.logger(
                        'prepareDataElements: error reported')
            # 7.2.6b
            raise statusInformation
コード例 #17
0
ファイル: rfc2576.py プロジェクト: rishie/testerman
    def prepareDataElements(
        self,
        snmpEngine,
        transportDomain,
        transportAddress,
        wholeMsg
        ):
        # rfc3412: 7.2.2 
        try:
            msg, restOfwholeMsg = decoder.decode(
                wholeMsg, asn1Spec=self._snmpMsgSpec
                )
        except PyAsn1Error:
            snmpInASNParseErrs, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpInASNParseErrs')
            snmpInASNParseErrs.syntax = snmpInASNParseErrs.syntax + 1
            raise error.StatusInformation(
                errorIndication = 'parseError'
                )

        debug.logger & debug.flagMP and debug.logger('prepareDataElements: msg decoded')

        # rfc3412: 7.2.3
        msgVersion = messageProcessingModel = msg.getComponentByPosition(0)
        pdu = msg.getComponentByPosition(2).getComponent()
        # (wild hack: use PDU reqID at MsgID)
        msgID = pdu.getComponentByPosition(0)

        # rfc2576: 5.2.1
        snmpEngineMaxMessageSize, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineMaxMessageSize')
        securityParameters = (
            msg.getComponentByPosition(1),
            (transportDomain, transportAddress),
            ('0.0.0.0', 0)  # XXX
            )
        messageProcessingModel = int(msg.getComponentByPosition(0))
        securityModel = messageProcessingModel + 1
        securityLevel = 1
    
        # rfc3412: 7.2.4 -- 7.2.5 -> noop

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

        # rfc3412: 7.2.6
        ( securityEngineID,
          securityName,
          scopedPDU,
          maxSizeResponseScopedPDU,
          securityStateReference ) = smHandler.processIncomingMsg(
            snmpEngine,
            messageProcessingModel,
            snmpEngineMaxMessageSize.syntax,
            securityParameters,
            securityModel,
            securityLevel,
            wholeMsg,
            msg
            )

        debug.logger & debug.flagMP and debug.logger('prepareDataElements: SM returned securityEngineID %s securityName %s' % (securityEngineID, securityName))

        # rfc3412: 7.2.6a --> noop

        # rfc3412: 7.2.7
        contextEngineId, contextName, pdu = scopedPDU

        # rfc2576: 5.2.1
        pduVersion = msgVersion
        pduType = pdu.tagSet
        
        # XXX use cache
        # set stateref to null as in v3 model
        stateReference = securityStateReference

        # rfc3412: 7.2.8, 7.2.9 -> noop

        # rfc3412: 7.2.10
        if rfc3411.responseClassPDUs.has_key(pduType):
            # 7.2.10a
            try:
                cachedReqParams = self._cachePopByMsgId(long(msgID))
            except error.ProtocolError:
                smHandler.releaseStateInformation(securityStateReference)
                raise error.StatusInformation(
                    errorIndication = 'dataMismatch'
                    )

            # 7.2.10b            
            sendPduHandle = cachedReqParams['sendPduHandle']
        else:
            sendPduHandle = None

        statusInformation = None

        # rfc3412: 7.2.11 -> noop

        # rfc3412: 7.2.12
        if rfc3411.responseClassPDUs.has_key(pduType):
            # rfc3412: 7.2.12a -> noop
            # rfc3412: 7.2.12b
            if securityModel != cachedReqParams['securityModel'] or \
               securityName != cachedReqParams['securityName'] or \
               securityLevel != cachedReqParams['securityLevel'] or \
               contextEngineId != cachedReqParams['contextEngineId'] or \
               contextName != cachedReqParams['contextName']:
                smHandler.releaseStateInformation(securityStateReference)
                raise error.StatusInformation(
                    errorIndication = 'dataMismatch'
                    )
            
            # rfc3412: 7.2.12c
            smHandler.releaseStateInformation(securityStateReference)

            # rfc3412: 7.2.12d
            return ( messageProcessingModel,
                     securityModel,
                     securityName,
                     securityLevel,
                     contextEngineId,
                     contextName,
                     pduVersion,
                     pdu,
                     pduType,
                     sendPduHandle,
                     maxSizeResponseScopedPDU,
                     statusInformation,
                     stateReference )

        # rfc3412: 7.2.13
        if rfc3411.confirmedClassPDUs.has_key(pduType):
            # rfc3412: 7.2.13a
            snmpEngineID, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
            if securityEngineID != snmpEngineID.syntax:
                smHandler.releaseStateInformation(securityStateReference)
                raise error.StatusInformation(
                    errorIndication = 'engineIDMispatch'
                    )

            # rfc3412: 7.2.13b
            stateReference = self._newStateReference()
            self._cachePushByStateRef(
                stateReference,
                msgVersion=messageProcessingModel,
                msgID=msgID,
                contextEngineId=contextEngineId,
                contextName=contextName,
                securityModel=securityModel,
                securityName=securityName,
                securityLevel=securityLevel,
                securityStateReference=securityStateReference,
                msgMaxSize=snmpEngineMaxMessageSize.syntax,
                maxSizeResponseScopedPDU=maxSizeResponseScopedPDU,
                transportDomain=transportDomain,
                transportAddress=transportAddress
                )

            debug.logger & debug.flagMP and debug.logger('prepareDataElements: cached by new stateReference %s' % stateReference)
                
            # rfc3412: 7.2.13c
            return ( messageProcessingModel,
                     securityModel,
                     securityName,
                     securityLevel,
                     contextEngineId,
                     contextName,
                     pduVersion,
                     pdu,
                     pduType,
                     sendPduHandle,
                     maxSizeResponseScopedPDU,
                     statusInformation,
                     stateReference )

        # rfc3412: 7.2.14
        if rfc3411.unconfirmedClassPDUs.has_key(pduType):
            # This is not specified explicitly in RFC
            smHandler.releaseStateInformation(securityStateReference)
            return ( messageProcessingModel,
                     securityModel,
                     securityName,
                     securityLevel,
                     contextEngineId,
                     contextName,
                     pduVersion,
                     pdu,
                     pduType,
                     sendPduHandle,
                     maxSizeResponseScopedPDU,
                     statusInformation,
                     stateReference )

        smHandler.releaseStateInformation(securityStateReference)
        raise error.StatusInformation(
            errorIndication = 'unsupportedPDUtype'
            )
コード例 #18
0
ファイル: rfc3412.py プロジェクト: rishie/testerman
class SnmpV3MessageProcessingModel(AbstractMessageProcessingModel):
    messageProcessingModelID = 3  # SNMPv3
    _snmpMsgSpec = SNMPv3Message()

    def __init__(self):
        AbstractMessageProcessingModel.__init__(self)
        self.__engineIDs = {}
        self.__engineIDsExpQueue = {}
        self.__expirationTimer = 0L

    # 7.1.1a
    def prepareOutgoingMessage(self, snmpEngine, transportDomain,
                               transportAddress, messageProcessingModel,
                               securityModel, securityName, securityLevel,
                               contextEngineId, contextName, pduVersion, pdu,
                               expectResponse, sendPduHandle):
        snmpEngineID, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
        snmpEngineID = snmpEngineID.syntax

        # 7.1.1b
        msgID = self._newMsgID()

        debug.logger & debug.flagMP and debug.logger(
            'prepareOutgoingMessage: new msgID %s' % msgID)

        peerSnmpEngineData = self.__engineIDs.get(
            (transportDomain, transportAddress))

        debug.logger & debug.flagMP and debug.logger(
            'prepareOutgoingMessage: peer SNMP engine data %s for transport %s, address %s'
            % (peerSnmpEngineData, transportDomain, transportAddress))

        # 7.1.4
        if contextEngineId is None:
            if peerSnmpEngineData is None:
                contextEngineId = snmpEngineID
            else:
                contextEngineId = peerSnmpEngineData['contextEngineId']
                # Defaulting contextEngineID to securityEngineID should
                # probably be done on Agent side (see 7.1.3.d.2,) so this
                # is a sort of workaround.
                if not contextEngineId:
                    contextEngineId = peerSnmpEngineData['securityEngineID']
        # 7.1.5
        if not contextName:
            contextName = ''

        debug.logger & debug.flagMP and debug.logger(
            'prepareOutgoingMessage: 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):
            msgFlags = msgFlags | 0x04

        headerData.setComponentByPosition(2, chr(msgFlags))

        # 7.1.7e
        # XXX need to coerce MIB value as it has incompatible constraints set
        headerData.setComponentByPosition(3, int(securityModel))

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

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

        # 7.1.9.a
        if rfc3411.unconfirmedClassPDUs.has_key(pdu.tagSet):
            securityEngineID = snmpEngineID
        else:
            if peerSnmpEngineData is None:
                # Force engineID discovery (rfc3414, 4)
                securityEngineID = securityName = ''
                securityLevel = 1
                # Clear possible auth&priv flags
                headerData.setComponentByPosition(2, chr(msgFlags & 0xfc))
                # XXX
                scopedPDU = ScopedPDU()
                scopedPDU.setComponentByPosition(0, '')
                scopedPDU.setComponentByPosition(1, '')
                scopedPDU.setComponentByPosition(2)

                # Use dead-empty PDU for engine-discovery report
                emptyPdu = pdu.clone()
                pMod.apiPDU.setDefaults(emptyPdu)

                scopedPDU.getComponentByPosition(2).setComponentByType(
                    emptyPdu.tagSet, emptyPdu)
                debug.logger & debug.flagMP and debug.logger(
                    'prepareOutgoingMessage: force engineID discovery')
            else:
                securityEngineID = peerSnmpEngineData['securityEngineID']

        debug.logger & debug.flagMP and debug.logger(
            'prepareOutgoingMessage: securityEngineID %s' % securityEngineID)

        # 7.1.9.b
        (securityParameters, wholeMsg) = smHandler.generateRequestMsg(
            snmpEngine, self.messageProcessingModelID, msg,
            snmpEngineMaxMessageSize.syntax, securityModel, securityEngineID,
            securityName, securityLevel, scopedPDU)

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

        # 7.1.9.c
        if rfc3411.confirmedClassPDUs.has_key(pdu.tagSet):
            # XXX rfc bug? why stateReference should be created?
            self._cachePushByMsgId(msgID,
                                   sendPduHandle=sendPduHandle,
                                   msgID=msgID,
                                   snmpEngineID=snmpEngineID,
                                   securityModel=securityModel,
                                   securityName=securityName,
                                   securityLevel=securityLevel,
                                   contextEngineId=contextEngineId,
                                   contextName=contextName,
                                   transportDomain=transportDomain,
                                   transportAddress=transportAddress)

        return (transportDomain, transportAddress, wholeMsg)

    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, 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)
コード例 #19
0
ファイル: rfc3412.py プロジェクト: rsmetana/Python
    def sendPdu(self,
                snmpEngine,
                transportDomain,
                transportAddress,
                messageProcessingModel,
                securityModel,
                securityName,
                securityLevel,
                contextEngineId,
                contextName,
                pduVersion,
                PDU,
                expectResponse,
                timeout=0,
                cbFun=None,
                cbCtx=None):
        """PDU dispatcher -- prepare and serialize a request or notification"""
        # 4.1.1.2
        k = int(messageProcessingModel)
        if k in snmpEngine.messageProcessingSubsystems:
            mpHandler = snmpEngine.messageProcessingSubsystems[k]
        else:
            raise error.StatusInformation(
                errorIndication=errind.unsupportedMsgProcessingModel)

        debug.logger & debug.flagDsp and debug.logger(
            'sendPdu: securityName %s, PDU\n%s' %
            (securityName, PDU.prettyPrint()))

        # 4.1.1.3
        sendPduHandle = self.__sendPduHandle()
        if expectResponse:
            self.__cache.add(sendPduHandle,
                             messageProcessingModel=messageProcessingModel,
                             sendPduHandle=sendPduHandle,
                             timeout=timeout +
                             snmpEngine.transportDispatcher.getTimerTicks(),
                             cbFun=cbFun,
                             cbCtx=cbCtx)

            debug.logger & debug.flagDsp and debug.logger(
                'sendPdu: current time %d ticks, one tick is %s seconds' %
                (snmpEngine.transportDispatcher.getTimerTicks(),
                 snmpEngine.transportDispatcher.getTimerResolution()))

        debug.logger & debug.flagDsp and debug.logger(
            'sendPdu: new sendPduHandle %s, timeout %s ticks, cbFun %s' %
            (sendPduHandle, timeout, cbFun))

        origTransportDomain = transportDomain
        origTransportAddress = transportAddress

        # 4.1.1.4 & 4.1.1.5
        try:
            (transportDomain, transportAddress,
             outgoingMessage) = mpHandler.prepareOutgoingMessage(
                 snmpEngine, origTransportDomain, origTransportAddress,
                 messageProcessingModel, securityModel, securityName,
                 securityLevel, contextEngineId, contextName, pduVersion, PDU,
                 expectResponse, sendPduHandle)

            debug.logger & debug.flagDsp and debug.logger(
                'sendPdu: MP succeeded')
        except PySnmpError:
            if expectResponse:
                self.__cache.pop(sendPduHandle)
                self.releaseStateInformation(snmpEngine, sendPduHandle,
                                             messageProcessingModel)
            raise

        # 4.1.1.6
        if snmpEngine.transportDispatcher is None:
            if expectResponse:
                self.__cache.pop(sendPduHandle)

            raise error.PySnmpError('Transport dispatcher not set')

        snmpEngine.observer.storeExecutionContext(
            snmpEngine, 'rfc3412.sendPdu',
            dict(transportDomain=transportDomain,
                 transportAddress=transportAddress,
                 outgoingMessage=outgoingMessage,
                 messageProcessingModel=messageProcessingModel,
                 securityModel=securityModel,
                 securityName=securityName,
                 securityLevel=securityLevel,
                 contextEngineId=contextEngineId,
                 contextName=contextName,
                 pdu=PDU))

        try:
            snmpEngine.transportDispatcher.sendMessage(outgoingMessage,
                                                       transportDomain,
                                                       transportAddress)
        except PySnmpError:
            if expectResponse:
                self.__cache.pop(sendPduHandle)
            raise

        snmpEngine.observer.clearExecutionContext(snmpEngine,
                                                  'rfc3412.sendPdu')

        # Update cache with orignal req params (used for retrying)
        if expectResponse:
            self.__cache.update(sendPduHandle,
                                transportDomain=origTransportDomain,
                                transportAddress=origTransportAddress,
                                securityModel=securityModel,
                                securityName=securityName,
                                securityLevel=securityLevel,
                                contextEngineId=contextEngineId,
                                contextName=contextName,
                                pduVersion=pduVersion,
                                PDU=PDU)

        return sendPduHandle
コード例 #20
0
ファイル: rfc3412.py プロジェクト: rishie/testerman
    def prepareOutgoingMessage(self, snmpEngine, transportDomain,
                               transportAddress, messageProcessingModel,
                               securityModel, securityName, securityLevel,
                               contextEngineId, contextName, pduVersion, pdu,
                               expectResponse, sendPduHandle):
        snmpEngineID, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
        snmpEngineID = snmpEngineID.syntax

        # 7.1.1b
        msgID = self._newMsgID()

        debug.logger & debug.flagMP and debug.logger(
            'prepareOutgoingMessage: new msgID %s' % msgID)

        peerSnmpEngineData = self.__engineIDs.get(
            (transportDomain, transportAddress))

        debug.logger & debug.flagMP and debug.logger(
            'prepareOutgoingMessage: peer SNMP engine data %s for transport %s, address %s'
            % (peerSnmpEngineData, transportDomain, transportAddress))

        # 7.1.4
        if contextEngineId is None:
            if peerSnmpEngineData is None:
                contextEngineId = snmpEngineID
            else:
                contextEngineId = peerSnmpEngineData['contextEngineId']
                # Defaulting contextEngineID to securityEngineID should
                # probably be done on Agent side (see 7.1.3.d.2,) so this
                # is a sort of workaround.
                if not contextEngineId:
                    contextEngineId = peerSnmpEngineData['securityEngineID']
        # 7.1.5
        if not contextName:
            contextName = ''

        debug.logger & debug.flagMP and debug.logger(
            'prepareOutgoingMessage: 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):
            msgFlags = msgFlags | 0x04

        headerData.setComponentByPosition(2, chr(msgFlags))

        # 7.1.7e
        # XXX need to coerce MIB value as it has incompatible constraints set
        headerData.setComponentByPosition(3, int(securityModel))

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

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

        # 7.1.9.a
        if rfc3411.unconfirmedClassPDUs.has_key(pdu.tagSet):
            securityEngineID = snmpEngineID
        else:
            if peerSnmpEngineData is None:
                # Force engineID discovery (rfc3414, 4)
                securityEngineID = securityName = ''
                securityLevel = 1
                # Clear possible auth&priv flags
                headerData.setComponentByPosition(2, chr(msgFlags & 0xfc))
                # XXX
                scopedPDU = ScopedPDU()
                scopedPDU.setComponentByPosition(0, '')
                scopedPDU.setComponentByPosition(1, '')
                scopedPDU.setComponentByPosition(2)

                # Use dead-empty PDU for engine-discovery report
                emptyPdu = pdu.clone()
                pMod.apiPDU.setDefaults(emptyPdu)

                scopedPDU.getComponentByPosition(2).setComponentByType(
                    emptyPdu.tagSet, emptyPdu)
                debug.logger & debug.flagMP and debug.logger(
                    'prepareOutgoingMessage: force engineID discovery')
            else:
                securityEngineID = peerSnmpEngineData['securityEngineID']

        debug.logger & debug.flagMP and debug.logger(
            'prepareOutgoingMessage: securityEngineID %s' % securityEngineID)

        # 7.1.9.b
        (securityParameters, wholeMsg) = smHandler.generateRequestMsg(
            snmpEngine, self.messageProcessingModelID, msg,
            snmpEngineMaxMessageSize.syntax, securityModel, securityEngineID,
            securityName, securityLevel, scopedPDU)

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

        # 7.1.9.c
        if rfc3411.confirmedClassPDUs.has_key(pdu.tagSet):
            # XXX rfc bug? why stateReference should be created?
            self._cachePushByMsgId(msgID,
                                   sendPduHandle=sendPduHandle,
                                   msgID=msgID,
                                   snmpEngineID=snmpEngineID,
                                   securityModel=securityModel,
                                   securityName=securityName,
                                   securityLevel=securityLevel,
                                   contextEngineId=contextEngineId,
                                   contextName=contextName,
                                   transportDomain=transportDomain,
                                   transportAddress=transportAddress)

        return (transportDomain, transportAddress, wholeMsg)
コード例 #21
0
    def isAccessAllowed(self, snmpEngine, securityModel, securityName,
                        securityLevel, 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))

        # 3.2.1
        vacmContextEntry, = mibInstrumController.mibBuilder.importSymbols(
            'SNMP-VIEW-BASED-ACM-MIB', 'vacmContextEntry')
        tblIdx = vacmContextEntry.getInstIdFromIndices(contextName)
        try:
            vacmContextName = vacmContextEntry.getNode(vacmContextEntry.name +
                                                       (1, ) + tblIdx).syntax
        except NoSuchInstanceError:
            raise error.StatusInformation(errorIndication=errind.noSuchContext)

        # 3.2.2
        vacmSecurityToGroupEntry, = mibInstrumController.mibBuilder.importSymbols(
            'SNMP-VIEW-BASED-ACM-MIB', 'vacmSecurityToGroupEntry')
        tblIdx = vacmSecurityToGroupEntry.getInstIdFromIndices(
            securityModel, securityName)
        try:
            vacmGroupName = vacmSecurityToGroupEntry.getNode(
                vacmSecurityToGroupEntry.name + (3, ) + tblIdx).syntax
        except NoSuchInstanceError:
            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)

        try:
            viewName = vacmAccessEntry.getNode(entryIdx).syntax
        except NoSuchInstanceError:
            raise error.StatusInformation(errorIndication=errind.noAccessEntry)
        if not len(viewName):
            raise error.StatusInformation(errorIndication=errind.noSuchView)

        # XXX split onto object & instance ?

        # 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 1:
            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 = mask + [b & c for b in __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
            # 3.2.5c
            return error.StatusInformation(
                errorIndication=errind.accessAllowed)
コード例 #22
0
ファイル: rfc2576.py プロジェクト: zxx1819/pysnmp
    def _com2sec(self, snmpEngine, communityName, transportInformation):
        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        snmpTargetAddrTAddress, = mibBuilder.importSymbols(
            'SNMP-TARGET-MIB', 'snmpTargetAddrTAddress')

        if self._transportBranchId != snmpTargetAddrTAddress.branchVersionId:
            (SnmpTagValue, snmpTargetAddrTDomain,
             snmpTargetAddrTagList) = mibBuilder.importSymbols(
                 'SNMP-TARGET-MIB', 'SnmpTagValue', 'snmpTargetAddrTDomain',
                 'snmpTargetAddrTagList')

            self._emptyTag = SnmpTagValue('')

            self._transportToTagMap = {}

            nextMibNode = snmpTargetAddrTagList

            while True:
                try:
                    nextMibNode = snmpTargetAddrTagList.getNextNode(
                        nextMibNode.name)

                except NoSuchInstanceError:
                    break

                instId = nextMibNode.name[len(snmpTargetAddrTagList.name):]

                targetAddrTDomain = snmpTargetAddrTDomain.getNode(
                    snmpTargetAddrTDomain.name + instId).syntax
                targetAddrTAddress = snmpTargetAddrTAddress.getNode(
                    snmpTargetAddrTAddress.name + instId).syntax

                targetAddrTDomain = tuple(targetAddrTDomain)

                if (targetAddrTDomain[:len(udp.SNMP_UDP_DOMAIN)] ==
                        udp.SNMP_UDP_DOMAIN):
                    SnmpUDPAddress, = mibBuilder.importSymbols(
                        'SNMPv2-TM', 'SnmpUDPAddress')
                    targetAddrTAddress = tuple(
                        SnmpUDPAddress(targetAddrTAddress))

                elif (targetAddrTDomain[:len(udp6.SNMP_UDP6_DOMAIN)] ==
                      udp6.SNMP_UDP6_DOMAIN):
                    TransportAddressIPv6, = mibBuilder.importSymbols(
                        'TRANSPORT-ADDRESS-MIB', 'TransportAddressIPv6')

                    targetAddrTAddress = tuple(
                        TransportAddressIPv6(targetAddrTAddress))

                targetAddr = targetAddrTDomain, targetAddrTAddress

                targetAddrTagList = snmpTargetAddrTagList.getNode(
                    snmpTargetAddrTagList.name + instId).syntax

                if targetAddr not in self._transportToTagMap:
                    self._transportToTagMap[targetAddr] = set()

                try:
                    if targetAddrTagList:
                        self._transportToTagMap[targetAddr].update([
                            SnmpTagValue(x)
                            for x in targetAddrTagList.asOctets().split()
                        ])

                    else:
                        self._transportToTagMap[targetAddr].add(self._emptyTag)

                except PyAsn1Error:
                    debug.logger & debug.FLAG_SM and debug.logger(
                        '_com2sec: table entries %r/%r hashing failed' %
                        (targetAddr, targetAddrTagList))
                    continue

            self._transportBranchId = snmpTargetAddrTAddress.branchVersionId

            debug.logger & debug.FLAG_SM and debug.logger(
                '_com2sec: built transport-to-tag map version %s: '
                '%s' % (self._transportBranchId, self._transportToTagMap))

        snmpTargetParamsSecurityName, = mibBuilder.importSymbols(
            'SNMP-TARGET-MIB', 'snmpTargetParamsSecurityName')

        if self._paramsBranchId != snmpTargetParamsSecurityName.branchVersionId:
            snmpTargetParamsSecurityModel, = mibBuilder.importSymbols(
                'SNMP-TARGET-MIB', 'snmpTargetParamsSecurityModel')

            self._nameToModelMap = {}

            nextMibNode = snmpTargetParamsSecurityName

            while True:
                try:
                    nextMibNode = snmpTargetParamsSecurityName.getNextNode(
                        nextMibNode.name)

                except NoSuchInstanceError:
                    break

                instId = nextMibNode.name[len(snmpTargetParamsSecurityName.name
                                              ):]

                mibNode = snmpTargetParamsSecurityModel.getNode(
                    snmpTargetParamsSecurityModel.name + instId)

                try:
                    if nextMibNode.syntax not in self._nameToModelMap:
                        self._nameToModelMap[nextMibNode.syntax] = set()

                    self._nameToModelMap[nextMibNode.syntax].add(
                        mibNode.syntax)

                except PyAsn1Error:
                    debug.logger & debug.FLAG_SM and debug.logger(
                        '_com2sec: table entries %r/%r hashing '
                        'failed' % (nextMibNode.syntax, mibNode.syntax))
                    continue

            self._paramsBranchId = snmpTargetParamsSecurityName.branchVersionId

            # invalidate next map as it include this one
            self._communityBranchId = -1

            debug.logger & debug.FLAG_SM and debug.logger(
                '_com2sec: built securityName to securityModel map, version '
                '%s: %s' % (self._paramsBranchId, self._nameToModelMap))

        snmpCommunityName, = mibBuilder.importSymbols('SNMP-COMMUNITY-MIB',
                                                      'snmpCommunityName')

        if self._communityBranchId != snmpCommunityName.branchVersionId:
            (snmpCommunitySecurityName, snmpCommunityContextEngineId,
             snmpCommunityContextName,
             snmpCommunityTransportTag) = mibBuilder.importSymbols(
                 'SNMP-COMMUNITY-MIB', 'snmpCommunitySecurityName',
                 'snmpCommunityContextEngineID', 'snmpCommunityContextName',
                 'snmpCommunityTransportTag')

            self._communityToTagMap = {}
            self._tagAndCommunityToSecurityMap = {}

            nextMibNode = snmpCommunityName

            while True:
                try:
                    nextMibNode = snmpCommunityName.getNextNode(
                        nextMibNode.name)

                except NoSuchInstanceError:
                    break

                instId = nextMibNode.name[len(snmpCommunityName.name):]

                securityName = snmpCommunitySecurityName.getNode(
                    snmpCommunitySecurityName.name + instId).syntax

                contextEngineId = snmpCommunityContextEngineId.getNode(
                    snmpCommunityContextEngineId.name + instId).syntax

                contextName = snmpCommunityContextName.getNode(
                    snmpCommunityContextName.name + instId).syntax

                transportTag = snmpCommunityTransportTag.getNode(
                    snmpCommunityTransportTag.name + instId).syntax

                _tagAndCommunity = transportTag, nextMibNode.syntax

                try:
                    if _tagAndCommunity not in self._tagAndCommunityToSecurityMap:
                        self._tagAndCommunityToSecurityMap[
                            _tagAndCommunity] = set()

                    self._tagAndCommunityToSecurityMap[_tagAndCommunity].add(
                        (securityName, contextEngineId, contextName))

                    if nextMibNode.syntax not in self._communityToTagMap:
                        self._communityToTagMap[nextMibNode.syntax] = set()

                    self._communityToTagMap[nextMibNode.syntax].add(
                        transportTag)

                except PyAsn1Error:
                    debug.logger & debug.FLAG_SM and debug.logger(
                        '_com2sec: table entries %r/%r hashing '
                        'failed' % (_tagAndCommunity, nextMibNode.syntax))
                    continue

            self._communityBranchId = snmpCommunityName.branchVersionId

            debug.logger & debug.FLAG_SM and debug.logger(
                '_com2sec: built communityName to tag map '
                '(securityModel %s), version %s: '
                '%s' % (self.SECURITY_MODEL_ID, self._communityBranchId,
                        self._communityToTagMap))

            debug.logger & debug.FLAG_SM and debug.logger(
                '_com2sec: built tag & community to securityName map '
                '(securityModel %s), version %s: '
                '%s' % (self.SECURITY_MODEL_ID, self._communityBranchId,
                        self._tagAndCommunityToSecurityMap))

        if communityName in self._communityToTagMap:
            if transportInformation in self._transportToTagMap:
                tags = self._transportToTagMap[
                    transportInformation].intersection(
                        self._communityToTagMap[communityName])

            elif self._emptyTag in self._communityToTagMap[communityName]:
                tags = [self._emptyTag]

            else:
                raise error.StatusInformation(
                    errorIndication=errind.unknownCommunityName)

            candidateSecurityNames = []

            securityNamesSets = [
                self._tagAndCommunityToSecurityMap[(t, communityName)]
                for t in tags
            ]

            for x in securityNamesSets:
                candidateSecurityNames.extend(list(x))

            if candidateSecurityNames:
                candidateSecurityNames.sort(key=self._orderSecurityNames)

                chosenSecurityName = candidateSecurityNames[0]  # min()

                debug.logger & debug.FLAG_SM and debug.logger(
                    '_com2sec: securityName candidates for communityName %s '
                    'are %s; choosing securityName '
                    '%s' % (communityName, candidateSecurityNames,
                            chosenSecurityName[0]))

                return chosenSecurityName

        raise error.StatusInformation(
            errorIndication=errind.unknownCommunityName)
コード例 #23
0
    def __generateRequestOrResponseMsg(self, snmpEngine,
                                       messageProcessingModel, globalData,
                                       maxMessageSize, securityModel,
                                       securityEngineID, securityName,
                                       securityLevel, scopedPDU,
                                       securityStateReference):
        snmpEngineID = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineID')[0].syntax
        # 3.1.1
        if securityStateReference is not None:
            # 3.1.1a
            cachedSecurityData = self._cache.pop(securityStateReference)
            usmUserName = cachedSecurityData['msgUserName']
            if 'usmUserSecurityName' in cachedSecurityData:
                usmUserSecurityName = cachedSecurityData['usmUserSecurityName']
            else:
                usmUserSecurityName = usmUserName
            if 'usmUserAuthProtocol' in cachedSecurityData:
                usmUserAuthProtocol = cachedSecurityData['usmUserAuthProtocol']
            else:
                usmUserAuthProtocol = noauth.NoAuth.serviceID
            if 'usmUserAuthKeyLocalized' in cachedSecurityData:
                usmUserAuthKeyLocalized = cachedSecurityData[
                    'usmUserAuthKeyLocalized']
            else:
                usmUserAuthKeyLocalized = None
            if 'usmUserPrivProtocol' in cachedSecurityData:
                usmUserPrivProtocol = cachedSecurityData['usmUserPrivProtocol']
            else:
                usmUserPrivProtocol = nopriv.NoPriv.serviceID
            if 'usmUserPrivKeyLocalized' in cachedSecurityData:
                usmUserPrivKeyLocalized = cachedSecurityData[
                    'usmUserPrivKeyLocalized']
            else:
                usmUserPrivKeyLocalized = None
            securityEngineID = snmpEngineID
            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: user info read from cache')
        elif securityName:
            # 3.1.1b
            try:
                (usmUserName, usmUserSecurityName, usmUserAuthProtocol,
                 usmUserAuthKeyLocalized, usmUserPrivProtocol,
                 usmUserPrivKeyLocalized) = self.__getUserInfo(
                     snmpEngine.msgAndPduDsp.mibInstrumController,
                     securityEngineID,
                     self.__sec2usr(snmpEngine, securityName,
                                    securityEngineID))
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: read user info')
            except NoSuchInstanceError:
                pysnmpUsmDiscovery, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__PYSNMP-USM-MIB', 'pysnmpUsmDiscovery')
                __reportUnknownName = not pysnmpUsmDiscovery.syntax
                if not __reportUnknownName:
                    try:
                        (usmUserName, usmUserSecurityName, usmUserAuthProtocol,
                         usmUserAuthKeyLocalized, usmUserPrivProtocol,
                         usmUserPrivKeyLocalized) = self.__cloneUserInfo(
                             snmpEngine.msgAndPduDsp.mibInstrumController,
                             securityEngineID,
                             self.__sec2usr(snmpEngine, securityName))
                    except NoSuchInstanceError:
                        __reportUnknownName = 1

                if __reportUnknownName:
                    raise error.StatusInformation(
                        errorIndication=errind.unknownSecurityName)
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: clone user info')
            except PyAsn1Error:
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: %s' % (sys.exc_info()[1], ))
                snmpInGenErrs, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__SNMPv2-MIB', 'snmpInGenErrs')
                snmpInGenErrs.syntax = snmpInGenErrs.syntax + 1
                raise error.StatusInformation(
                    errorIndication=errind.invalidMsg)
        else:
            # empty username used for engineID discovery
            usmUserName = usmUserSecurityName = null
            usmUserAuthProtocol = noauth.NoAuth.serviceID
            usmUserPrivProtocol = nopriv.NoPriv.serviceID
            usmUserAuthKeyLocalized = usmUserPrivKeyLocalized = None
            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: use empty USM data')

        debug.logger & debug.flagSM and debug.logger(
            '__generateRequestOrResponseMsg: local usmUserName %r usmUserSecurityName %r usmUserAuthProtocol %s usmUserPrivProtocol %s securityEngineID %r securityName %r'
            % (usmUserName, usmUserSecurityName, usmUserAuthProtocol,
               usmUserPrivProtocol, securityEngineID, securityName))

        msg = globalData

        # 3.1.2
        if securityLevel == 3:
            if usmUserAuthProtocol == noauth.NoAuth.serviceID or \
               usmUserPrivProtocol == nopriv.NoPriv.serviceID:
                raise error.StatusInformation(
                    errorIndication=errind.unsupportedSecurityLevel)

        # 3.1.3
        if securityLevel == 3 or securityLevel == 2:
            if usmUserAuthProtocol == noauth.NoAuth.serviceID:
                raise error.StatusInformation(
                    errorIndication=errind.unsupportedSecurityLevel)

        securityParameters = self.__securityParametersSpec

        scopedPDUData = msg.setComponentByPosition(3).getComponentByPosition(3)
        scopedPDUData.setComponentByPosition(0,
                                             scopedPDU,
                                             verifyConstraints=False)

        # 3.1.6a
        if securityStateReference is None and (  # request type check added
                securityLevel == 3 or securityLevel == 2):
            if securityEngineID in self.__timeline:
                (snmpEngineBoots, snmpEngineTime, latestReceivedEngineTime,
                 latestUpdateTimestamp) = self.__timeline[securityEngineID]
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: read snmpEngineBoots, snmpEngineTime from timeline'
                )
            else:
                # 2.3 XXX is this correct?
                snmpEngineBoots = snmpEngineTime = 0
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: no timeline for securityEngineID %r'
                    % (securityEngineID, ))
        # 3.1.6.b
        elif securityStateReference is not None:  # XXX Report?
            (
                snmpEngineBoots, snmpEngineTime
            ) = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                '__SNMP-FRAMEWORK-MIB', 'snmpEngineBoots', 'snmpEngineTime')
            snmpEngineBoots = snmpEngineBoots.syntax
            snmpEngineTime = snmpEngineTime.syntax.clone()
            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: read snmpEngineBoots, snmpEngineTime from LCD'
            )
        # 3.1.6.c
        else:
            snmpEngineBoots = snmpEngineTime = 0
            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: assuming zero snmpEngineBoots, snmpEngineTime'
            )

        debug.logger & debug.flagSM and debug.logger(
            '__generateRequestOrResponseMsg: use snmpEngineBoots %s snmpEngineTime %s for securityEngineID %r'
            % (snmpEngineBoots, snmpEngineTime, securityEngineID))

        # 3.1.4a
        if securityLevel == 3:
            if usmUserPrivProtocol in self.privServices:
                privHandler = self.privServices[usmUserPrivProtocol]
            else:
                raise error.StatusInformation(
                    errorIndication=errind.encryptionError)

            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: scopedPDU %s' %
                scopedPDU.prettyPrint())

            try:
                dataToEncrypt = encoder.encode(scopedPDU)
            except PyAsn1Error:
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: scopedPDU serialization error: %s'
                    % sys.exc_info()[1])
                raise error.StatusInformation(
                    errorIndication=errind.serializationError)

            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: scopedPDU encoded into %s' %
                debug.hexdump(dataToEncrypt))

            (encryptedData, privParameters) = privHandler.encryptData(
                usmUserPrivKeyLocalized,
                (snmpEngineBoots, snmpEngineTime, None), dataToEncrypt)

            securityParameters.setComponentByPosition(5,
                                                      privParameters,
                                                      verifyConstraints=False)
            scopedPDUData.setComponentByPosition(1,
                                                 encryptedData,
                                                 verifyConstraints=False)

            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: scopedPDU ciphered into %s' %
                debug.hexdump(encryptedData))

        # 3.1.4b
        elif securityLevel == 1 or securityLevel == 2:
            securityParameters.setComponentByPosition(5, '')

        debug.logger & debug.flagSM and debug.logger(
            '__generateRequestOrResponseMsg: %s' % scopedPDUData.prettyPrint())

        # 3.1.5
        securityParameters.setComponentByPosition(0,
                                                  securityEngineID,
                                                  verifyConstraints=False)
        securityParameters.setComponentByPosition(1,
                                                  snmpEngineBoots,
                                                  verifyConstraints=False)
        securityParameters.setComponentByPosition(2,
                                                  snmpEngineTime,
                                                  verifyConstraints=False)

        # 3.1.7
        securityParameters.setComponentByPosition(3,
                                                  usmUserName,
                                                  verifyConstraints=False)

        # 3.1.8a
        if securityLevel == 3 or securityLevel == 2:
            if usmUserAuthProtocol in self.authServices:
                authHandler = self.authServices[usmUserAuthProtocol]
            else:
                raise error.StatusInformation(
                    errorIndication=errind.authenticationFailure)

            # extra-wild hack to facilitate BER substrate in-place re-write
            securityParameters.setComponentByPosition(
                4, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')

            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: %s' %
                (securityParameters.prettyPrint(), ))

            try:
                msg.setComponentByPosition(2,
                                           encoder.encode(securityParameters),
                                           verifyConstraints=False)
            except PyAsn1Error:
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: securityParameters serialization error: %s'
                    % sys.exc_info()[1])
                raise error.StatusInformation(
                    errorIndication=errind.serializationError)

            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: auth outgoing msg: %s' %
                msg.prettyPrint())

            try:
                wholeMsg = encoder.encode(msg)
            except PyAsn1Error:
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: msg serialization error: %s'
                    % sys.exc_info()[1])
                raise error.StatusInformation(
                    errorIndication=errind.serializationError)

            authenticatedWholeMsg = authHandler.authenticateOutgoingMsg(
                usmUserAuthKeyLocalized, wholeMsg)

        # 3.1.8b
        else:
            securityParameters.setComponentByPosition(4,
                                                      '',
                                                      verifyConstraints=False)

            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: %s' %
                (securityParameters.prettyPrint(), ))

            try:
                msg.setComponentByPosition(2,
                                           encoder.encode(securityParameters),
                                           verifyConstraints=False)
            except PyAsn1Error:
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: secutiryParameters serialization error: %s'
                    % sys.exc_info()[1])
                raise error.StatusInformation(
                    errorIndication=errind.serializationError)

            try:
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: plain outgoing msg: %s' %
                    msg.prettyPrint())
                authenticatedWholeMsg = encoder.encode(msg)
            except PyAsn1Error:
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: msg serialization error: %s'
                    % sys.exc_info()[1])
                raise error.StatusInformation(
                    errorIndication=errind.serializationError)

        debug.logger & debug.flagSM and debug.logger(
            '__generateRequestOrResponseMsg: %s outgoing msg: %s' %
            (securityLevel > 1 and "authenticated"
             or "plain", debug.hexdump(authenticatedWholeMsg)))

        # 3.1.9
        return (msg.getComponentByPosition(2), authenticatedWholeMsg)
コード例 #24
0
ファイル: rfc2576.py プロジェクト: zxx1819/pysnmp
    def _sec2com(self, snmpEngine, securityName, contextEngineId, contextName):
        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        snmpTargetParamsSecurityName, = mibBuilder.importSymbols(
            'SNMP-TARGET-MIB', 'snmpTargetParamsSecurityName')

        if self._paramsBranchId != snmpTargetParamsSecurityName.branchVersionId:
            snmpTargetParamsSecurityModel, = mibBuilder.importSymbols(
                'SNMP-TARGET-MIB', 'snmpTargetParamsSecurityModel')

            self._nameToModelMap = {}

            nextMibNode = snmpTargetParamsSecurityName

            while True:
                try:
                    nextMibNode = snmpTargetParamsSecurityName.getNextNode(
                        nextMibNode.name)

                except NoSuchInstanceError:
                    break

                instId = nextMibNode.name[len(snmpTargetParamsSecurityName.name
                                              ):]

                mibNode = snmpTargetParamsSecurityModel.getNode(
                    snmpTargetParamsSecurityModel.name + instId)

                try:
                    if mibNode.syntax not in self._nameToModelMap:
                        self._nameToModelMap[nextMibNode.syntax] = set()

                    self._nameToModelMap[nextMibNode.syntax].add(
                        mibNode.syntax)

                except PyAsn1Error:
                    debug.logger & debug.FLAG_SM and debug.logger(
                        '_sec2com: table entries %r/%r hashing '
                        'failed' % (nextMibNode.syntax, mibNode.syntax))
                    continue

            self._paramsBranchId = snmpTargetParamsSecurityName.branchVersionId

            # invalidate next map as it include this one
            self._securityBranchId = -1

        snmpCommunityName, = mibBuilder.importSymbols('SNMP-COMMUNITY-MIB',
                                                      'snmpCommunityName')

        if self._securityBranchId != snmpCommunityName.branchVersionId:
            (snmpCommunitySecurityName, snmpCommunityContextEngineId,
             snmpCommunityContextName) = mibBuilder.importSymbols(
                 'SNMP-COMMUNITY-MIB', 'snmpCommunitySecurityName',
                 'snmpCommunityContextEngineID', 'snmpCommunityContextName')

            self._securityMap = {}

            nextMibNode = snmpCommunityName

            while True:
                try:
                    nextMibNode = snmpCommunityName.getNextNode(
                        nextMibNode.name)

                except NoSuchInstanceError:
                    break

                instId = nextMibNode.name[len(snmpCommunityName.name):]

                _securityName = snmpCommunitySecurityName.getNode(
                    snmpCommunitySecurityName.name + instId).syntax

                _contextEngineId = snmpCommunityContextEngineId.getNode(
                    snmpCommunityContextEngineId.name + instId).syntax

                _contextName = snmpCommunityContextName.getNode(
                    snmpCommunityContextName.name + instId).syntax

                key = _securityName, _contextEngineId, _contextName

                try:
                    self._securityMap[key] = nextMibNode.syntax

                except PyAsn1Error:
                    debug.logger & debug.FLAG_SM and debug.logger(
                        '_sec2com: table entries %r/%r/%r hashing failed' %
                        key)
                    continue

            self._securityBranchId = snmpCommunityName.branchVersionId

            debug.logger & debug.FLAG_SM and debug.logger(
                '_sec2com: built securityName to communityName map, version '
                '%s: %s' % (self._securityBranchId, self._securityMap))

        key = securityName, contextEngineId, contextName

        try:
            return self._securityMap[key]

        except KeyError:
            raise error.StatusInformation(
                errorIndication=errind.unknownCommunityName)
コード例 #25
0
ファイル: rfc2576.py プロジェクト: zxx1819/pysnmp
    def prepareResponseMessage(self, snmpEngine, messageProcessingModel,
                               securityModel, securityName, securityLevel,
                               contextEngineId, contextName, pduVersion, pdu,
                               maxSizeResponseScopedPDU, stateReference,
                               statusInformation):

        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        snmpEngineId, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB',
                                                 'snmpEngineID')
        snmpEngineId = snmpEngineId.syntax

        # rfc3412: 7.1.2.b
        if stateReference is None:
            raise error.StatusInformation(errorIndication=errind.nonReportable)

        cachedParams = self._cache.popByStateRef(stateReference)

        msgID = cachedParams['msgID']
        reqID = cachedParams['reqID']
        contextEngineId = cachedParams['contextEngineId']
        contextName = cachedParams['contextName']
        securityModel = cachedParams['securityModel']
        securityName = cachedParams['securityName']
        securityLevel = cachedParams['securityLevel']
        securityStateReference = cachedParams['securityStateReference']
        maxMessageSize = cachedParams['msgMaxSize']
        transportDomain = cachedParams['transportDomain']
        transportAddress = cachedParams['transportAddress']

        debug.logger & debug.FLAG_MP and debug.logger(
            'prepareResponseMessage: cache read msgID %s transportDomain %s '
            'transportAddress %s by stateReference %s' %
            (msgID, transportDomain, transportAddress, stateReference))

        # rfc3412: 7.1.3
        if statusInformation:
            # rfc3412: 7.1.3a (N/A)

            # rfc3412: 7.1.3b (always discard)
            raise error.StatusInformation(errorIndication=errind.nonReportable)

        # rfc3412: 7.1.4
        # Since there's no SNMP engine identification in v1/2c,
        # set destination contextEngineId to ours
        if not contextEngineId:
            contextEngineId = snmpEngineId

        # rfc3412: 7.1.5
        if not contextName:
            contextName = null

        # rfc3412: 7.1.6
        scopedPDU = (contextEngineId, contextName, pdu)

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

        msg = self._snmpMsgSpec
        msg.setComponentByPosition(0, messageProcessingModel)
        msg.setComponentByPosition(2)
        msg.getComponentByPosition(2).setComponentByType(
            pdu.tagSet,
            pdu,
            verifyConstraints=False,
            matchTags=False,
            matchConstraints=False)

        # att: msgId not set back to PDU as it's up to responder app

        # rfc3412: 7.1.7
        globalData = (msg, )

        k = int(securityModel)
        if k in snmpEngine.securityModels:
            smHandler = snmpEngine.securityModels[k]

        else:
            raise error.StatusInformation(
                errorIndication=errind.unsupportedSecurityModel)

        # set original request-id right prior to PDU serialization
        pdu.setComponentByPosition(0, reqID)

        # rfc3412: 7.1.8.a
        securityParameters, wholeMsg = smHandler.generateResponseMsg(
            snmpEngine, self.MESSAGE_PROCESSING_MODEL_ID, globalData,
            maxMessageSize, securityModel, snmpEngineId, securityName,
            securityLevel, scopedPDU, securityStateReference)

        # recover unique request-id right after PDU serialization
        pdu.setComponentByPosition(0, msgID)

        snmpEngine.observer.storeExecutionContext(
            snmpEngine, 'rfc2576.prepareResponseMessage',
            dict(transportDomain=transportDomain,
                 transportAddress=transportAddress,
                 securityModel=securityModel,
                 securityName=securityName,
                 securityLevel=securityLevel,
                 contextEngineId=contextEngineId,
                 contextName=contextName,
                 securityEngineId=snmpEngineId,
                 communityName=msg.getComponentByPosition(1),
                 pdu=pdu))

        snmpEngine.observer.clearExecutionContext(
            snmpEngine, 'rfc2576.prepareResponseMessage')

        return transportDomain, transportAddress, wholeMsg
コード例 #26
0
ファイル: rfc2576.py プロジェクト: zxx1819/pysnmp
    def processIncomingMsg(self, snmpEngine, messageProcessingModel,
                           maxMessageSize, securityParameters, securityModel,
                           securityLevel, wholeMsg, msg):
        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        # rfc2576: 5.2.1
        communityName, transportInformation = securityParameters

        scope = dict(communityName=communityName,
                     transportInformation=transportInformation)

        snmpEngine.observer.storeExecutionContext(
            snmpEngine, 'rfc2576.processIncomingMsg:writable', scope)

        snmpEngine.observer.clearExecutionContext(
            snmpEngine, 'rfc2576.processIncomingMsg:writable')

        try:
            securityName, contextEngineId, contextName = self._com2sec(
                snmpEngine, scope.get('communityName', communityName),
                scope.get('transportInformation', transportInformation))

        except error.StatusInformation:
            snmpInBadCommunityNames, = mibBuilder.importSymbols(
                '__SNMPv2-MIB', 'snmpInBadCommunityNames')
            snmpInBadCommunityNames.syntax += 1

            raise error.StatusInformation(
                errorIndication=errind.unknownCommunityName,
                communityName=communityName)

        snmpEngineID, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB',
                                                 'snmpEngineID')

        securityEngineID = snmpEngineID.syntax

        snmpEngine.observer.storeExecutionContext(
            snmpEngine, 'rfc2576.processIncomingMsg',
            dict(transportInformation=transportInformation,
                 securityEngineId=securityEngineID,
                 securityName=securityName,
                 communityName=communityName,
                 contextEngineId=contextEngineId,
                 contextName=contextName))

        snmpEngine.observer.clearExecutionContext(
            snmpEngine, 'rfc2576.processIncomingMsg')

        debug.logger & debug.FLAG_SM and debug.logger(
            'processIncomingMsg: looked up securityName %r securityModel %r '
            'contextEngineId %r contextName %r by communityName %r '
            'AND transportInformation '
            '%r' % (securityName, self.SECURITY_MODEL_ID, contextEngineId,
                    contextName, communityName, transportInformation))

        stateReference = self._cache.push(communityName=communityName)

        scopedPDU = (contextEngineId, contextName,
                     msg.getComponentByPosition(2).getComponent())

        maxSizeResponseScopedPDU = maxMessageSize - 128

        securityStateReference = stateReference

        debug.logger & debug.FLAG_SM and debug.logger(
            'processIncomingMsg: generated maxSizeResponseScopedPDU '
            '%s securityStateReference '
            '%s' % (maxSizeResponseScopedPDU, securityStateReference))

        return (securityEngineID, securityName, scopedPDU,
                maxSizeResponseScopedPDU, securityStateReference)
コード例 #27
0
ファイル: rfc2576.py プロジェクト: zxx1819/pysnmp
    def prepareOutgoingMessage(self, snmpEngine, transportDomain,
                               transportAddress, messageProcessingModel,
                               securityModel, securityName, securityLevel,
                               contextEngineId, contextName, pduVersion, pdu,
                               expectResponse, sendPduHandle):

        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        snmpEngineId, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB',
                                                 'snmpEngineID')
        snmpEngineId = snmpEngineId.syntax

        # rfc3412: 7.1.1b
        if pdu.tagSet in rfc3411.CONFIRMED_CLASS_PDUS:
            # serve unique PDU request-id
            msgID = self._cache.newMsgID()
            reqID = pdu.getComponentByPosition(0)

            debug.logger & debug.FLAG_MP and debug.logger(
                'prepareOutgoingMessage: PDU request-id %s replaced with '
                'unique ID %s' % (reqID, msgID))

        # rfc3412: 7.1.4
        # Since there's no SNMP engine identification in v1/2c,
        # set destination contextEngineId to ours
        if not contextEngineId:
            contextEngineId = snmpEngineId

        # rfc3412: 7.1.5
        if not contextName:
            contextName = null

        debug.logger & debug.FLAG_MP and debug.logger(
            'prepareOutgoingMessage: using contextEngineId %r contextName '
            '%r' % (contextEngineId, contextName))

        # rfc3412: 7.1.6
        scopedPDU = contextEngineId, contextName, pdu

        msg = self._snmpMsgSpec

        msg.setComponentByPosition(0, self.MESSAGE_PROCESSING_MODEL_ID)
        msg.setComponentByPosition(2)
        msg.getComponentByPosition(2).setComponentByType(
            pdu.tagSet,
            pdu,
            verifyConstraints=False,
            matchTags=False,
            matchConstraints=False)

        # rfc3412: 7.1.7
        globalData = (msg, )

        k = int(securityModel)
        if k in snmpEngine.securityModels:
            smHandler = snmpEngine.securityModels[k]

        else:
            raise error.StatusInformation(
                errorIndication=errind.unsupportedSecurityModel)

        # rfc3412: 7.1.9.a & rfc2576: 5.2.1 --> no-op

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

        # fix unique request-id right prior PDU serialization
        if pdu.tagSet in rfc3411.CONFIRMED_CLASS_PDUS:
            # noinspection PyUnboundLocalVariable
            pdu.setComponentByPosition(0, msgID)

        # rfc3412: 7.1.9.b
        securityParameters, wholeMsg = smHandler.generateRequestMsg(
            snmpEngine, self.MESSAGE_PROCESSING_MODEL_ID, globalData,
            snmpEngineMaxMessageSize.syntax, securityModel, snmpEngineId,
            securityName, securityLevel, scopedPDU)

        # return original request-id right after PDU serialization
        if pdu.tagSet in rfc3411.CONFIRMED_CLASS_PDUS:
            # noinspection PyUnboundLocalVariable
            pdu.setComponentByPosition(0, reqID)

        # rfc3412: 7.1.9.c
        if pdu.tagSet in rfc3411.CONFIRMED_CLASS_PDUS:
            # XXX rfc bug? why stateReference should be created?
            self._cache.pushByMsgId(int(msgID),
                                    sendPduHandle=sendPduHandle,
                                    reqID=reqID,
                                    snmpEngineId=snmpEngineId,
                                    securityModel=securityModel,
                                    securityName=securityName,
                                    securityLevel=securityLevel,
                                    contextEngineId=contextEngineId,
                                    contextName=contextName,
                                    transportDomain=transportDomain,
                                    transportAddress=transportAddress)

        communityName = msg.getComponentByPosition(1)  # for observer

        snmpEngine.observer.storeExecutionContext(
            snmpEngine, 'rfc2576.prepareOutgoingMessage',
            dict(transportDomain=transportDomain,
                 transportAddress=transportAddress,
                 wholeMsg=wholeMsg,
                 securityModel=securityModel,
                 securityName=securityName,
                 securityLevel=securityLevel,
                 contextEngineId=contextEngineId,
                 contextName=contextName,
                 communityName=communityName,
                 pdu=pdu))

        snmpEngine.observer.clearExecutionContext(
            snmpEngine, 'rfc2576.prepareOutgoingMessage')

        return transportDomain, transportAddress, wholeMsg
コード例 #28
0
ファイル: rfc2576.py プロジェクト: rishie/testerman
    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

        # rfc3412: 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']
        maxMessageSize = cachedParams['msgMaxSize']
        transportDomain = cachedParams['transportDomain']
        transportAddress = cachedParams['transportAddress']

        debug.logger & debug.flagMP and debug.logger('prepareResponseMessage: cache read msgID %s transportDomain %s transportAddress %s by stateReference %s' % (msgID, transportDomain, transportAddress, stateReference))

        # rfc3412: 7.1.3
        if statusInformation:
            # rfc3412: 7.1.3a (N/A)
            
            # rfc3412: 7.1.3b (always discard)
            raise error.StatusInformation(
                errorIndication = 'nonReportable'
                )

        # rfc3412: 7.1.4
        # Since there's no SNMP engine identification in v1/2c,
        # set destination contextEngineId to ours
        if not contextEngineId:
            contextEngineId = snmpEngineID

        # rfc3412: 7.1.5
        if not contextName:
            contextName = ''

        # rfc3412: 7.1.6
        scopedPDU = ( contextEngineId, contextName, pdu )

        debug.logger & debug.flagMP and debug.logger('prepareResponseMessage: using contextEngineId %s contextName %s' % (contextEngineId, contextName))
        
        msg = self._snmpMsgSpec.clone()
        msg.setComponentByPosition(0, messageProcessingModel)
        msg.setComponentByPosition(2)
        msg.getComponentByPosition(2).setComponentByType(pdu.tagSet, pdu)

        # att: msgId not set back to PDU as it's up to responder app
        
        # rfc3412: 7.1.7
        globalData = ( msg, )

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

        securityEngineId = snmpEngineID

        # rfc3412: 7.1.8.a
        ( securityParameters,
          wholeMsg ) = smHandler.generateResponseMsg(
            snmpEngine,
            self.messageProcessingModelID,
            globalData,
            maxMessageSize,
            securityModel,
            snmpEngineID,
            securityName,
            securityLevel,
            scopedPDU,
            securityStateReference
            )

        return ( transportDomain, transportAddress, wholeMsg )
コード例 #29
0
ファイル: rfc2576.py プロジェクト: fyfdoc/IntegrateTest
    def _sec2com(self, snmpEngine, securityName, contextEngineId, contextName):
        snmpTargetParamsSecurityName, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            'SNMP-TARGET-MIB', 'snmpTargetParamsSecurityName')
        if self.__paramsBranchId != snmpTargetParamsSecurityName.branchVersionId:
            snmpTargetParamsSecurityModel, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                'SNMP-TARGET-MIB', 'snmpTargetParamsSecurityModel')

            self.__nameToModelMap = {}

            nextMibNode = snmpTargetParamsSecurityName

            while 1:
                try:
                    nextMibNode = snmpTargetParamsSecurityName.getNextNode(
                        nextMibNode.name)

                except NoSuchInstanceError:
                    break

                instId = nextMibNode.name[len(snmpTargetParamsSecurityName.name
                                              ):]

                mibNode = snmpTargetParamsSecurityModel.getNode(
                    snmpTargetParamsSecurityModel.name + instId)

                if mibNode.syntax not in self.__nameToModelMap:
                    self.__nameToModelMap[nextMibNode.syntax] = set()

                self.__nameToModelMap[nextMibNode.syntax].add(mibNode.syntax)

            self.__paramsBranchId = snmpTargetParamsSecurityName.branchVersionId

            # invalidate next map as it include this one
            self.__securityBranchId = -1

        snmpCommunityName, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            'SNMP-COMMUNITY-MIB', 'snmpCommunityName')
        if self.__securityBranchId != snmpCommunityName.branchVersionId:
            (
                snmpCommunitySecurityName, snmpCommunityContextEngineId,
                snmpCommunityContextName
            ) = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                'SNMP-COMMUNITY-MIB', 'snmpCommunitySecurityName',
                'snmpCommunityContextEngineID', 'snmpCommunityContextName')

            self.__securityMap = {}

            nextMibNode = snmpCommunityName
            while 1:
                try:
                    nextMibNode = snmpCommunityName.getNextNode(
                        nextMibNode.name)

                except NoSuchInstanceError:
                    break

                instId = nextMibNode.name[len(snmpCommunityName.name):]

                _securityName = snmpCommunitySecurityName.getNode(
                    snmpCommunitySecurityName.name + instId).syntax

                _contextEngineId = snmpCommunityContextEngineId.getNode(
                    snmpCommunityContextEngineId.name + instId).syntax

                _contextName = snmpCommunityContextName.getNode(
                    snmpCommunityContextName.name + instId).syntax

                self.__securityMap[(_securityName, _contextEngineId,
                                    _contextName)] = nextMibNode.syntax

            self.__securityBranchId = snmpCommunityName.branchVersionId

            debug.logger & debug.flagSM and debug.logger(
                '_sec2com: built securityName to communityName map, version %s: %s'
                % (self.__securityBranchId, self.__securityMap))

        try:
            return self.__securityMap[(securityName, contextEngineId,
                                       contextName)]

        except KeyError:
            raise error.StatusInformation(
                errorIndication=errind.unknownCommunityName)
コード例 #30
0
ファイル: rfc2576.py プロジェクト: jordonTian/pysnmp
def v2ToV1(v2Pdu, origV1Pdu=None):
    debug.logger & debug.FLAG_PRX and debug.logger(
        'v2ToV1: v2Pdu %s' % v2Pdu.prettyPrint())

    pduType = v2Pdu.tagSet

    if pduType in V2_TO_V1_PDU_MAP:
        v1Pdu = V2_TO_V1_PDU_MAP[pduType].clone()

    else:
        raise error.ProtocolError('Unsupported PDU type')

    v2VarBinds = v2c.apiPDU.getVarBinds(v2Pdu)
    v1VarBinds = []

    zeroInt = v1.Integer(0)

    # 3.2
    if pduType in rfc3411.NOTIFICATION_CLASS_PDUS:
        if len(v2VarBinds) < 2:
            raise error.ProtocolError(
                'SNMP v2c TRAP PDU requires at least two var-binds')

        # 3.2.1
        snmpTrapOID, snmpTrapOIDParam = v2VarBinds[1]
        if snmpTrapOID != v2c.apiTrapPDU.snmpTrapOID:
            raise error.ProtocolError('Second OID not snmpTrapOID')

        if snmpTrapOIDParam in V2_TO_V1_TRAP_MAP:
            for oid, val in v2VarBinds:
                if oid == v2c.apiTrapPDU.snmpTrapEnterprise:
                    v1.apiTrapPDU.setEnterprise(v1Pdu, val)
                    break

            else:
                # snmpTraps
                v1.apiTrapPDU.setEnterprise(v1Pdu, (1, 3, 6, 1, 6, 3, 1, 1, 5))

        else:
            if snmpTrapOIDParam[-2] == 0:
                v1.apiTrapPDU.setEnterprise(v1Pdu, snmpTrapOIDParam[:-2])

            else:
                v1.apiTrapPDU.setEnterprise(v1Pdu, snmpTrapOIDParam[:-1])

        # 3.2.2
        for oid, val in v2VarBinds:
            # snmpTrapAddress
            if oid == v2c.apiTrapPDU.snmpTrapAddress:
                # v2c.OctetString is more constrained
                v1.apiTrapPDU.setAgentAddr(v1Pdu, v1.IpAddress(val))
                break

        else:
            v1.apiTrapPDU.setAgentAddr(v1Pdu, v1.IpAddress('0.0.0.0'))

        # 3.2.3
        if snmpTrapOIDParam in V2_TO_V1_TRAP_MAP:
            v1.apiTrapPDU.setGenericTrap(
                v1Pdu, V2_TO_V1_TRAP_MAP[snmpTrapOIDParam])

        else:
            v1.apiTrapPDU.setGenericTrap(v1Pdu, 6)

        # 3.2.4
        if snmpTrapOIDParam in V2_TO_V1_TRAP_MAP:
            v1.apiTrapPDU.setSpecificTrap(v1Pdu, zeroInt)

        else:
            v1.apiTrapPDU.setSpecificTrap(v1Pdu, snmpTrapOIDParam[-1])

        # 3.2.5
        v1.apiTrapPDU.setTimeStamp(v1Pdu, v2VarBinds[0][1])

        __v2VarBinds = []
        for oid, val in v2VarBinds[2:]:

            if (oid in V2_TO_V1_TRAP_MAP or
                    oid in (v2c.apiTrapPDU.sysUpTime,
                            v2c.apiTrapPDU.snmpTrapAddress,
                            v2c.apiTrapPDU.snmpTrapEnterprise)):
                continue

            __v2VarBinds.append((oid, val))

        v2VarBinds = __v2VarBinds

        # 3.2.6 --> done below

    else:
        v1.apiPDU.setErrorStatus(v1Pdu, zeroInt)
        v1.apiPDU.setErrorIndex(v1Pdu, zeroInt)

    if pduType in rfc3411.RESPONSE_CLASS_PDUS:

        idx = len(v2VarBinds) - 1

        while idx >= 0:
            # 4.1.2.1
            oid, val = v2VarBinds[idx]

            if v2c.Counter64.tagSet == val.tagSet:
                if origV1Pdu.tagSet == v1.GetRequestPDU.tagSet:
                    v1.apiPDU.setErrorStatus(v1Pdu, 2)
                    v1.apiPDU.setErrorIndex(v1Pdu, idx + 1)
                    break

                elif origV1Pdu.tagSet == v1.GetNextRequestPDU.tagSet:
                    raise error.StatusInformation(idx=idx, pdu=v2Pdu)

                else:
                    raise error.ProtocolError('Counter64 on the way')

            # 4.1.2.2.1&2
            if val.tagSet in (v2c.NoSuchObject.tagSet,
                              v2c.NoSuchInstance.tagSet,
                              v2c.EndOfMibView.tagSet):
                v1.apiPDU.setErrorStatus(v1Pdu, 2)
                v1.apiPDU.setErrorIndex(v1Pdu, idx + 1)

            idx -= 1

        # 4.1.2.3.1
        v2ErrorStatus = v2c.apiPDU.getErrorStatus(v2Pdu)
        if v2ErrorStatus:
            v1.apiPDU.setErrorStatus(
                v1Pdu, V2_TO_V1_ERROR_MAP.get(v2ErrorStatus, 5))
            v1.apiPDU.setErrorIndex(v1Pdu, v2c.apiPDU.getErrorIndex(v2Pdu, muteErrors=True))

    elif pduType in rfc3411.CONFIRMED_CLASS_PDUS:
        v1.apiPDU.setErrorStatus(v1Pdu, 0)
        v1.apiPDU.setErrorIndex(v1Pdu, 0)

    # Translate Var-Binds
    if (pduType in rfc3411.RESPONSE_CLASS_PDUS and
            v1.apiPDU.getErrorStatus(v1Pdu)):

        v1VarBinds = v1.apiPDU.getVarBinds(origV1Pdu)

    else:
        for oid, v2Val in v2VarBinds:
            v1VarBinds.append(
                (oid, V2_TO_V1_VALUE_MAP[v2Val.tagSet].clone(v2Val))
            )

    if pduType in rfc3411.NOTIFICATION_CLASS_PDUS:
        v1.apiTrapPDU.setVarBinds(v1Pdu, v1VarBinds)

    else:
        v1.apiPDU.setVarBinds(v1Pdu, v1VarBinds)

        v1.apiPDU.setRequestID(
            v1Pdu, v2c.apiPDU.getRequestID(v2Pdu)
        )

    debug.logger & debug.FLAG_PRX and debug.logger(
        'v2ToV1: v1Pdu %s' % v1Pdu.prettyPrint())

    return v1Pdu