Example #1
0
 def prettyIn(self, bits):
     if type(bits) not in (types.TupleType, types.ListType):
         return str(bits) # raw bitstring
     octets = []
     for bit in bits: # tuple of named bits
         v = self.__namedValues.getValue(bit)
         if v is None:
             raise error.ProtocolError(
                 'Unknown named bit %s' % bit
                 )
         d, m = divmod(v, 8)
         if d >= len(octets):
             octets.extend([0] * (d - len(octets) + 1))
         octets[d] = octets[d] | 0x01 << (7-m)
     return string.join(map(lambda x: chr(x), octets))
Example #2
0
    def popByStateRef(self, stateReference):
        if stateReference in self.__stateReferenceIndex:
            cacheInfo = self.__stateReferenceIndex[stateReference]

        else:
            raise error.ProtocolError('Cache miss for stateReference=%s at '
                                      '%s' % (stateReference, self))

        del self.__stateReferenceIndex[stateReference]

        cacheEntry, expireAt = cacheInfo

        del self.__expirationQueue[expireAt]['stateReference'][stateReference]

        return cacheEntry
Example #3
0
    def hashPassphrase(self, authProtocol, privKey):
        if authProtocol == hmacmd5.HmacMd5.SERVICE_ID:
            hashAlgo = md5

        elif authProtocol == hmacsha.HmacSha.SERVICE_ID:
            hashAlgo = sha1

        elif authProtocol in hmacsha2.HmacSha2.HASH_ALGORITHM:
            hashAlgo = hmacsha2.HmacSha2.HASH_ALGORITHM[authProtocol]

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

        return localkey.hashPassphrase(privKey, hashAlgo)
Example #4
0
 def localizeKey(self, authProtocol, privKey, snmpEngineID):
     if authProtocol == hmacmd5.HmacMd5.serviceID:
         localPrivKey = localkey.localizeKeyMD5(privKey, snmpEngineID)
         while ceil(self.keySize // len(localPrivKey)):
             # noinspection PyDeprecation,PyCallingNonCallable
             localPrivKey = localPrivKey + md5(localPrivKey).digest()
     elif authProtocol == hmacsha.HmacSha.serviceID:
         localPrivKey = localkey.localizeKeySHA(privKey, snmpEngineID)
         while ceil(self.keySize // len(localPrivKey)):
             localPrivKey = localPrivKey + sha1(localPrivKey).digest()
     else:
         raise error.ProtocolError(
             'Unknown auth protocol %s' % (authProtocol,)
         )
     return localPrivKey[:self.keySize]
Example #5
0
    def pushByMsgId(self, msgId, **msgInfo):
        if msgId in self.__msgIdIndex:
            raise error.ProtocolError('Cache dup for msgId=%s at %s' %
                                      (msgId, self))
        expireAt = self.__expirationTimer + 600
        self.__msgIdIndex[msgId] = msgInfo, expireAt

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

        # Schedule to expire
        if expireAt not in self.__expirationQueue:
            self.__expirationQueue[expireAt] = {}
        if 'msgId' not in self.__expirationQueue[expireAt]:
            self.__expirationQueue[expireAt]['msgId'] = {}
        self.__expirationQueue[expireAt]['msgId'][msgId] = 1
Example #6
0
 def prettyIn(self, bits):
     if not isinstance(bits, (tuple, list)):
         return OctetString.prettyIn(self, bits)  # raw bitstring
     _octets = []
     for bit in bits:  # tuple of named bits
         v = self.__namedValues.getValue(bit)
         if v is None:
             raise error.ProtocolError(
                 'Unknown named bit %s' % bit
             )
         d, m = divmod(v, 8)
         if d >= len(_octets):
             _octets.extend([0] * (d - len(_octets) + 1))
         _octets[d] |= 0x01 << (7 - m)
     return OctetString.prettyIn(self, _octets)
Example #7
0
    def authenticateIncomingMsg(self, authKey, authParameters, wholeMsg):
        # 6.3.2.1 & 2
        if len(authParameters) != 12:
            raise error.StatusInformation(
                errorIndication=errind.authenticationError)

        # 6.3.2.3
        ln = wholeMsg.find(authParameters.asOctets())
        if ln == -1:
            raise error.ProtocolError('Cant locate digest in wholeMsg')

        wholeHead = wholeMsg[:ln]
        wholeTail = wholeMsg[ln + 12:]

        authenticatedWholeMsg = wholeHead + TWELVE_ZEROS + wholeTail

        # 6.3.2.4a
        extendedAuthKey = authKey.asNumbers() + FORTY_EIGHT_ZEROS

        # 6.3.2.4b --> no-op

        # 6.3.2.4c
        k1 = univ.OctetString(
            map(lambda x, y: x ^ y, extendedAuthKey, self.IPAD))

        # 6.3.2.4d --> no-op

        # 6.3.2.4e
        k2 = univ.OctetString(
            map(lambda x, y: x ^ y, extendedAuthKey, self.OPAD))

        # 6.3.2.5a
        # noinspection PyDeprecation,PyCallingNonCallable
        d1 = md5(k1.asOctets() + authenticatedWholeMsg).digest()

        # 6.3.2.5b
        # noinspection PyDeprecation,PyCallingNonCallable
        d2 = md5(k2.asOctets() + d1).digest()

        # 6.3.2.5c
        mac = d2[:12]

        # 6.3.2.6
        if mac != authParameters:
            raise error.StatusInformation(
                errorIndication=errind.authenticationFailure)

        return authenticatedWholeMsg
Example #8
0
    def authenticateIncomingMsg(self, authKey, authParameters, wholeMsg):
        # 7.3.2.1 & 2
        if len(authParameters) != 12:
            raise error.StatusInformation(
                errorIndication=errind.authenticationError
            )

        # 7.3.2.3
        l = wholeMsg.find(authParameters.asOctets())
        if l == -1:
            raise error.ProtocolError('Cant locate digest in wholeMsg')
        wholeHead = wholeMsg[:l]
        wholeTail = wholeMsg[l + 12:]
        authenticatedWholeMsg = wholeHead + _twelveZeros + wholeTail

        # 7.3.2.4a
        extendedAuthKey = authKey.asNumbers() + _fortyFourZeros

        # 7.3.2.4b --> noop

        # 7.3.2.4c
        k1 = univ.OctetString(
            map(lambda x, y: x ^ y, extendedAuthKey, self.__ipad)
        )

        # 7.3.2.4d --> noop

        # 7.3.2.4e
        k2 = univ.OctetString(
            map(lambda x, y: x ^ y, extendedAuthKey, self.__opad)
        )

        # 7.3.2.5a
        d1 = sha1(k1.asOctets() + authenticatedWholeMsg).digest()

        # 7.3.2.5b
        d2 = sha1(k2.asOctets() + d1).digest()

        # 7.3.2.5c
        mac = d2[:12]

        # 7.3.2.6
        if mac != authParameters:
            raise error.StatusInformation(
                errorIndication=errind.authenticationFailure
            )

        return authenticatedWholeMsg
Example #9
0
 def localizeKey(self, authProtocol, privKey, snmpEngineID):
     if authProtocol == hmacmd5.HmacMd5.serviceID:
         localPrivKey = localkey.localizeKeyMD5(privKey, snmpEngineID)
         # now extend this key if too short by repeating steps that includes the hashPassphrase step
         while len(localPrivKey) < self.keySize:
             newKey = localkey.hashPassphraseMD5(localPrivKey)
             localPrivKey += localkey.localizeKeyMD5(newKey, snmpEngineID)
     elif authProtocol == hmacsha.HmacSha.serviceID:
         localPrivKey = localkey.localizeKeySHA(privKey, snmpEngineID)
         while len(localPrivKey) < self.keySize:
             newKey = localkey.hashPassphraseSHA(localPrivKey)
             localPrivKey += localkey.localizeKeySHA(newKey, snmpEngineID)
     else:
         raise error.ProtocolError('Unknown auth protocol %s' %
                                   (authProtocol, ))
     return localPrivKey[:self.keySize]
Example #10
0
 def localizeKey(self, authProtocol, privKey, snmpEngineID):
     if authProtocol == hmacmd5.HmacMd5.serviceID:
         localPrivKey = localkey.localizeKeyMD5(privKey, snmpEngineID)
         localPrivKey = localPrivKey + localkey.localizeKeyMD5(
             localPrivKey, snmpEngineID
             )
     elif authProtocol == hmacsha.HmacSha.serviceID:
         localPrivKey = localkey.localizeKeySHA(privKey, snmpEngineID)
         localPrivKey = localPrivKey + localkey.localizeKeySHA(
             localPrivKey, snmpEngineID
             )
     else:
         raise error.ProtocolError(
             'Unknown auth protocol %s' % (authProtocol,)
             )
     return localPrivKey[:32]
Example #11
0
 def localizeKey(self, authProtocol, privKey, snmpEngineID):
     if authProtocol == hmacmd5.HmacMd5.serviceID:
         localPrivKey = localkey.localizeKeyMD5(privKey, snmpEngineID)
         for count in range(1, int(ceil(self.keySize * 1.0 / len(localPrivKey)))):
             # noinspection PyDeprecation,PyCallingNonCallable
             localPrivKey += md5(localPrivKey).digest()
     elif authProtocol == hmacsha.HmacSha.serviceID:
         localPrivKey = localkey.localizeKeySHA(privKey, snmpEngineID)
         # RFC mentions this algo generates 480bit key, but only up to 256 bits are used
         for count in range(1, int(ceil(self.keySize * 1.0 / len(localPrivKey)))):
             localPrivKey += sha1(localPrivKey).digest()
     else:
         raise error.ProtocolError(
             'Unknown auth protocol %s' % (authProtocol,)
         )
     return localPrivKey[:self.keySize]
Example #12
0
    def _cachePushByMsgId(self, msgId, **msgInfo):
        if self.__msgIdIndex.has_key(msgId):
            raise error.ProtocolError('Cache dup for msgId=%s at %s' %
                                      (msgId, self))
        expireAt = self.__expirationTimer + 50
        self.__msgIdIndex[msgId] = (msgInfo, expireAt)

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

        # Schedule to expire
        if not self.__expirationQueue.has_key(expireAt):
            self.__expirationQueue[expireAt] = {}
        if not self.__expirationQueue[expireAt].has_key('msgId'):
            self.__expirationQueue[expireAt]['msgId'] = {}
        self.__expirationQueue[expireAt]['msgId'][msgId] = 1
        self.__expireCaches()
Example #13
0
 def __verifyAccess(self, name, syntax, idx, viewType, acCtx):
     snmpEngine = acCtx
     execCtx = snmpEngine.observer.getExecutionContext(
         'rfc3412.receiveMessage:request')
     (securityModel, securityName, securityLevel, contextName,
      pduType) = (execCtx['securityModel'], execCtx['securityName'],
                  execCtx['securityLevel'], execCtx['contextName'],
                  execCtx['pdu'].getTagSet())
     try:
         snmpEngine.accessControlModel[self.acmID].isAccessAllowed(
             snmpEngine, securityModel, securityName, securityLevel,
             viewType, contextName, name)
     # Map ACM errors onto SMI ones
     except error.StatusInformation:
         statusInformation = sys.exc_info()[1]
         debug.logger & debug.flagApp and debug.logger(
             '__verifyAccess: name %s, statusInformation %s' %
             (name, statusInformation))
         errorIndication = statusInformation['errorIndication']
         # 3.2.5...
         if (errorIndication == errind.noSuchView
                 or errorIndication == errind.noAccessEntry
                 or errorIndication == errind.noGroupName):
             raise pysnmp.smi.error.AuthorizationError(name=name, idx=idx)
         elif errorIndication == errind.otherError:
             raise pysnmp.smi.error.GenError(name=name, idx=idx)
         elif errorIndication == errind.noSuchContext:
             snmpUnknownContexts, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
                 '__SNMP-TARGET-MIB', 'snmpUnknownContexts')
             snmpUnknownContexts.syntax += 1
             # Request REPORT generation
             raise pysnmp.smi.error.GenError(name=name,
                                             idx=idx,
                                             oid=snmpUnknownContexts.name,
                                             val=snmpUnknownContexts.syntax)
         elif errorIndication == errind.notInView:
             return 1
         else:
             raise error.ProtocolError('Unknown ACM error %s' %
                                       errorIndication)
     else:
         # rfc2576: 4.1.2.1
         if (securityModel == 1 and syntax is not None
                 and self._counter64Type == syntax.getTagSet()
                 and self._getNextRequestType == pduType):
             # This will cause MibTree to skip this OID-value
             raise pysnmp.smi.error.NoAccessError(name=name, idx=idx)
Example #14
0
def _sendNotification(self,
                      snmpEngine,
                      notificationTarget,
                      notificationName,
                      additionalVarBinds=(),
                      cbFun=None,
                      cbCtx=None,
                      contextName=null,
                      instanceIndex=None):
    if self.snmpContext is None:
        raise error.ProtocolError('SNMP context not specified')
        
    #
    # Here we first expand trap OID into associated OBJECTS
    # and then look them up at context-specific MIB
    #

    mibViewController = snmpEngine.getUserContext('mibViewController')
    if not mibViewController:
        mibViewController = view.MibViewController(snmpEngine.getMibBuilder())
        snmpEngine.setUserContext(mibViewController=mibViewController)

    # Support the following syntax:
    #   '1.2.3.4'
    #   (1,2,3,4)
    #   ('MIB', 'symbol')
    if isinstance(notificationName, (tuple, list)) and \
            notificationName and isinstance(notificationName[0], str):
        notificationName = rfc1902.ObjectIdentity(*notificationName)
    else:
        notificationName = rfc1902.ObjectIdentity(notificationName)

    varBinds = rfc1902.NotificationType(
        notificationName, instanceIndex=instanceIndex
    ).resolveWithMib(mibViewController)

    mibInstrumController = self.snmpContext.getMibInstrum(contextName)

    varBinds = varBinds[:1] + mibInstrumController.readVars(varBinds[1:])

    return self.sendVarBinds(snmpEngine,
                             notificationTarget,
                             self.snmpContext.contextEngineId,
                             contextName,
                             varBinds + list(additionalVarBinds),
                             _sendNotificationCbFun,
                             (cbFun, cbCtx))
Example #15
0
    def localizeKey(self, authProtocol, privKey, snmpEngineID):
        if authProtocol == hmacmd5.HmacMd5.SERVICE_ID:
            hashAlgo = md5

        elif authProtocol == hmacsha.HmacSha.SERVICE_ID:
            hashAlgo = sha1

        elif authProtocol in hmacsha2.HmacSha2.HASH_ALGORITHM:
            hashAlgo = hmacsha2.HmacSha2.HASH_ALGORITHM[authProtocol]

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

        localPrivKey = localkey.localizeKey(privKey, snmpEngineID, hashAlgo)

        return localPrivKey[:self.KEY_SIZE]
Example #16
0
    def registerContextEngineId(self, contextEngineId, pduTypes, processPdu):
        """Register application with dispatcher"""
        # 4.3.2 -> noop

        # 4.3.3
        for pduType in pduTypes:
            k = (contextEngineId, pduType)
            if k in self.__appsRegistration:
                raise error.ProtocolError(
                    'Duplicate registration %r/%s' % (contextEngineId, pduType)
                )

            # 4.3.4
            self.__appsRegistration[k] = processPdu

        debug.logger & debug.flagDsp and debug.logger(
            'registerContextEngineId: contextEngineId %r pduTypes %s' % (contextEngineId, pduTypes))
Example #17
0
    def pushByStateRef(self, stateReference, **msgInfo):
        if stateReference in self.__stateReferenceIndex:
            raise error.ProtocolError('Cache dup for stateReference=%s at %s' %
                                      (stateReference, self))

        expireAt = self.__expirationTimer + 600

        self.__stateReferenceIndex[stateReference] = msgInfo, expireAt

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

        if 'stateReference' not in self.__expirationQueue[expireAt]:
            self.__expirationQueue[expireAt]['stateReference'] = {}

        self.__expirationQueue[expireAt]['stateReference'][stateReference] = 1
Example #18
0
 def prettyOut(self, value):
     names = []
     octets = tuple(map(None, str(value)))
     i = 0
     while i < len(octets):
         v = ord(octets[i])
         j = 7
         while j >= 0:
             if v & (0x01<<j):
                 name = self.__namedValues.getName(i*8+7-j)
                 if name is None:
                     raise error.ProtocolError(
                         'Unknown named value %s' % v
                         )
                 names.append(name)
             j = j - 1
         i = i + 1
     return string.join(map(lambda x: str(x), names), ', ')
Example #19
0
    def popByMsgId(self, msgId):
        if msgId in self.__msgIdIndex:
            cacheInfo = self.__msgIdIndex[msgId]

        else:
            raise error.ProtocolError('Cache miss for msgId=%s at %s' %
                                      (msgId, self))

        msgInfo, expireAt = cacheInfo

        del self.__sendPduHandleIdx[msgInfo['sendPduHandle']]
        del self.__msgIdIndex[msgId]

        cacheEntry, expireAt = cacheInfo

        del self.__expirationQueue[expireAt]['msgId'][msgId]

        return cacheEntry
Example #20
0
 def prettyOut(self, value):
     names = []
     ints = self.__class__(value).asNumbers()
     i = 0
     while i < len(ints):
         v = ints[i]
         j = 7
         while j >= 0:
             if v & (0x01<<j):
                 name = self.__namedValues.getName(i*8+7-j)
                 if name is None:
                     raise error.ProtocolError(
                         'Unknown named value %s' % v
                         )
                 names.append(name)
             j = j - 1
         i = i + 1
     return ', '.join([ str(x) for x in names ])
Example #21
0
 def localizeKey(self, authProtocol, privKey, snmpEngineID):
     if authProtocol == hmacmd5.HmacMd5.serviceID:
         hashAlgo = md5
     elif authProtocol == hmacsha.HmacSha.serviceID:
         hashAlgo = sha1
     elif authProtocol in hmacsha2.HmacSha2.hashAlgorithms:
         hashAlgo = hmacsha2.HmacSha2.hashAlgorithms[authProtocol]
     else:
         raise error.ProtocolError('Unknown auth protocol %s' %
                                   (authProtocol, ))
     localPrivKey = localkey.localizeKey(privKey, snmpEngineID, hashAlgo)
     # now extend this key if too short by repeating steps that includes the hashPassphrase step
     while len(localPrivKey) < self.keySize:
         # this is the difference between reeder and bluementhal
         newKey = localkey.hashPassphrase(localPrivKey, hashAlgo)
         localPrivKey += localkey.localizeKey(newKey, snmpEngineID,
                                              hashAlgo)
     return localPrivKey[:self.keySize]
Example #22
0
    def authenticateIncomingMsg(self, authKey, authParameters, wholeMsg):
        # 7.3.2.1 & 2
        if len(authParameters) != 12:
            raise error.StatusInformation(
                errorIndication='authenticationError')

        # 7.3.2.3
        l = string.find(wholeMsg, str(authParameters))
        if l == -1:
            raise error.ProtocolError('Cant locate digest in wholeMsg')
        wholeHead = wholeMsg[:l]
        wholeTail = wholeMsg[l + 12:]
        authenticatedWholeMsg = '%s%s%s' % (wholeHead, _twelveZeros, wholeTail)

        # 7.3.2.4a
        extendedAuthKey = map(ord, str(authKey) + _fortyFourZeros)

        # 7.3.2.4b --> noop

        # 7.3.2.4c
        k1 = string.join(
            map(lambda x, y: chr(x ^ y), extendedAuthKey, self.__ipad), '')

        # 7.3.2.4d --> noop

        # 7.3.2.4e
        k2 = string.join(
            map(lambda x, y: chr(x ^ y), extendedAuthKey, self.__opad), '')

        # 7.3.2.5a
        d1 = sha1(k1 + authenticatedWholeMsg).digest()

        # 7.3.2.5b
        d2 = sha1(k2 + d1).digest()

        # 7.3.2.5c
        mac = d2[:12]

        # 7.3.2.6
        if mac != authParameters:
            raise error.StatusInformation(
                errorIndication='authenticationFailure')

        return authenticatedWholeMsg
Example #23
0
    def localizeKey(self, authProtocol, privKey, snmpEngineID):
        if authProtocol == hmacmd5.HmacMd5.serviceID:
            hashAlgo = md5
        elif authProtocol == hmacsha.HmacSha.serviceID:
            hashAlgo = sha1
        elif authProtocol in hmacsha2.HmacSha2.hashAlgorithms:
            hashAlgo = hmacsha2.HmacSha2.hashAlgorithms[authProtocol]
        else:
            raise error.ProtocolError('Unknown auth protocol %s' %
                                      (authProtocol, ))

        localPrivKey = localkey.localizeKey(privKey, snmpEngineID, hashAlgo)

        # now extend this key if too short by repeating steps that includes the hashPassphrase step
        for count in range(1,
                           int(ceil(self.keySize * 1.0 / len(localPrivKey)))):
            localPrivKey += hashAlgo(localPrivKey).digest()

        return localPrivKey[:self.keySize]
Example #24
0
    def authenticateOutgoingMsg(self, authKey, wholeMsg):
        # 7.3.1.1
        location = wholeMsg.find(self.__placeHolder)
        if location == -1:
            raise error.ProtocolError('Can\'t locate digest placeholder')
        wholeHead = wholeMsg[:location]
        wholeTail = wholeMsg[location + self.__digestLength:]

        # 7.3.1.2, 7.3.1.3
        try:
            mac = hmac.new(authKey.asOctets(), wholeMsg, self.__hashAlgo)

        except errind.ErrorIndication:
            raise error.StatusInformation(errorIndication=sys.exc_info()[1])

        # 7.3.1.4
        mac = mac.digest()[:self.__digestLength]

        # 7.3.1.5 & 6
        return wholeHead + mac + wholeTail
Example #25
0
    def authenticateOutgoingMsg(self, authKey, wholeMsg):
        # Here we expect calling secmod to indicate where the digest
        # should be in the substrate. Also, it pre-sets digest placeholder
        # so we hash wholeMsg out of the box.
        # Yes, that's ugly but that's rfc...
        l = wholeMsg.find(_twelveZeros)
        if l == -1:
            raise error.ProtocolError('Cant locate digest placeholder')
        wholeHead = wholeMsg[:l]
        wholeTail = wholeMsg[l + 12:]

        # 6.3.1.1

        # 6.3.1.2a
        extendedAuthKey = authKey.asNumbers() + _fortyEightZeros

        # 6.3.1.2b --> no-op

        # 6.3.1.2c
        k1 = univ.OctetString(
            map(lambda x, y: x ^ y, extendedAuthKey, self.__ipad)
        )

        # 6.3.1.2d --> no-op

        # 6.3.1.2e
        k2 = univ.OctetString(
            map(lambda x, y: x ^ y, extendedAuthKey, self.__opad)
        )

        # 6.3.1.3
        # noinspection PyDeprecation,PyCallingNonCallable
        d1 = md5(k1.asOctets() + wholeMsg).digest()

        # 6.3.1.4
        # noinspection PyDeprecation,PyCallingNonCallable
        d2 = md5(k2.asOctets() + d1).digest()
        mac = d2[:12]

        # 6.3.1.5 & 6
        return wholeHead + mac + wholeTail
Example #26
0
    def processPdu(self, snmpEngine, messageProcessingModel, securityModel,
                   securityName, securityLevel, contextEngineId, contextName,
                   pduVersion, PDU, maxSizeResponseScopedPDU, stateReference):

        # Agent-side API complies with SMIv2
        if messageProcessingModel == 0:
            origPdu = PDU
            PDU = rfc2576.v1ToV2(PDU)
        else:
            origPdu = None

        # 3.2.1
        if (PDU.tagSet not in rfc3411.readClassPDUs
                and PDU.tagSet not in rfc3411.writeClassPDUs):
            raise error.ProtocolError('Unexpected PDU class %s' % PDU.tagSet)

        # 3.2.2 --> no-op

        # 3.2.4
        rspPDU = v2c.apiPDU.getResponse(PDU)

        statusInformation = {}

        self.__pendingReqs[stateReference] = (messageProcessingModel,
                                              securityModel, securityName,
                                              securityLevel, contextEngineId,
                                              contextName, pduVersion, rspPDU,
                                              origPdu,
                                              maxSizeResponseScopedPDU,
                                              statusInformation)

        # 3.2.5
        varBinds = v2c.apiPDU.getVarBinds(PDU)

        debug.logger & debug.flagApp and debug.logger(
            'processPdu: stateReference %s, varBinds %s' %
            (stateReference, varBinds))

        self.initiateMgmtOperation(snmpEngine, stateReference, contextName,
                                   PDU)
Example #27
0
    def authenticateOutgoingMsg(self, authKey, wholeMsg):
        # Here we expect calling secmod to indicate where the digest
        # should be in the substrate. Also, it pre-sets digest placeholder
        # so we hash wholeMsg out of the box.
        # Yes, that's ugly but that's rfc...
        l = string.find(wholeMsg, _twelveZeros)
        if l == -1:
            raise error.ProtocolError('Cant locate digest placeholder')
        wholeHead = wholeMsg[:l]
        wholeTail = wholeMsg[l + 12:]

        # 6.3.1.1

        # 6.3.1.2a
        extendedAuthKey = map(ord, str(authKey) + _fortyEightZeros)

        # 6.3.1.2b --> noop

        # 6.3.1.2c
        k1 = string.join(
            map(lambda x, y: chr(x ^ y), extendedAuthKey, self.__ipad), '')

        # 6.3.1.2d --> noop

        # 6.3.1.2e
        k2 = string.join(
            map(lambda x, y: chr(x ^ y), extendedAuthKey, self.__opad), '')

        # 6.3.1.3
        d1 = md5(k1 + wholeMsg).digest()

        # 6.3.1.4
        d2 = md5(k2 + d1).digest()
        mac = d2[:12]

        # 6.3.1.5 & 6
        return '%s%s%s' % (wholeHead, mac, wholeTail)
Example #28
0
    def authenticateOutgoingMsg(self, authKey, wholeMsg):
        # 7.3.1.1
        # Here we expect calling secmod to indicate where the digest
        # should be in the substrate. Also, it pre-sets digest placeholder
        # so we hash wholeMsg out of the box.
        # Yes, that's ugly but that's rfc...
        ln = wholeMsg.find(TWELVE_ZEROS)
        if ln == -1:
            raise error.ProtocolError('Cant locate digest placeholder')

        wholeHead = wholeMsg[:ln]
        wholeTail = wholeMsg[ln + 12:]

        # 7.3.1.2a
        extendedAuthKey = authKey.asNumbers() + FORTY_FOUR_ZEROS

        # 7.3.1.2b -- no-op

        # 7.3.1.2c
        k1 = univ.OctetString(
            map(lambda x, y: x ^ y, extendedAuthKey, self.IPAD))

        # 7.3.1.2d -- no-op

        # 7.3.1.2e
        k2 = univ.OctetString(
            map(lambda x, y: x ^ y, extendedAuthKey, self.OPAD))

        # 7.3.1.3
        d1 = sha1(k1.asOctets() + wholeMsg).digest()

        # 7.3.1.4
        d2 = sha1(k2.asOctets() + d1).digest()
        mac = d2[:12]

        # 7.3.1.5 & 6
        return wholeHead + mac + wholeTail
Example #29
0
    def sendVarBinds(self,
                     snmpEngine,
                     notificationTarget,
                     contextEngineId,
                     contextName,
                     varBinds=(),
                     cbFun=None,
                     cbCtx=None):
        debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationTarget %s, contextEngineId %s, contextName "%s", varBinds %s' % (notificationTarget, contextEngineId or '<default>', contextName, varBinds))

        if contextName:
            __SnmpAdminString, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('SNMP-FRAMEWORK-MIB', 'SnmpAdminString')
            contextName = __SnmpAdminString(contextName)
 
        # 3.3
        ( notifyTag,
          notifyType ) = config.getNotificationInfo(
                snmpEngine, notificationTarget
            )

        notificationHandle = getNextHandle()

        debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationHandle %s, notifyTag %s, notifyType %s' % (notificationHandle, notifyTag, notifyType))

        varBinds = [  (v2c.ObjectIdentifier(x),y) for x,y in varBinds ]

        # 3.3.2 & 3.3.3
        snmpTrapOID, sysUpTime = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpTrapOID', 'sysUpTime')

        for idx in range(len(varBinds)):
            if idx and varBinds[idx][0] == sysUpTime.getName():
                if varBinds[0][0] == sysUpTime.getName():
                    varBinds[0] = varBinds[idx]
                else:
                    varBinds.insert(0, varBinds[idx])
                    del varBinds[idx]

            if varBinds[0][0] != sysUpTime.getName():
                varBinds.insert(0, (v2c.ObjectIdentifier(sysUpTime.getName()),
                                    sysUpTime.getSyntax().clone()))

        if len(varBinds) < 2 or varBinds[1][0] != snmpTrapOID.getName():
            varBinds.insert(1, (v2c.ObjectIdentifier(snmpTrapOID.getName()),
                                snmpTrapOID.getSyntax()))

        debug.logger & debug.flagApp and debug.logger('sendVarBinds: final varBinds %s' % (varBinds,))

        for targetAddrName in config.getTargetNames(snmpEngine, notifyTag):
            ( transportDomain,
              transportAddress,
              timeout,
              retryCount,
              params ) = config.getTargetAddr(snmpEngine, targetAddrName)
            ( messageProcessingModel,
              securityModel,
              securityName,
              securityLevel ) = config.getTargetParams(snmpEngine, params)

            # 3.3.1 XXX
# XXX filtering's yet to be implemented
#             filterProfileName = config.getNotifyFilterProfile(params)

#             ( filterSubtree,
#               filterMask,
#               filterType ) = config.getNotifyFilter(filterProfileName)

            debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationHandle %s, notifyTag %s yields: transportDomain %s, transportAddress %r, securityModel %s, securityName %s, securityLevel %s' % (notificationHandle, notifyTag, transportDomain, transportAddress, securityModel, securityName, securityLevel))

            for varName, varVal in varBinds:
                if varName in (sysUpTime.name, snmpTrapOID.name):
                    continue
                try:
                    snmpEngine.accessControlModel[self.acmID].isAccessAllowed(
                        snmpEngine, securityModel, securityName,
                        securityLevel, 'notify', contextName, varName
                        )

                    debug.logger & debug.flagApp and debug.logger('sendVarBinds: ACL succeeded for OID %s securityName %s' % (varName, securityName))

                except error.StatusInformation:
                    debug.logger & debug.flagApp and debug.logger('sendVarBinds: ACL denied access for OID %s securityName %s, droppping notification' % (varName, securityName))
                    return

            # 3.3.4
            if notifyType == 1:
                pdu = v2c.SNMPv2TrapPDU()
            elif notifyType == 2:
                pdu = v2c.InformRequestPDU()
            else:
                raise error.ProtocolError('Unknown notify-type %r', notifyType)
            
            v2c.apiPDU.setDefaults(pdu)
            v2c.apiPDU.setVarBinds(pdu, varBinds)

            # 3.3.5
            try:
                sendRequestHandle = self.sendPdu(snmpEngine,
                                                 targetAddrName,
                                                 contextEngineId,
                                                 contextName,
                                                 pdu,
                                                 self.processResponseVarBinds,
                                                 (notificationHandle, 
                                                  cbFun, cbCtx))
                
            except error.StatusInformation:
                statusInformation = sys.exc_info()[1]
                debug.logger & debug.flagApp and debug.logger('sendVarBinds: sendRequestHandle %s: sendPdu() failed with %r' % (sendRequestHandle, statusInformation))
                if notificationHandle not in self.__pendingNotifications or \
                       not self.__pendingNotifications[notificationHandle]:
                    if notificationHandle in self.__pendingNotifications:
                        del self.__pendingNotifications[notificationHandle]
                    cbFun(snmpEngine,
                          notificationHandle,
                          statusInformation['errorIndication'],
                          0, 0, (), cbCtx)
                return notificationHandle

            debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationHandle %s, sendRequestHandle %s, timeout %d' % (notificationHandle, sendRequestHandle, timeout))

            if notifyType == 2:
                if notificationHandle not in self.__pendingNotifications:
                    self.__pendingNotifications[notificationHandle] = set()
                self.__pendingNotifications[notificationHandle].add(sendRequestHandle)

        debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationHandle %s, sendRequestHandle %s, notification(s) sent' % (notificationHandle, sendRequestHandle))

        return notificationHandle
Example #30
0
    def processResponsePdu(self,
                           snmpEngine,
                           messageProcessingModel,
                           securityModel,
                           securityName,
                           securityLevel,
                           contextEngineId,
                           contextName,
                           pduVersion,
                           PDU,
                           statusInformation,
                           sendPduHandle,
                           cbInfo):
        sendRequestHandle, cbFun, cbCtx = cbInfo

        # 3.3.6d
        if sendPduHandle not in self.__pendingReqs:
            raise error.ProtocolError('Missing sendPduHandle %s' % sendPduHandle)

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

        snmpEngine.transportDispatcher.jobFinished(id(self))

        if statusInformation:
            debug.logger & debug.flagApp and debug.logger('processResponsePdu: sendRequestHandle %s, sendPduHandle %s statusInformation %s' % (sendRequestHandle, sendPduHandle, statusInformation))
            if origRetries == origRetryCount:
                debug.logger & debug.flagApp and debug.logger('processResponsePdu: sendRequestHandle %s, sendPduHandle %s retry count %d exceeded' % (sendRequestHandle, sendPduHandle, origRetries))
                cbFun(snmpEngine,
                      sendRequestHandle,
                      statusInformation['errorIndication'],
                      None,
                      cbCtx)
                return

            # Convert timeout in seconds into timeout in timer ticks
            timeoutInTicks = float(origTimeout)/100/snmpEngine.transportDispatcher.getTimerResolution()

            # User-side API assumes SMIv2
            if messageProcessingModel == 0:
                reqPDU = rfc2576.v2ToV1(origPdu)
                pduVersion = 0
            else:
                reqPDU = origPdu
                pduVersion = 1
 
            # 3.3.6a
            try:
                sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu(
                    snmpEngine,
                    origTransportDomain,
                    origTransportAddress,
                    origMessageProcessingModel,
                    origSecurityModel,
                    origSecurityName,
                    origSecurityLevel,
                    origContextEngineId,
                    origContextName,
                    pduVersion,
                    reqPDU,
                    1,                              # expectResponse
                    timeoutInTicks,
                    self.processResponsePdu,
                    (sendRequestHandle, cbFun, cbCtx)
                )
            except error.StatusInformation:
                statusInformation = sys.exc_info()[1]
                debug.logger & debug.flagApp and debug.logger('processResponsePdu: sendRequestHandle %s: sendPdu() failed with %r ' % (sendRequestHandle, statusInformation))
                cbFun(snmpEngine,
                      sendRequestHandle,
                      statusInformation['errorIndication'],
                      None,
                      cbCtx)
                return

            snmpEngine.transportDispatcher.jobStarted(id(self))

            debug.logger & debug.flagApp and debug.logger('processResponsePdu: sendRequestHandle %s, sendPduHandle %s, timeout %d, retry %d of %d' % (sendRequestHandle, sendPduHandle, origTimeout, origRetries, origRetryCount))
        
            # 3.3.6b
            self.__pendingReqs[sendPduHandle] = (
                origTransportDomain,
                origTransportAddress,
                origMessageProcessingModel,
                origSecurityModel,
                origSecurityName,
                origSecurityLevel,
                origContextEngineId,
                origContextName,
                origPdu,
                origTimeout,
                origRetryCount,
                origRetries + 1
            )
            return

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

        cbFun(snmpEngine, sendRequestHandle, None, PDU, cbCtx)