Example #1
0
usmAesBlumenthalCfb256Protocol = aes256.AesBlumenthal256.serviceID  # semi-standard but not widely used
usmAesCfb192Protocol = aes192.Aes192.serviceID  # non-standard but used by many vendors
usmAesCfb256Protocol = aes256.Aes256.serviceID  # non-standard but used by many vendors
usmNoPrivProtocol = nopriv.NoPriv.serviceID

# Auth services
authServices = {hmacmd5.HmacMd5.serviceID: hmacmd5.HmacMd5(),
                hmacsha.HmacSha.serviceID: hmacsha.HmacSha(),
                hmacsha2.HmacSha2.sha224ServiceID: hmacsha2.HmacSha2(hmacsha2.HmacSha2.sha224ServiceID),
                hmacsha2.HmacSha2.sha256ServiceID: hmacsha2.HmacSha2(hmacsha2.HmacSha2.sha256ServiceID),
                hmacsha2.HmacSha2.sha384ServiceID: hmacsha2.HmacSha2(hmacsha2.HmacSha2.sha384ServiceID),
                hmacsha2.HmacSha2.sha512ServiceID: hmacsha2.HmacSha2(hmacsha2.HmacSha2.sha512ServiceID),
                noauth.NoAuth.serviceID: noauth.NoAuth()}

# Privacy services
privServices = {des.Des.serviceID: des.Des(),
                des3.Des3.serviceID: des3.Des3(),
                aes.Aes.serviceID: aes.Aes(),
                aes192.AesBlumenthal192.serviceID: aes192.AesBlumenthal192(),
                aes256.AesBlumenthal256.serviceID: aes256.AesBlumenthal256(),
                aes192.Aes192.serviceID: aes192.Aes192(),  # non-standard
                aes256.Aes256.serviceID: aes256.Aes256(),  # non-standard
                nopriv.NoPriv.serviceID: nopriv.NoPriv()}


def __cookV1SystemInfo(snmpEngine, communityIndex):
    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

    snmpEngineID, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
    snmpCommunityEntry, = mibBuilder.importSymbols('SNMP-COMMUNITY-MIB', 'snmpCommunityEntry')
    tblIdx = snmpCommunityEntry.getInstIdFromIndices(communityIndex)
Example #2
0
usm3DESEDEPrivProtocol = des3.Des3.serviceID
usmAesCfb128Protocol = aes.Aes.serviceID
usmAesCfb192Protocol = aes192.Aes192.serviceID
usmAesCfb256Protocol = aes256.Aes256.serviceID
usmNoPrivProtocol = nopriv.NoPriv.serviceID

# Auth services
authServices = {
    hmacmd5.HmacMd5.serviceID: hmacmd5.HmacMd5(),
    hmacsha.HmacSha.serviceID: hmacsha.HmacSha(),
    noauth.NoAuth.serviceID: noauth.NoAuth()
    }

# Privacy services
privServices = {
    des.Des.serviceID: des.Des(),
    des3.Des3.serviceID: des3.Des3(),        
    aes.Aes.serviceID: aes.Aes(),
    aes192.Aes192.serviceID: aes192.Aes192(),
    aes256.Aes256.serviceID: aes256.Aes256(),
    nopriv.NoPriv.serviceID: nopriv.NoPriv()
    }
    
def __cookV1SystemInfo(snmpEngine, communityIndex):
    snmpEngineID, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')

    snmpCommunityEntry, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('SNMP-COMMUNITY-MIB', 'snmpCommunityEntry')
    tblIdx = snmpCommunityEntry.getInstIdFromIndices(communityIndex)
    return snmpCommunityEntry, tblIdx, snmpEngineID
    
def addV1System(snmpEngine, communityIndex, communityName,
Example #3
0
class SnmpUSMSecurityModel(AbstractSecurityModel):
    securityModelID = 3
    authServices = {
        hmacmd5.HmacMd5.serviceID: hmacmd5.HmacMd5(),
        hmacsha.HmacSha.serviceID: hmacsha.HmacSha(),
        noauth.NoAuth.serviceID: noauth.NoAuth()
    }
    privServices = {
        des.Des.serviceID: des.Des(),
        des3.Des3.serviceID: des3.Des3(),
        aes.Aes.serviceID: aes.Aes(),
        aes192.Aes192.serviceID: aes192.Aes192(),
        aes256.Aes256.serviceID: aes256.Aes256(),
        nopriv.NoPriv.serviceID: nopriv.NoPriv()
    }

    def __init__(self):
        AbstractSecurityModel.__init__(self)
        self.__securityParametersSpec = UsmSecurityParameters()
        self.__timeline = {}
        self.__timelineExpQueue = {}
        self.__expirationTimer = 0
        self.__paramsBranchId = -1

    def __sec2usr(self, snmpEngine, securityName, securityEngineID=None):
        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
        usmUserEngineID, = mibBuilder.importSymbols('SNMP-USER-BASED-SM-MIB',
                                                    'usmUserEngineID')
        if self.__paramsBranchId != usmUserEngineID.branchVersionId:
            usmUserName, usmUserSecurityName = mibBuilder.importSymbols(
                'SNMP-USER-BASED-SM-MIB', 'usmUserName', 'usmUserSecurityName')

            self.__securityToUserMap = {}

            nextMibNode = usmUserEngineID

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

                except NoSuchInstanceError:
                    self.__paramsBranchId = usmUserEngineID.branchVersionId
                    debug.logger & debug.flagSM and debug.logger(
                        '_sec2usr: built snmpEngineId + securityName to userName map, version %s: %r'
                        % (self.__paramsBranchId, self.__securityToUserMap))
                    break

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

                __engineID = usmUserEngineID.getNode(usmUserEngineID.name +
                                                     instId).syntax
                __userName = usmUserName.getNode(usmUserName.name +
                                                 instId).syntax
                __securityName = usmUserSecurityName.getNode(
                    usmUserSecurityName.name + instId).syntax

                k = __engineID, __securityName

                # first (lesser) securityName wins
                if k not in self.__securityToUserMap:
                    self.__securityToUserMap[k] = __userName

        if securityEngineID is None:
            snmpEngineID, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB',
                                                     'snmpEngineID')
            securityEngineID = snmpEngineID.syntax

        try:
            userName = self.__securityToUserMap[(securityEngineID,
                                                 securityName)]
        except KeyError:
            debug.logger & debug.flagSM and debug.logger(
                '_sec2usr: no entry exists for snmpEngineId %r, securityName %r'
                % (securityEngineID, securityName))
            raise NoSuchInstanceError()  # emulate MIB lookup

        debug.logger & debug.flagSM and debug.logger(
            '_sec2usr: using userName %r for snmpEngineId %r, securityName %r'
            % (userName, securityEngineID, securityName))

        return userName

    @staticmethod
    def __getUserInfo(mibInstrumController, securityEngineID, userName):
        usmUserEntry, = mibInstrumController.mibBuilder.importSymbols(
            'SNMP-USER-BASED-SM-MIB', 'usmUserEntry')
        tblIdx = usmUserEntry.getInstIdFromIndices(securityEngineID, userName)
        # Get userName & securityName
        usmUserName = usmUserEntry.getNode(usmUserEntry.name + (2, ) +
                                           tblIdx).syntax
        usmUserSecurityName = usmUserEntry.getNode(usmUserEntry.name + (3, ) +
                                                   tblIdx).syntax
        # Get protocols
        usmUserAuthProtocol = usmUserEntry.getNode(usmUserEntry.name + (5, ) +
                                                   tblIdx).syntax
        usmUserPrivProtocol = usmUserEntry.getNode(usmUserEntry.name + (8, ) +
                                                   tblIdx).syntax
        # Get keys
        pysnmpUsmKeyEntry, = mibInstrumController.mibBuilder.importSymbols(
            'PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry')
        pysnmpUsmKeyAuthLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (1, ) + tblIdx).syntax
        pysnmpUsmKeyPrivLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (2, ) + tblIdx).syntax
        return (usmUserName, usmUserSecurityName, usmUserAuthProtocol,
                pysnmpUsmKeyAuthLocalized, usmUserPrivProtocol,
                pysnmpUsmKeyPrivLocalized)

    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)

    def __generateRequestOrResponseMsg(self, snmpEngine,
                                       messageProcessingModel, globalData,
                                       maxMessageSize, securityModel,
                                       securityEngineID, securityName,
                                       securityLevel, scopedPDU,
                                       securityStateReference):
        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
        snmpEngineID = 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, = 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 = True

                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(
                    '__generateRequestOrResponseMsg: %s' %
                    (sys.exc_info()[1], ))
                snmpInGenErrs, = mibBuilder.importSymbols(
                    '__SNMPv2-MIB', 'snmpInGenErrs')
                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')

        # noinspection PyUnboundLocalVariable
        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 securityLevel in (2, 3):
            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) = 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))

            # noinspection PyUnboundLocalVariable
            (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)

            # noinspection PyUnboundLocalVariable
            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

    def generateRequestMsg(self, snmpEngine, messageProcessingModel,
                           globalData, maxMessageSize, securityModel,
                           securityEngineID, securityName, securityLevel,
                           scopedPDU):
        return self.__generateRequestOrResponseMsg(
            snmpEngine, messageProcessingModel, globalData, maxMessageSize,
            securityModel, securityEngineID, securityName, securityLevel,
            scopedPDU, None)

    def generateResponseMsg(self, snmpEngine, messageProcessingModel,
                            globalData, maxMessageSize, securityModel,
                            securityEngineID, securityName, securityLevel,
                            scopedPDU, securityStateReference):
        return self.__generateRequestOrResponseMsg(
            snmpEngine, messageProcessingModel, globalData, maxMessageSize,
            securityModel, securityEngineID, securityName, securityLevel,
            scopedPDU, securityStateReference)

    # 3.2
    def processIncomingMsg(self, snmpEngine, messageProcessingModel,
                           maxMessageSize, securityParameters, securityModel,
                           securityLevel, wholeMsg, msg):
        mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        # 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, = mibBuilder.importSymbols(
                '__SNMPv2-MIB', 'snmpInASNParseErrs')
            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 = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB',
                                                   'snmpEngineID')[0].syntax
        contextName = null

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

        # 3.2.3
        if msgAuthoritativeEngineId != snmpEngineID and \
                msgAuthoritativeEngineId not in self.__timeline:
            if msgAuthoritativeEngineId and \
                    4 < len(msgAuthoritativeEngineId) < 33:
                # 3.2.3a - cloned user when request was sent
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: unsynchronized securityEngineID %r' %
                    (msgAuthoritativeEngineId, ))
            else:
                # 3.2.3b
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: peer requested snmpEngineID discovery'
                )
                usmStatsUnknownEngineIDs, = mibBuilder.importSymbols(
                    '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownEngineIDs')
                usmStatsUnknownEngineIDs.syntax += 1
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: null or malformed msgAuthoritativeEngineId'
                )
                pysnmpUsmDiscoverable, = 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)

        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:
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: unknown securityEngineID %r msgUserName %r'
                    % (msgAuthoritativeEngineId, msgUserName))
                usmStatsUnknownUserNames, = mibBuilder.importSymbols(
                    '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownUserNames')
                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, = mibBuilder.importSymbols(
                    '__SNMPv2-MIB', 'snmpInGenErrs')
                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)

        snmpEngine.observer.storeExecutionContext(
            snmpEngine, 'rfc3414.processIncomingMsg',
            dict(securityEngineId=msgAuthoritativeEngineId,
                 snmpEngineBoots=msgAuthoritativeEngineBoots,
                 snmpEngineTime=msgAuthoritativeEngineTime,
                 userName=usmUserName,
                 securityName=usmUserSecurityName,
                 authProtocol=usmUserAuthProtocol,
                 authKey=usmUserAuthKeyLocalized,
                 privProtocol=usmUserPrivProtocol,
                 privKey=usmUserPrivKeyLocalized))
        snmpEngine.observer.clearExecutionContext(
            snmpEngine, 'rfc3414.processIncomingMsg')

        # 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, = mibBuilder.importSymbols(
                    '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnsupportedSecLevels')
                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:
                authHandler.authenticateIncomingMsg(
                    usmUserAuthKeyLocalized,
                    securityParameters.getComponentByPosition(4), wholeMsg)

            except error.StatusInformation:
                usmStatsWrongDigests, = mibBuilder.importSymbols(
                    '__SNMP-USER-BASED-SM-MIB', 'usmStatsWrongDigests')
                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')

            # synchronize time with authed peer
            self.__timeline[msgAuthoritativeEngineId] = (
                securityParameters.getComponentByPosition(1),
                securityParameters.getComponentByPosition(2),
                securityParameters.getComponentByPosition(2), int(time.time()))

            timerResolution = snmpEngine.transportDispatcher is None and 1.0 or snmpEngine.transportDispatcher.getTimerResolution(
            )
            expireAt = int(self.__expirationTimer + 300 / timerResolution)
            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) = 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, = mibBuilder.importSymbols(
                        '__SNMP-USER-BASED-SM-MIB', 'usmStatsNotInTimeWindows')
                    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
                # noinspection PyUnboundLocalVariable
                if msgAuthoritativeEngineBoots > snmpEngineBoots or \
                        msgAuthoritativeEngineBoots == snmpEngineBoots and \
                        msgAuthoritativeEngineTime > latestReceivedEngineTime:
                    self.__timeline[msgAuthoritativeEngineId] = (
                        msgAuthoritativeEngineBoots,
                        msgAuthoritativeEngineTime, msgAuthoritativeEngineTime,
                        int(time.time()))

                    timerResolution = snmpEngine.transportDispatcher is None and 1.0 or snmpEngine.transportDispatcher.getTimerResolution(
                    )
                    expireAt = int(self.__expirationTimer +
                                   300 / timerResolution)
                    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, = mibBuilder.importSymbols(
                    '__SNMP-USER-BASED-SM-MIB', 'usmStatsDecryptionErrors')
                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, = mibBuilder.importSymbols(
                '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownUserNames')
            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)

    def __expireTimelineInfo(self):
        if self.__expirationTimer in self.__timelineExpQueue:
            for engineIdKey in self.__timelineExpQueue[self.__expirationTimer]:
                if engineIdKey in self.__timeline:
                    del self.__timeline[engineIdKey]
                    debug.logger & debug.flagSM and debug.logger(
                        '__expireTimelineInfo: expiring %r' % (engineIdKey, ))
            del self.__timelineExpQueue[self.__expirationTimer]
        self.__expirationTimer += 1

    def receiveTimerTick(self, snmpEngine, timeNow):
        self.__expireTimelineInfo()
Example #4
0
    hmacsha.HmacSha.SERVICE_ID:
    hmacsha.HmacSha(),
    hmacsha2.HmacSha2.SHA224_SERVICE_ID:
    hmacsha2.HmacSha2(hmacsha2.HmacSha2.SHA224_SERVICE_ID),
    hmacsha2.HmacSha2.SHA256_SERVICE_ID:
    hmacsha2.HmacSha2(hmacsha2.HmacSha2.SHA256_SERVICE_ID),
    hmacsha2.HmacSha2.SHA384_SERVICE_ID:
    hmacsha2.HmacSha2(hmacsha2.HmacSha2.SHA384_SERVICE_ID),
    hmacsha2.HmacSha2.SHA512_SERVICE_ID:
    hmacsha2.HmacSha2(hmacsha2.HmacSha2.SHA512_SERVICE_ID),
    noauth.NoAuth.SERVICE_ID:
    noauth.NoAuth()
}

PRIV_SERVICES = {
    des.Des.SERVICE_ID: des.Des(),
    des3.Des3.SERVICE_ID: des3.Des3(),
    aes.Aes.SERVICE_ID: aes.Aes(),
    aes192.AesBlumenthal192.SERVICE_ID: aes192.AesBlumenthal192(),
    aes256.AesBlumenthal256.SERVICE_ID: aes256.AesBlumenthal256(),
    aes192.Aes192.SERVICE_ID: aes192.Aes192(),  # non-standard
    aes256.Aes256.SERVICE_ID: aes256.Aes256(),  # non-standard
    nopriv.NoPriv.SERVICE_ID: nopriv.NoPriv()
}

# This module uses Management Instrumentation subsystem in purely
# synchronous manner. The assumption is that the Management
# Instrumentation calls never yield control but block.


def __cookV1SystemInfo(snmpEngine, communityIndex):
Example #5
0
class SnmpUSMSecurityModel(AbstractSecurityModel):
    securityModelID = 3
    authServices = {
        hmacmd5.HmacMd5.serviceID: hmacmd5.HmacMd5(),
        hmacsha.HmacSha.serviceID: hmacsha.HmacSha(),
        noauth.NoAuth.serviceID: noauth.NoAuth()
    }
    privServices = {
        des.Des.serviceID: des.Des(),
        aes.Aes.serviceID: aes.Aes(),
        nopriv.NoPriv.serviceID: nopriv.NoPriv()
    }
    _securityParametersSpec = UsmSecurityParameters()

    def __init__(self):
        AbstractSecurityModel.__init__(self)
        self.__timeline = {}
        self.__timelineExpQueue = {}
        self.__expirationTimer = 0L

    def __getUserInfo(self, mibInstrumController, securityEngineID,
                      securityName):
        usmUserEntry, = mibInstrumController.mibBuilder.importSymbols(
            'SNMP-USER-BASED-SM-MIB', 'usmUserEntry')
        tblIdx = usmUserEntry.getInstIdFromIndices(securityEngineID,
                                                   securityName)
        # Get protocols
        usmUserSecurityName = usmUserEntry.getNode(usmUserEntry.name + (3, ) +
                                                   tblIdx).syntax
        usmUserAuthProtocol = usmUserEntry.getNode(usmUserEntry.name + (5, ) +
                                                   tblIdx).syntax
        usmUserPrivProtocol = usmUserEntry.getNode(usmUserEntry.name + (8, ) +
                                                   tblIdx).syntax
        # Get keys
        pysnmpUsmKeyEntry, = mibInstrumController.mibBuilder.importSymbols(
            'PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry')
        pysnmpUsmKeyAuthLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (1, ) + tblIdx).syntax
        pysnmpUsmKeyPrivLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (2, ) + tblIdx).syntax
        return (
            usmUserSecurityName,  # XXX function needed?
            usmUserAuthProtocol,
            pysnmpUsmKeyAuthLocalized,
            usmUserPrivProtocol,
            pysnmpUsmKeyPrivLocalized)

    def __cloneUserInfo(self, mibInstrumController, securityEngineID,
                        securityName):
        snmpEngineID, = mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
        # Proto entry
        usmUserEntry, = mibInstrumController.mibBuilder.importSymbols(
            'SNMP-USER-BASED-SM-MIB', 'usmUserEntry')
        tblIdx = usmUserEntry.getInstIdFromIndices(snmpEngineID.syntax,
                                                   securityName)
        # Get proto protocols
        usmUserSecurityName = usmUserEntry.getNode(usmUserEntry.name + (3, ) +
                                                   tblIdx)
        usmUserAuthProtocol = usmUserEntry.getNode(usmUserEntry.name + (5, ) +
                                                   tblIdx)
        usmUserPrivProtocol = usmUserEntry.getNode(usmUserEntry.name + (8, ) +
                                                   tblIdx)
        # Get proto keys
        pysnmpUsmKeyEntry, = mibInstrumController.mibBuilder.importSymbols(
            'PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry')
        pysnmpUsmKeyAuth = pysnmpUsmKeyEntry.getNode(pysnmpUsmKeyEntry.name +
                                                     (3, ) + tblIdx)
        pysnmpUsmKeyPriv = pysnmpUsmKeyEntry.getNode(pysnmpUsmKeyEntry.name +
                                                     (4, ) + tblIdx)

        # Create new row from proto values

        tblIdx = usmUserEntry.getInstIdFromIndices(securityEngineID,
                                                   securityName)
        # New row
        mibInstrumController.writeVars(
            ((usmUserEntry.name + (13, ) + tblIdx, 4), ))
        # Set protocols
        usmUserEntry.getNode(usmUserEntry.name + (3, ) +
                             tblIdx).syntax = usmUserSecurityName.syntax
        usmUserEntry.getNode(usmUserEntry.name + (5, ) +
                             tblIdx).syntax = usmUserAuthProtocol.syntax
        usmUserEntry.getNode(usmUserEntry.name + (8, ) +
                             tblIdx).syntax = usmUserPrivProtocol.syntax

        # Localize and set keys
        pysnmpUsmKeyEntry, = mibInstrumController.mibBuilder.importSymbols(
            'PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry')
        pysnmpUsmKeyAuthLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (1, ) + tblIdx)
        if usmUserAuthProtocol.syntax == hmacsha.HmacSha.serviceID:
            localAuthKey = localkey.localizeKeySHA(pysnmpUsmKeyAuth.syntax,
                                                   securityEngineID)
        elif usmUserAuthProtocol.syntax == hmacmd5.HmacMd5.serviceID:
            localAuthKey = localkey.localizeKeyMD5(pysnmpUsmKeyAuth.syntax,
                                                   securityEngineID)
        elif usmUserAuthProtocol.syntax == noauth.NoAuth.serviceID:
            localAuthKey = None
        else:
            raise error.StatusInformation(
                errorIndication='unsupportedAuthProtocol')
        if localAuthKey is not None:
            pysnmpUsmKeyAuthLocalized.syntax = pysnmpUsmKeyAuthLocalized.syntax.clone(
                localAuthKey)
        pysnmpUsmKeyPrivLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (2, ) + tblIdx)
        if usmUserPrivProtocol.syntax == des.Des.serviceID or \
           usmUserPrivProtocol.syntax == aes.Aes.serviceID:
            if usmUserAuthProtocol.syntax == hmacsha.HmacSha.serviceID:
                localPrivKey = localkey.localizeKeySHA(pysnmpUsmKeyPriv.syntax,
                                                       securityEngineID)
            else:
                localPrivKey = localkey.localizeKeyMD5(pysnmpUsmKeyPriv.syntax,
                                                       securityEngineID)
        elif usmUserPrivProtocol.syntax == nopriv.NoPriv.serviceID:
            localPrivKey = None
        else:
            raise error.StatusInformation(
                errorIndication='unsupportedPrivProtocol')
        if localPrivKey is not None:
            pysnmpUsmKeyPrivLocalized.syntax = pysnmpUsmKeyPrivLocalized.syntax.clone(
                localPrivKey)
        return (
            usmUserSecurityName.syntax,  # XXX function needed?
            usmUserAuthProtocol.syntax,
            pysnmpUsmKeyAuthLocalized.syntax,
            usmUserPrivProtocol.syntax,
            pysnmpUsmKeyPrivLocalized.syntax)

    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._cachePop(securityStateReference)
            usmUserName = cachedSecurityData['msgUserName']
            usmUserAuthProtocol = cachedSecurityData.get('usmUserAuthProtocol')
            usmUserAuthKeyLocalized = cachedSecurityData.get(
                'usmUserAuthKeyLocalized')
            usmUserPrivProtocol = cachedSecurityData.get('usmUserPrivProtocol')
            usmUserPrivKeyLocalized = cachedSecurityData.get(
                'usmUserPrivKeyLocalized')
            securityEngineID = snmpEngineID
            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: user info read from cache')
        elif securityName:
            # 3.1.1b
            try:
                (usmUserName, usmUserAuthProtocol, usmUserAuthKeyLocalized,
                 usmUserPrivProtocol,
                 usmUserPrivKeyLocalized) = self.__getUserInfo(
                     snmpEngine.msgAndPduDsp.mibInstrumController,
                     securityEngineID, securityName)
                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, usmUserAuthProtocol,
                         usmUserAuthKeyLocalized, usmUserPrivProtocol,
                         usmUserPrivKeyLocalized) = self.__cloneUserInfo(
                             snmpEngine.msgAndPduDsp.mibInstrumController,
                             securityEngineID, securityName)
                    except NoSuchInstanceError:
                        __reportUnknownName = 1

                if __reportUnknownName:
                    raise error.StatusInformation(
                        errorIndication='unknownSecurityName')
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: clone user info')
        else:
            # empty username used for engineID discovery
            usmUserName = usmUserSecurityName = ''
            usmUserAuthProtocol = usmUserAuthKeyLocalized = None
            usmUserPrivProtocol = usmUserPrivKeyLocalized = None
            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: use empty USM data')

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

        msg = globalData

        # 3.1.2
        if securityLevel == 3:
            if not usmUserAuthProtocol or not usmUserPrivProtocol:
                raise error.StatusInformation(
                    errorIndication='unsupportedSecurityLevel')

        # 3.1.3
        if securityLevel == 3 or securityLevel == 2:
            if not usmUserAuthProtocol:
                raise error.StatusInformation(
                    errorIndication='unsupportedSecurityLevel')

        securityParameters = UsmSecurityParameters()

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

        # 3.1.6a
        if securityStateReference is None and (  # request type check added
                securityLevel == 3 or securityLevel == 2):
            if self.__timeline.has_key(securityEngineID):
                (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 %s'
                    % 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 %s'
            % (snmpEngineBoots, snmpEngineTime, securityEngineID))

        # 3.1.4a
        if securityLevel == 3:
            privHandler = self.privServices.get(usmUserPrivProtocol)
            if privHandler is None:
                raise error.StatusInformation(
                    errorIndication='encryptionError')
            dataToEncrypt = encoder.encode(scopedPDU)

            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: scopedPDU encoded')

            try:
                (encryptedData, privParameters) = privHandler.encryptData(
                    usmUserPrivKeyLocalized,
                    (snmpEngineBoots, snmpEngineTime, None), dataToEncrypt)
            except error.StatusInformation, statusInformation:
                raise

            securityParameters.setComponentByPosition(5, privParameters)
            scopedPDUData.setComponentByPosition(1, encryptedData)

            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: scopedPDU ciphered')

        # 3.1.4b
        elif securityLevel == 1 or securityLevel == 2:
            securityParameters.setComponentByPosition(5, '')
Example #6
0
class SnmpUSMSecurityModel(AbstractSecurityModel):
    securityModelID = 3
    authServices = {
        hmacmd5.HmacMd5.serviceID: hmacmd5.HmacMd5(),
        hmacsha.HmacSha.serviceID: hmacsha.HmacSha(),
        noauth.NoAuth.serviceID: noauth.NoAuth()
    }
    privServices = {
        des.Des.serviceID: des.Des(),
        aes.Aes.serviceID: aes.Aes(),
        nopriv.NoPriv.serviceID: nopriv.NoPriv()
    }
    _securityParametersSpec = UsmSecurityParameters()

    def __init__(self):
        AbstractSecurityModel.__init__(self)
        self.__timeline = {}
        self.__timelineExpQueue = {}
        self.__expirationTimer = 0

    def __getUserInfo(self, mibInstrumController, securityEngineID,
                      securityName):
        usmUserEntry, = mibInstrumController.mibBuilder.importSymbols(
            'SNMP-USER-BASED-SM-MIB', 'usmUserEntry')
        tblIdx = usmUserEntry.getInstIdFromIndices(securityEngineID,
                                                   securityName)
        # Get protocols
        usmUserSecurityName = usmUserEntry.getNode(usmUserEntry.name + (3, ) +
                                                   tblIdx).syntax
        usmUserAuthProtocol = usmUserEntry.getNode(usmUserEntry.name + (5, ) +
                                                   tblIdx).syntax
        usmUserPrivProtocol = usmUserEntry.getNode(usmUserEntry.name + (8, ) +
                                                   tblIdx).syntax
        # Get keys
        pysnmpUsmKeyEntry, = mibInstrumController.mibBuilder.importSymbols(
            'PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry')
        pysnmpUsmKeyAuthLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (1, ) + tblIdx).syntax
        pysnmpUsmKeyPrivLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (2, ) + tblIdx).syntax
        return (
            usmUserSecurityName,  # XXX function needed?
            usmUserAuthProtocol,
            pysnmpUsmKeyAuthLocalized,
            usmUserPrivProtocol,
            pysnmpUsmKeyPrivLocalized)

    def __cloneUserInfo(self, mibInstrumController, securityEngineID,
                        securityName):
        snmpEngineID, = mibInstrumController.mibBuilder.importSymbols(
            '__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
        # Proto entry
        usmUserEntry, = mibInstrumController.mibBuilder.importSymbols(
            'SNMP-USER-BASED-SM-MIB', 'usmUserEntry')
        tblIdx = usmUserEntry.getInstIdFromIndices(snmpEngineID.syntax,
                                                   securityName)
        # Get proto protocols
        usmUserSecurityName = usmUserEntry.getNode(usmUserEntry.name + (3, ) +
                                                   tblIdx)
        usmUserAuthProtocol = usmUserEntry.getNode(usmUserEntry.name + (5, ) +
                                                   tblIdx)
        usmUserPrivProtocol = usmUserEntry.getNode(usmUserEntry.name + (8, ) +
                                                   tblIdx)
        # Get proto keys
        pysnmpUsmKeyEntry, = mibInstrumController.mibBuilder.importSymbols(
            'PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry')
        pysnmpUsmKeyAuth = pysnmpUsmKeyEntry.getNode(pysnmpUsmKeyEntry.name +
                                                     (3, ) + tblIdx)
        pysnmpUsmKeyPriv = pysnmpUsmKeyEntry.getNode(pysnmpUsmKeyEntry.name +
                                                     (4, ) + tblIdx)

        # Create new row from proto values

        tblIdx = usmUserEntry.getInstIdFromIndices(securityEngineID,
                                                   securityName)
        # New row
        mibInstrumController.writeVars(
            ((usmUserEntry.name + (13, ) + tblIdx, 4), ))
        # Set protocols
        usmUserEntry.getNode(usmUserEntry.name + (3, ) +
                             tblIdx).syntax = usmUserSecurityName.syntax
        usmUserEntry.getNode(usmUserEntry.name + (5, ) +
                             tblIdx).syntax = usmUserAuthProtocol.syntax
        usmUserEntry.getNode(usmUserEntry.name + (8, ) +
                             tblIdx).syntax = usmUserPrivProtocol.syntax

        # Localize and set keys
        pysnmpUsmKeyEntry, = mibInstrumController.mibBuilder.importSymbols(
            'PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry')
        pysnmpUsmKeyAuthLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (1, ) + tblIdx)
        if usmUserAuthProtocol.syntax == hmacsha.HmacSha.serviceID:
            localAuthKey = localkey.localizeKeySHA(pysnmpUsmKeyAuth.syntax,
                                                   securityEngineID)
        elif usmUserAuthProtocol.syntax == hmacmd5.HmacMd5.serviceID:
            localAuthKey = localkey.localizeKeyMD5(pysnmpUsmKeyAuth.syntax,
                                                   securityEngineID)
        elif usmUserAuthProtocol.syntax == noauth.NoAuth.serviceID:
            localAuthKey = None
        else:
            raise error.StatusInformation(
                errorIndication='unsupportedAuthProtocol')
        if localAuthKey is not None:
            pysnmpUsmKeyAuthLocalized.syntax = pysnmpUsmKeyAuthLocalized.syntax.clone(
                localAuthKey)
        pysnmpUsmKeyPrivLocalized = pysnmpUsmKeyEntry.getNode(
            pysnmpUsmKeyEntry.name + (2, ) + tblIdx)
        if usmUserPrivProtocol.syntax == des.Des.serviceID or \
           usmUserPrivProtocol.syntax == aes.Aes.serviceID:
            if usmUserAuthProtocol.syntax == hmacsha.HmacSha.serviceID:
                localPrivKey = localkey.localizeKeySHA(pysnmpUsmKeyPriv.syntax,
                                                       securityEngineID)
            else:
                localPrivKey = localkey.localizeKeyMD5(pysnmpUsmKeyPriv.syntax,
                                                       securityEngineID)
        elif usmUserPrivProtocol.syntax == nopriv.NoPriv.serviceID:
            localPrivKey = None
        else:
            raise error.StatusInformation(
                errorIndication='unsupportedPrivProtocol')
        if localPrivKey is not None:
            pysnmpUsmKeyPrivLocalized.syntax = pysnmpUsmKeyPrivLocalized.syntax.clone(
                localPrivKey)
        return (
            usmUserSecurityName.syntax,  # XXX function needed?
            usmUserAuthProtocol.syntax,
            pysnmpUsmKeyAuthLocalized.syntax,
            usmUserPrivProtocol.syntax,
            pysnmpUsmKeyPrivLocalized.syntax)

    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._cachePop(securityStateReference)
            usmUserName = cachedSecurityData['msgUserName']
            usmUserAuthProtocol = cachedSecurityData.get('usmUserAuthProtocol')
            usmUserAuthKeyLocalized = cachedSecurityData.get(
                'usmUserAuthKeyLocalized')
            usmUserPrivProtocol = cachedSecurityData.get('usmUserPrivProtocol')
            usmUserPrivKeyLocalized = cachedSecurityData.get(
                'usmUserPrivKeyLocalized')
            securityEngineID = snmpEngineID
            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: user info read from cache')
        elif securityName:
            # 3.1.1b
            try:
                (usmUserName, usmUserAuthProtocol, usmUserAuthKeyLocalized,
                 usmUserPrivProtocol,
                 usmUserPrivKeyLocalized) = self.__getUserInfo(
                     snmpEngine.msgAndPduDsp.mibInstrumController,
                     securityEngineID, securityName)
                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, usmUserAuthProtocol,
                         usmUserAuthKeyLocalized, usmUserPrivProtocol,
                         usmUserPrivKeyLocalized) = self.__cloneUserInfo(
                             snmpEngine.msgAndPduDsp.mibInstrumController,
                             securityEngineID, securityName)
                    except NoSuchInstanceError:
                        __reportUnknownName = 1

                if __reportUnknownName:
                    raise error.StatusInformation(
                        errorIndication='unknownSecurityName')
                debug.logger & debug.flagSM and debug.logger(
                    '__generateRequestOrResponseMsg: clone user info')
        else:
            # empty username used for engineID discovery
            usmUserName = usmUserSecurityName = ''
            usmUserAuthProtocol = usmUserAuthKeyLocalized = None
            usmUserPrivProtocol = usmUserPrivKeyLocalized = None
            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: use empty USM data')

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

        msg = globalData

        # 3.1.2
        if securityLevel == 3:
            if not usmUserAuthProtocol or not usmUserPrivProtocol:
                raise error.StatusInformation(
                    errorIndication='unsupportedSecurityLevel')

        # 3.1.3
        if securityLevel == 3 or securityLevel == 2:
            if not usmUserAuthProtocol:
                raise error.StatusInformation(
                    errorIndication='unsupportedSecurityLevel')

        securityParameters = UsmSecurityParameters()

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

        # 3.1.6a
        if securityStateReference is None and (  # request type check added
                securityLevel == 3 or securityLevel == 2):
            if self.__timeline.has_key(securityEngineID):
                (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 %s'
                    % 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 %s'
            % (snmpEngineBoots, snmpEngineTime, securityEngineID))

        # 3.1.4a
        if securityLevel == 3:
            privHandler = self.privServices.get(usmUserPrivProtocol)
            if privHandler is None:
                raise error.StatusInformation(
                    errorIndication='encryptionError')
            dataToEncrypt = encoder.encode(scopedPDU)

            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: scopedPDU encoded')

            try:
                (encryptedData, privParameters) = privHandler.encryptData(
                    usmUserPrivKeyLocalized,
                    (snmpEngineBoots, snmpEngineTime, None), dataToEncrypt)
            except error.StatusInformation as statusInformation:
                raise

            securityParameters.setComponentByPosition(5, privParameters)
            scopedPDUData.setComponentByPosition(1, encryptedData)

            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: scopedPDU ciphered')

        # 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)
        securityParameters.setComponentByPosition(1, snmpEngineBoots)
        securityParameters.setComponentByPosition(2, snmpEngineTime)

        # 3.1.7
        securityParameters.setComponentByPosition(3, usmUserName)

        # 3.1.8a
        if securityLevel == 3 or securityLevel == 2:
            authHandler = self.authServices.get(usmUserAuthProtocol)
            if authHandler is None:
                raise error.StatusInformation(
                    errorIndication='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(), ))

            msg.setComponentByPosition(2, encoder.encode(securityParameters))

            wholeMsg = encoder.encode(msg)

            try:
                authenticatedWholeMsg = authHandler.authenticateOutgoingMsg(
                    usmUserAuthKeyLocalized, wholeMsg)
            except error.StatusInformation as statusInformation:
                raise

            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: auth outgoing msg')
        # 3.1.8b
        else:
            securityParameters.setComponentByPosition(4, '')
            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: %s' %
                (securityParameters.prettyPrint(), ))
            msg.setComponentByPosition(2, encoder.encode(securityParameters))
            authenticatedWholeMsg = encoder.encode(msg)
            debug.logger & debug.flagSM and debug.logger(
                '__generateRequestOrResponseMsg: plain outgoing msg')

        # 3.1.9
        return (msg.getComponentByPosition(2), authenticatedWholeMsg)

    def generateRequestMsg(
        self,
        snmpEngine,
        messageProcessingModel,
        globalData,
        maxMessageSize,
        securityModel,
        securityEngineID,
        securityName,
        securityLevel,
        scopedPDU,
    ):
        return self.__generateRequestOrResponseMsg(
            snmpEngine, messageProcessingModel, globalData, maxMessageSize,
            securityModel, securityEngineID, securityName, securityLevel,
            scopedPDU, None)

    def generateResponseMsg(self, snmpEngine, messageProcessingModel,
                            globalData, maxMessageSize, securityModel,
                            securityEngineID, securityName, securityLevel,
                            scopedPDU, securityStateReference):
        return self.__generateRequestOrResponseMsg(
            snmpEngine, messageProcessingModel, globalData, maxMessageSize,
            securityModel, securityEngineID, securityName, securityLevel,
            scopedPDU, securityStateReference)

    # 3.2
    def processIncomingMsg(
            self,
            snmpEngine,
            messageProcessingModel,
            maxMessageSize,
            securityParameters,
            securityModel,
            securityLevel,
            wholeMsg,
            msg  # XXX 
    ):
        # 3.2.1
        try:
            securityParameters, rest = decoder.decode(
                securityParameters, asn1Spec=self._securityParametersSpec)
        except PyAsn1Error:
            snmpInASNParseErrs, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                '__SNMPv2-MIB', 'snmpInASNParseErrs')
            snmpInASNParseErrs.syntax = snmpInASNParseErrs.syntax + 1
            raise error.StatusInformation(errorIndication='parseError')

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

        # 3.2.9 -- moved up here to be able to report
        # maxSizeResponseScopedPDU on error
        maxSizeResponseScopedPDU = maxMessageSize - 512  # XXX
        if maxSizeResponseScopedPDU < 0:
            maxSizeResponseScopedPDU = 0

        # 3.2.2
        securityEngineID = securityParameters.getComponentByPosition(0)
        securityStateReference = self._cachePush(
            msgUserName=securityParameters.getComponentByPosition(3))

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

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

        # 3.2.3
        if not self.__timeline.has_key(securityEngineID):
            debug.logger & debug.flagSM and debug.logger(
                'processIncomingMsg: unknown securityEngineID %s' %
                securityEngineID)
            if securityEngineID:
                # 3.2.3a XXX any other way to get auth engine in cache?
                self.__timeline[securityEngineID] = (
                    securityParameters.getComponentByPosition(1),
                    securityParameters.getComponentByPosition(2),
                    securityParameters.getComponentByPosition(2),
                    int(time.time()))

                expireAt = self.__expirationTimer + 300
                if not self.__timelineExpQueue.has_key(expireAt):
                    self.__timelineExpQueue[expireAt] = []
                self.__timelineExpQueue[expireAt].append(securityEngineID)

                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: store timeline for securityEngineID %s'
                    % (securityEngineID, ))
            else:
                # 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 securityEngineID')
                pysnmpUsmDiscoverable, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__PYSNMP-USM-MIB', 'pysnmpUsmDiscoverable')
                if pysnmpUsmDiscoverable.syntax:
                    debug.logger & debug.flagSM and debug.logger(
                        'processIncomingMsg: request EngineID discovery')
                    raise error.StatusInformation(
                        errorIndication='unknownEngineID',
                        oid=usmStatsUnknownEngineIDs.name,
                        val=usmStatsUnknownEngineIDs.syntax,
                        securityStateReference=securityStateReference,
                        contextEngineId=contextEngineId,
                        contextName=contextName,
                        maxSizeResponseScopedPDU=maxSizeResponseScopedPDU)
                else:
                    debug.logger & debug.flagSM and debug.logger(
                        'processIncomingMsg: will not discover EngineID')
                    # free securityStateReference XXX
                    raise error.StatusInformation(
                        errorIndication='unknownEngineID')

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

        msgAuthoritativeEngineID = securityParameters.getComponentByPosition(0)
        msgUserName = securityParameters.getComponentByPosition(3)

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

        if msgUserName:
            # 3.2.4
            try:
                (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:
                        (usmUserSecurityName, usmUserAuthProtocol,
                         usmUserAuthKeyLocalized, usmUserPrivProtocol,
                         usmUserPrivKeyLocalized) = self.__cloneUserInfo(
                             snmpEngine.msgAndPduDsp.mibInstrumController,
                             securityEngineID, 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 %s msgUserName %s'
                    % (securityEngineID, msgUserName))
                if __reportUnknownName:
                    usmStatsUnknownUserNames, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                        '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownUserNames')
                    usmStatsUnknownUserNames.syntax = usmStatsUnknownUserNames.syntax + 1
                    raise error.StatusInformation(
                        errorIndication='unknownSecurityName',
                        oid=usmStatsUnknownUserNames.name,
                        val=usmStatsUnknownUserNames.syntax,
                        securityStateReference=securityStateReference,
                        contextEngineId=contextEngineId,
                        contextName=contextName,
                        maxSizeResponseScopedPDU=maxSizeResponseScopedPDU)
        else:
            # empty username used for engineID discovery
            usmUserName = usmUserSecurityName = ''
            usmUserAuthProtocol = usmUserAuthKeyLocalized = None
            usmUserPrivProtocol = usmUserPrivKeyLocalized = None

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

        # 3.2.5
        __reportError = 0
        if securityLevel == 3:
            if not usmUserAuthProtocol or not usmUserPrivProtocol:
                __reportError = 1
            elif securityLevel == 2:
                if not usmUserAuthProtocol:
                    __reportError = 1
        if __reportError:
            usmStatsUnsupportedSecLevels, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnsupportedSecLevels')
            usmStatsUnsupportedSecLevels.syntax = usmStatsUnsupportedSecLevels.syntax + 1
            raise error.StatusInformation(
                errorIndication='unsupportedSecurityLevel',
                oid=usmStatsUnknownEngineIDs.name,
                val=usmStatsUnknownEngineIDs.syntax,
                securityStateReference=securityStateReference,
                contextEngineId=contextEngineId,
                contextName=contextName,
                maxSizeResponseScopedPDU=maxSizeResponseScopedPDU)

        # 3.2.6
        if securityLevel == 3 or securityLevel == 2:
            authHandler = self.authServices.get(usmUserAuthProtocol)
            if authHandler is None:
                raise error.StatusInformation(
                    errorIndication='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='authenticationFailure',
                    oid=usmStatsWrongDigests.name,
                    val=usmStatsWrongDigests.syntax,
                    securityStateReference=securityStateReference,
                    contextEngineId=contextEngineId,
                    contextName=contextName,
                    maxSizeResponseScopedPDU=maxSizeResponseScopedPDU)

            debug.logger & debug.flagSM and debug.logger(
                'processIncomingMsg: incoming msg authed')
        # 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 self.__timeline.has_key(securityEngineID):
                    (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 %s, idle time %s secs'
                        % (snmpEngineBoots, snmpEngineTime,
                           msgAuthoritativeEngineID, idleTime))
                else:
                    raise error.ProtocolError('Peer SNMP engine info missing')

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

            # 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='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()))
                    debug.logger & debug.flagSM and debug.logger(
                        'processIncomingMsg: stored timeline msgAuthoritativeEngineBoots %s msgAuthoritativeEngineTime %s for msgAuthoritativeEngineID %s'
                        %
                        (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='notInTimeWindow')

        scopedPduData = msg.getComponentByPosition(3)

        # 3.2.8a
        if securityLevel == 3:
            privHandler = self.privServices.get(usmUserPrivProtocol)
            if privHandler is None:
                raise error.StatusInformation(
                    errorIndication='decryptionError')
            encryptedPDU = scopedPduData.getComponentByPosition(1)
            if encryptedPDU is None:  # no ciphertext
                raise error.StatusInformation(
                    errorIndication='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')
            except error.StatusInformation:
                usmStatsDecryptionErrors, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                    '__SNMP-USER-BASED-SM-MIB', 'usmStatsDecryptionErrors')
                usmStatsDecryptionErrors.syntax = usmStatsDecryptionErrors.syntax + 1
                raise error.StatusInformation(
                    errorIndication='decryptionError',
                    oid=usmStatsDecryptionErrors.name,
                    val=usmStatsDecryptionErrors.syntax,
                    securityStateReference=securityStateReference,
                    contextEngineId=contextEngineId,
                    contextName=contextName,
                    maxSizeResponseScopedPDU=maxSizeResponseScopedPDU)
            scopedPduSpec = scopedPduData.setComponentByPosition(
                0).getComponentByPosition(0)
            try:
                scopedPDU, rest = decoder.decode(decryptedData,
                                                 asn1Spec=scopedPduSpec)
            except PyAsn1Error as why:
                debug.logger & debug.flagSM and debug.logger(
                    'processIncomingMsg: PDU decoder failed %s' % why)
                raise error.StatusInformation(
                    errorIndication='decryptionError')
        else:
            # 3.2.8b
            scopedPDU = scopedPduData.getComponentByPosition(0)
            if scopedPDU is None:  # no plaintext
                raise error.StatusInformation(
                    errorIndication='decryptionError')

        # 3.2.10
        securityName = usmUserSecurityName

        # 3.2.11
        self._cachePop(securityStateReference)
        securityStateReference = self._cachePush(
            msgUserName=securityParameters.getComponentByPosition(3),
            usmUserAuthProtocol=usmUserAuthProtocol,
            usmUserAuthKeyLocalized=usmUserAuthKeyLocalized,
            usmUserPrivProtocol=usmUserPrivProtocol,
            usmUserPrivKeyLocalized=usmUserPrivKeyLocalized)

        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 securityEngineID:
            usmStatsUnknownUserNames, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                '__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownUserNames')
            usmStatsUnknownUserNames.syntax = usmStatsUnknownUserNames.syntax + 1
            raise error.StatusInformation(
                errorIndication='unknownSecurityName',
                oid=usmStatsUnknownUserNames.name,
                val=usmStatsUnknownUserNames.syntax,
                securityStateReference=securityStateReference,
                securityEngineID=securityEngineID,
                contextEngineId=contextEngineId,
                contextName=contextName,
                maxSizeResponseScopedPDU=maxSizeResponseScopedPDU,
                PDU=scopedPDU)

        # 3.2.12
        return (securityEngineID, securityName, scopedPDU,
                maxSizeResponseScopedPDU, securityStateReference)

    def __expireTimelineInfo(self):
        if self.__timelineExpQueue.has_key(self.__expirationTimer):
            for engineIdKey in self.__timelineExpQueue[self.__expirationTimer]:
                del self.__timeline[engineIdKey]
                debug.logger & debug.flagMP and debug.logger(
                    '__expireEnginesInfo: expiring %s' % (engineIdKey, ))
            del self.__timelineExpQueue[self.__expirationTimer]
        self.__expirationTimer = self.__expirationTimer + 1

    def receiveTimerTick(self, snmpEngine, timeNow):
        self.__expireTimelineInfo()