Example #1
0
    def handle_read(self):
        try:
            incomingMessage, transportAddress = self._recvfrom(self.socket, 65535)

            transportAddress = self.normalizeAddress(transportAddress)

            debug.logger & debug.FLAG_IO and debug.logger(
                'handle_read: transportAddress %r -> %r incomingMessage (%d '
                'octets) %s' % (transportAddress, transportAddress.getLocalAddress(),
                                len(incomingMessage), debug.hexdump(incomingMessage)))

            if not incomingMessage:
                self.handle_close()
                return

            else:
                self._cbFun(self, transportAddress, incomingMessage)
                return

        except socket.error as exc:
            if exc.args[0] in SOCK_ERRORS:
                debug.logger & debug.FLAG_IO and debug.logger(
                    'handle_read: known socket error %s' % exc)
                SOCK_ERRORS[exc.args[0]] and self.handle_close()
                return

            else:
                raise error.CarrierError('recvfrom() failed: %s' % exc)
Example #2
0
 def handle_read(self):
     try:
         incomingMessage, transportAddress = self._recvfrom(
             self.socket, 65535)
         transportAddress = self.normalizeAddress(transportAddress)
         debug.logger & debug.flagIO and debug.logger(
             'handle_read: transportAddress %r -> %r incomingMessage (%d octets) %s'
             % (transportAddress, transportAddress.getLocalAddress(),
                len(incomingMessage), debug.hexdump(incomingMessage)))
         if not incomingMessage:
             self.handle_close()
             return
         else:
             self._cbFun(self, transportAddress, incomingMessage)
             return
     except socket.error:
         if sys.exc_info()[1].args[0] in sockErrors:
             debug.logger & debug.flagIO and debug.logger(
                 'handle_read: known socket error %s' %
                 (sys.exc_info()[1], ))
             sockErrors[sys.exc_info()[1].args[0]] and self.handle_close()
             return
         else:
             raise error.CarrierError('recvfrom() failed: %s' %
                                      (sys.exc_info()[1], ))
Example #3
0
    def sendMessage(self, outgoingMessage, transportAddress):
        self.__outQueue.append(
            (outgoingMessage, self.normalizeAddress(transportAddress))
        )

        debug.logger & debug.FLAG_IO and debug.logger(
            'sendMessage: outgoingMessage queued (%d octets) %s' % (
                len(outgoingMessage), debug.hexdump(outgoingMessage)))
Example #4
0
 def connection_made(self, transport):
     self.transport = transport
     debug.logger & debug.flagIO and debug.logger('connection_made: invoked')
     while self._writeQ:
         outgoingMessage, transportAddress = self._writeQ.pop(0)
         debug.logger & debug.flagIO and debug.logger('connection_made: transportAddress %r outgoingMessage %s' %
                                                      (transportAddress, debug.hexdump(outgoingMessage)))
         try:
             self.transport.sendto(outgoingMessage, self.normalizeAddress(transportAddress))
         except Exception:
             raise error.CarrierError(';'.join(traceback.format_exception(*sys.exc_info())))
Example #5
0
 def connection_made(self, transport):
     self.transport = transport
     debug.logger & debug.flagIO and debug.logger('connection_made: invoked')
     while self._writeQ:
         outgoingMessage, transportAddress = self._writeQ.pop(0)
         debug.logger & debug.flagIO and debug.logger('connection_made: transportAddress %r outgoingMessage %s' %
                                                      (transportAddress, debug.hexdump(outgoingMessage)))
         try:
             self.transport.sendto(outgoingMessage, self.normalizeAddress(transportAddress))
         except Exception:
             raise error.CarrierError(';'.join(traceback.format_exception(*sys.exc_info())))
Example #6
0
 def sendMessage(self, outgoingMessage, transportAddress):
     debug.logger & debug.flagIO and debug.logger('sendMessage: %s transportAddress %r outgoingMessage %s' % (
         (self.transport is None and "queuing" or "sending"),
         transportAddress, debug.hexdump(outgoingMessage)
     ))
     if self.transport is None:
         self._writeQ.append((outgoingMessage, transportAddress))
     else:
         try:
             self.transport.sendto(outgoingMessage, self.normalizeAddress(transportAddress))
         except Exception:
             raise error.CarrierError(';'.join(traceback.format_exception(*sys.exc_info())))
Example #7
0
 def startProtocol(self):
     debug.logger & debug.flagIO and debug.logger('startProtocol: invoked')
     while self._writeQ:
         outgoingMessage, transportAddress = self._writeQ.pop(0)
         debug.logger & debug.flagIO and debug.logger(
             'startProtocol: transportAddress %r outgoingMessage %s' %
             (transportAddress, debug.hexdump(outgoingMessage)))
         try:
             self.transport.write(outgoingMessage, transportAddress)
         except Exception:
             raise error.CarrierError('Twisted exception: %s' %
                                      (sys.exc_info()[1], ))
Example #8
0
 def sendMessage(self, outgoingMessage, transportAddress):
     debug.logger & debug.flagIO and debug.logger('sendMessage: %s transportAddress %r outgoingMessage %s' % (
         (self.transport is None and "queuing" or "sending"),
         transportAddress, debug.hexdump(outgoingMessage)
     ))
     if self.transport is None:
         self._writeQ.append((outgoingMessage, transportAddress))
     else:
         try:
             self.transport.sendto(outgoingMessage, self.normalizeAddress(transportAddress))
         except Exception:
             raise error.CarrierError(';'.join(traceback.format_exception(*sys.exc_info())))
Example #9
0
 def sendMessage(self, outgoingMessage, transportAddress):
     debug.logger & debug.flagIO and debug.logger(
         'startProtocol: %s transportAddress %r outgoingMessage %s' %
         ((self.transport is None and "queuing"
           or "sending"), transportAddress, debug.hexdump(outgoingMessage)))
     if self.transport is None:
         self._writeQ.append((outgoingMessage, transportAddress))
     else:
         try:
             self.transport.write(outgoingMessage, transportAddress)
         except Exception:
             raise error.CarrierError('Twisted exception: %s' %
                                      (sys.exc_info()[1], ))
Example #10
0
    def sendMessage(self, outgoingMessage, transportAddress):
        debug.logger & debug.FLAG_IO and debug.logger(
            'startProtocol: %s transportAddress %r outgoingMessage '
            '%s' % ((self.transport is None and "queuing" or "sending"),
                    transportAddress, debug.hexdump(outgoingMessage)))

        if not self.transport:
            self._writeQ.append((outgoingMessage, transportAddress))

        else:
            try:
                self.transport.write(outgoingMessage, transportAddress)

            except Exception as exc:
                raise error.CarrierError('Twisted exception: %s' % exc)
Example #11
0
 def handle_write(self):
     outgoingMessage, transportAddress = self.__outQueue.pop(0)
     debug.logger & debug.flagIO and debug.logger(
         "handle_write: transportAddress %r -> %r outgoingMessage (%d octets) %s"
         % (self.__getsockname(), transportAddress, len(outgoingMessage), debug.hexdump(outgoingMessage))
     )
     if not transportAddress:
         debug.logger & debug.flagIO and debug.logger("handle_write: missing dst address, loosing outgoing msg")
         return
     try:
         self.socket.sendto(outgoingMessage, transportAddress)
     except socket.error:
         if sys.exc_info()[1].args[0] in sockErrors:
             debug.logger & debug.flagIO and debug.logger(
                 "handle_write: ignoring socket error %s" % (sys.exc_info()[1],)
             )
         else:
             raise error.CarrierError("sendto() failed for %s: %s" % (transportAddress, sys.exc_info()[1]))
Example #12
0
File: base.py Project: ithek/pysnmp
 def handle_write(self):
     outgoingMessage, transportAddress = self.__outQueue.pop()
     debug.logger & debug.flagIO and debug.logger(
         'handle_write: transportAddress %r -> %r outgoingMessage %s' %
         (self.socket.getsockname(), transportAddress,
          debug.hexdump(outgoingMessage)))
     if not transportAddress:
         debug.logger & debug.flagIO and debug.logger(
             'handle_write: missing dst address, loosing outgoing msg')
         return
     try:
         self.socket.sendto(outgoingMessage, transportAddress)
     except socket.error:
         if sys.exc_info()[1].args[0] in sockErrors:
             debug.logger & debug.flagIO and debug.logger(
                 'handle_write: ignoring socket error %s' %
                 (sys.exc_info()[1], ))
         else:
             raise error.CarrierError('sendto() failed for %s: %s' %
                                      (transportAddress, sys.exc_info()[1]))
Example #13
0
 def handle_read(self):
     try:
         incomingMessage, transportAddress = self.socket.recvfrom(65535)
         transportAddress = self.normalizeAddress(transportAddress)
         debug.logger & debug.flagIO and debug.logger(
             "handle_read: transportAddress %r -> %r incomingMessage (%d octets) %s"
             % (transportAddress, self.__getsockname(), len(incomingMessage), debug.hexdump(incomingMessage))
         )
         if not incomingMessage:
             self.handle_close()
             return
         else:
             self._cbFun(self, transportAddress, incomingMessage)
             return
     except socket.error:
         if sys.exc_info()[1].args[0] in sockErrors:
             debug.logger & debug.flagIO and debug.logger(
                 "handle_read: known socket error %s" % (sys.exc_info()[1],)
             )
             sockErrors[sys.exc_info()[1].args[0]] and self.handle_close()
             return
         else:
             raise error.CarrierError("recvfrom() failed: %s" % (sys.exc_info()[1],))
Example #14
0
    def handle_write(self):
        outgoingMessage, transportAddress = self.__outQueue.pop(0)

        debug.logger & debug.FLAG_IO and debug.logger(
            'handle_write: transportAddress %r -> %r outgoingMessage (%d '
            'octets) %s' % (transportAddress.getLocalAddress(), transportAddress,
                            len(outgoingMessage), debug.hexdump(outgoingMessage)))

        if not transportAddress:
            debug.logger & debug.FLAG_IO and debug.logger(
                'handle_write: missing dst address, loosing outgoing msg')
            return

        try:
            self._sendto(self.socket, outgoingMessage, transportAddress)

        except socket.error as exc:
            if exc.args[0] in SOCK_ERRORS:
                debug.logger & debug.FLAG_IO and debug.logger(
                    'handle_write: ignoring socket error %s' % exc)

            else:
                raise error.CarrierError(
                    'sendto() failed for %s: %s' % (transportAddress, exc))
Example #15
0
    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)
Example #16
0
    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 sendMessage(self, outgoingMessage, transportAddress):
     debug.logger & debug.flagIO and debug.logger('startProtocol: %s transportAddress %r outgoingMessage %s' % ((self.transport is None and "queuing" or "sending"), transportAddress, debug.hexdump(outgoingMessage)))
     if self.transport is None:
         self._writeQ.append((outgoingMessage, transportAddress))
     else:
         try:
             self.transport.write(outgoingMessage, transportAddress)
         except Exception:
             raise error.CarrierError('Twisted exception: %s' % (sys.exc_info()[1],))
 def startProtocol(self):
     debug.logger & debug.flagIO and debug.logger('startProtocol: invoked')
     while self._writeQ:
         outgoingMessage, transportAddress = self._writeQ.pop(0)
         debug.logger & debug.flagIO and debug.logger('startProtocol: transportAddress %r outgoingMessage %s' % (transportAddress, debug.hexdump(outgoingMessage)))
         try:
             self.transport.write(outgoingMessage, transportAddress)
         except Exception:
             raise error.CarrierError('Twisted exception: %s' % (sys.exc_info()[1],))
Example #19
0
 def sendMessage(self, outgoingMessage, transportAddress):
     self.__outQueue.append(
         (outgoingMessage, self.normalizeAddress(transportAddress)))
     debug.logger & debug.flagIO and debug.logger(
         'sendMessage: outgoingMessage queued (%d octets) %s' %
         (len(outgoingMessage), debug.hexdump(outgoingMessage)))
Example #20
0
    def __generateRequestOrResponseMsg(
        self,
        snmpEngine,
        messageProcessingModel,
        globalData,
        maxMessageSize,
        securityModel,
        securityEngineID,
        securityName,
        securityLevel,
        scopedPDU,
        securityStateReference
        ):
        snmpEngineID = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')[0].syntax
        # 3.1.1
        if securityStateReference is not None:
            # 3.1.1a
            cachedSecurityData = self._cache.pop(securityStateReference)
            usmUserName = cachedSecurityData['msgUserName']
            if '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,
                  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 = errind.unknownSecurityName
                        )
                debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: clone user info')
        else:
            # empty username used for engineID discovery
            usmUserName = usmUserSecurityName = null
            usmUserAuthProtocol = noauth.NoAuth.serviceID
            usmUserPrivProtocol = nopriv.NoPriv.serviceID
            usmUserAuthKeyLocalized = usmUserPrivKeyLocalized = None
            debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: use empty USM data')
            
        debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: local user usmUserName %r usmUserAuthProtocol %s usmUserPrivProtocol %s securityEngineID %r securityName %r' % (usmUserName, usmUserAuthProtocol, usmUserPrivProtocol, securityEngineID, securityName))

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

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

        securityParameters = self.__securityParametersSpec

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

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

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

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

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

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

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

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

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

        debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: %s' % scopedPDUData.prettyPrint())
        
        # 3.1.5
        securityParameters.setComponentByPosition(
            0, securityEngineID, verifyConstraints=False
            )
        securityParameters.setComponentByPosition(
            1, snmpEngineBoots, verifyConstraints=False
            )
        securityParameters.setComponentByPosition(
            2, snmpEngineTime, verifyConstraints=False
            )
    
        # 3.1.7
        securityParameters.setComponentByPosition(
            3, usmUserName, verifyConstraints=False
            )

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

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

            debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: %s' % (securityParameters.prettyPrint(),))
            
            msg.setComponentByPosition(
                2, encoder.encode(securityParameters), verifyConstraints=False
                )

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

            wholeMsg = encoder.encode(msg)

            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(),))

            msg.setComponentByPosition(
                2, encoder.encode(securityParameters), verifyConstraints=False
                )

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

            authenticatedWholeMsg = encoder.encode(msg)

        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
            )
Example #21
0
    def processIncomingMsg(
        self,
        snmpEngine,
        messageProcessingModel,
        maxMessageSize,
        securityParameters,
        securityModel,
        securityLevel,
        wholeMsg,
        msg  # XXX 
        ):
        # 3.2.9 -- moved up here to be able to report
        # maxSizeResponseScopedPDU on error
        # (48 - maximum SNMPv3 header length)
        maxSizeResponseScopedPDU = maxMessageSize - len(securityParameters)-48

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

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

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

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

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

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

        # 3.2.3
        if msgAuthoritativeEngineID not in self.__timeline:
            debug.logger & debug.flagSM and debug.logger('processIncomingMsg: unknown securityEngineID %r' % (msgAuthoritativeEngineID,))
            if not msgAuthoritativeEngineID:
                # 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')

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

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

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

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

        debug.logger & debug.flagSM and debug.logger('processIncomingMsg: read from securityParams msgAuthoritativeEngineID %r msgUserName %r' % (msgAuthoritativeEngineID, msgUserName))
        
        if msgUserName:
            # 3.2.4
            try:
                ( 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,
                            msgAuthoritativeEngineID,
                            msgUserName
                            )
                        debug.logger & debug.flagSM and debug.logger('processIncomingMsg: cloned user info')
                    except NoSuchInstanceError:
                        __reportUnknownName = 1
                debug.logger & debug.flagSM and debug.logger('processIncomingMsg: unknown securityEngineID %r msgUserName %r' % (msgAuthoritativeEngineID, msgUserName))
                if __reportUnknownName:
                        usmStatsUnknownUserNames, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownUserNames')
                        usmStatsUnknownUserNames.syntax = usmStatsUnknownUserNames.syntax+1
                        raise error.StatusInformation(
                            errorIndication = errind.unknownSecurityName,
                            oid = usmStatsUnknownUserNames.name,
                            val = usmStatsUnknownUserNames.syntax,
                            securityStateReference=securityStateReference,
                            securityLevel=securityLevel,
                            contextEngineId=contextEngineId,
                            contextName=contextName,
                            maxSizeResponseScopedPDU=maxSizeResponseScopedPDU
                            )
        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 usmUserSecurityName %s usmUserAuthProtocol %s usmUserPrivProtocol %s for msgUserName %s' % (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),
            usmUserAuthProtocol=usmUserAuthProtocol,
            usmUserAuthKeyLocalized=usmUserAuthKeyLocalized,
            usmUserPrivProtocol=usmUserPrivProtocol,
            usmUserPrivKeyLocalized=usmUserPrivKeyLocalized
            )

        # 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:
                    __badSecIndication = 'authNoPriv wanted while priv expected'

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

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

            if msgAuthoritativeEngineID:
                # 3.2.3a moved down here to execute only for authed msg
                self.__timeline[msgAuthoritativeEngineID] = (
                    securityParameters.getComponentByPosition(1),
                    securityParameters.getComponentByPosition(2),
                    securityParameters.getComponentByPosition(2),
                    int(time.time())
                    )
                
                expireAt = int(self.__expirationTimer + 300 / snmpEngine.transportDispatcher.getTimerResolution())
                if expireAt not in self.__timelineExpQueue:
                    self.__timelineExpQueue[expireAt] = []
                self.__timelineExpQueue[expireAt].append(
                    msgAuthoritativeEngineID
                    )
                    
                debug.logger & debug.flagSM and debug.logger('processIncomingMsg: store timeline for securityEngineID %r' % (msgAuthoritativeEngineID,))
            
        # 3.2.7
        if securityLevel == 3 or securityLevel == 2:
            if msgAuthoritativeEngineID == snmpEngineID:
                # Authoritative SNMP engine: use local notion (SF bug #1649032)
                ( snmpEngineBoots,
                  snmpEngineTime ) = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineBoots', 'snmpEngineTime')
                snmpEngineBoots = snmpEngineBoots.syntax
                snmpEngineTime = snmpEngineTime.syntax.clone()
                idleTime = 0
                debug.logger & debug.flagSM and debug.logger('processIncomingMsg: read snmpEngineBoots (%s), snmpEngineTime (%s) from LCD' % (snmpEngineBoots, snmpEngineTime))
            else:
                # Non-authoritative SNMP engine: use cached estimates
                if msgAuthoritativeEngineID in self.__timeline:
                    ( snmpEngineBoots,
                      snmpEngineTime,
                      latestReceivedEngineTime,
                      latestUpdateTimestamp ) = self.__timeline[
                        msgAuthoritativeEngineID
                        ]
                    # time passed since last talk with this SNMP engine
                    idleTime = int(time.time())-latestUpdateTimestamp
                    debug.logger & debug.flagSM and debug.logger('processIncomingMsg: read timeline snmpEngineBoots %s snmpEngineTime %s for msgAuthoritativeEngineID %r, idle time %s secs' % (snmpEngineBoots, snmpEngineTime, msgAuthoritativeEngineID, idleTime))
                else:
                    raise error.ProtocolError('Peer SNMP engine info missing')

            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 = errind.notInTimeWindow,
                        oid=usmStatsNotInTimeWindows.name,
                        val=usmStatsNotInTimeWindows.syntax,
                        securityStateReference=securityStateReference,
                        securityLevel=2,
                        contextEngineId=contextEngineId,
                        contextName=contextName,
                        maxSizeResponseScopedPDU=maxSizeResponseScopedPDU
                        )
            # 3.2.7b
            else:
                # 3.2.7b.1
                if msgAuthoritativeEngineBoots > snmpEngineBoots or \
                   msgAuthoritativeEngineBoots == snmpEngineBoots and \
                   msgAuthoritativeEngineTime > latestReceivedEngineTime:
                    self.__timeline[msgAuthoritativeEngineID] = (
                        msgAuthoritativeEngineBoots,
                        msgAuthoritativeEngineTime,
                        msgAuthoritativeEngineTime,
                        int(time.time())
                        )
                    expireAt = int(self.__expirationTimer + 300 / snmpEngine.transportDispatcher.getTimerResolution())
                    if expireAt not in self.__timelineExpQueue:
                        self.__timelineExpQueue[expireAt] = []
                    self.__timelineExpQueue[expireAt].append(
                        msgAuthoritativeEngineID
                        )

                    debug.logger & debug.flagSM and debug.logger('processIncomingMsg: stored timeline msgAuthoritativeEngineBoots %s msgAuthoritativeEngineTime %s for msgAuthoritativeEngineID %r' % (msgAuthoritativeEngineBoots, msgAuthoritativeEngineTime, msgAuthoritativeEngineID))
                    
                # 3.2.7b.2
                if snmpEngineBoots == 2147483647 or \
                   msgAuthoritativeEngineBoots < snmpEngineBoots or \
                   msgAuthoritativeEngineBoots == snmpEngineBoots and \
                   abs(idleTime + int(snmpEngineTime) - \
                       int(msgAuthoritativeEngineTime)) > 150:
                    raise error.StatusInformation(
                        errorIndication = errind.notInTimeWindow
                        )

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

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

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

        # 3.2.10
        securityName = usmUserSecurityName
        
        debug.logger & debug.flagSM and debug.logger('processIncomingMsg: cached msgUserName %s info by securityStateReference %s' % (msgUserName, securityStateReference))
        
        # Delayed to include details
        if not msgUserName and not msgAuthoritativeEngineID:
            usmStatsUnknownUserNames, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-USER-BASED-SM-MIB', 'usmStatsUnknownUserNames')
            usmStatsUnknownUserNames.syntax = usmStatsUnknownUserNames.syntax+1
            raise error.StatusInformation(
                errorIndication=errind.unknownSecurityName,
                oid=usmStatsUnknownUserNames.name,
                val=usmStatsUnknownUserNames.syntax,
                securityStateReference=securityStateReference,
                securityEngineID=msgAuthoritativeEngineID,
                securityLevel=securityLevel,
                contextEngineId=contextEngineId,
                contextName=contextName,
                maxSizeResponseScopedPDU=maxSizeResponseScopedPDU,
                PDU=scopedPDU
                )

        # 3.2.12
        return ( msgAuthoritativeEngineID,
                 securityName,
                 scopedPDU,
                 maxSizeResponseScopedPDU,
                 securityStateReference )
Example #22
0
 def sendMessage(self, outgoingMessage, transportAddress):
     self.__outQueue.append(
         (outgoingMessage, transportAddress)
         )
     self.set_writable(True)
     LOGGER.debug('sendMessage: outgoingMessage queued (%d octets) %s' % (len(outgoingMessage), debug.hexdump(outgoingMessage)))
Example #23
0
 def handle_write(self):
     if not self.__outQueue:
         self.set_writable(False)
         return
     outgoingMessage, transportAddress = self.__outQueue.pop(0)
     LOGGER.debug('handle_write: transportAddress %r -> %r outgoingMessage (%d octets) %s' % (self.__getsockname(), transportAddress, len(outgoingMessage), debug.hexdump(outgoingMessage)))
     if not transportAddress:
         LOGGER.debug('handle_write: missing dst address, loosing outgoing msg')
         return
     try:
         self.socket.sendto(outgoingMessage, transportAddress)
     except socket.error:
         if sys.exc_info()[1].args[0] in sockErrors:
             LOGGER.debug('handle_write: ignoring socket error %s' % (sys.exc_info()[1],))
         else:
             raise error.CarrierError('sendto() failed for %s: %s' % (transportAddress, sys.exc_info()[1]))
Example #24
0
 def handle_read(self):
     try:
         incomingMessage, transportAddress = self.socket.recvfrom(65535)
         transportAddress = self.normalizeAddress(transportAddress)
         LOGGER.debug('handle_read: transportAddress %r -> %r incomingMessage (%d octets) %s' % (transportAddress, self.__getsockname(), len(incomingMessage), debug.hexdump(incomingMessage)))
         if not incomingMessage:
             # must do something, but don't know what
             return
         else:
             self._cbFun(self, transportAddress, incomingMessage)
             return
     except socket.error:
         if sys.exc_info()[1].args[0] in sockErrors:
             LOGGER.debug('handle_read: known socket error %s' % (sys.exc_info()[1],))
             sockErrors[sys.exc_info()[1].args[0]] and self.handle_close()
             return
         else:
             raise error.CarrierError('recvfrom() failed: %s' % (sys.exc_info()[1],))
Example #25
0
 def sendMessage(self, outgoingMessage, transportAddress):
     self.__outQueue.append((outgoingMessage, transportAddress))
     debug.logger & debug.flagIO and debug.logger(
         "sendMessage: outgoingMessage queued (%d octets) %s"
         % (len(outgoingMessage), debug.hexdump(outgoingMessage))
     )