Esempio n. 1
0
File: node.py Progetto: MAHIS/PyNDN2
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """
        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

        # Now process as Interest or Data.
        if interest != None:
            # Call all interest filter callbacks which match.
            for i in range(len(self._interestFilterTable)):
                entry = self._interestFilterTable[i]
                if entry.getFilter().doesMatch(interest.getName()):
                    includeFilter = True
                    # Use getcallargs to test if onInterest accepts 5 args.
                    try:
                        inspect.getcallargs(entry.getOnInterest(),
                          None, None, None, None, None)
                    except TypeError:
                        # Assume onInterest is old-style with 4 arguments.
                        includeFilter = False

                    if includeFilter:
                        try:
                            entry.getOnInterest()(
                              entry.getFilter().getPrefix(), interest,
                              entry.getFace(), entry.getInterestFilterId(),
                              entry.getFilter())
                        except:
                            logging.exception("Error in onInterest")
                    else:
                        # Old-style onInterest without the filter argument. We
                        # still pass a Face instead of Transport since Face also
                        # has a send method.
                        try:
                            entry.getOnInterest()(
                              entry.getFilter().getPrefix(), interest,
                              entry.getFace(), entry.getInterestFilterId())
                        except:
                            logging.exception("Error in onInterest")
        elif data != None:
            pendingInterests = self._extractEntriesForExpressedInterest(
              data.getName())
            for pendingInterest in pendingInterests:
                try:
                    pendingInterest.getOnData()(pendingInterest.getInterest(), data)
                except:
                    logging.exception("Error in onData")
    def addMember(self, scheduleName, keyName, key):
        """
        Add a new member with the given key named keyName into a schedule named
        scheduleName. The member's identity name is keyName.getPrefix(-1).

        :param str scheduleName: The schedule name.
        :param Name keyName: The name of the key.
        :param Blob key: A Blob of the public key DER.
        :raises GroupManagerDb.Error: If there's no schedule named scheduleName,
          if the member's identity name already exists, or other database error.
        """
        scheduleId = self._getScheduleId(scheduleName)
        if scheduleId == -1:
          raise GroupManagerDb.Error("The schedule does not exist")

        # Needs to be changed in the future.
        memberName = keyName.getPrefix(-1)

        try:
            cursor = self._database.cursor()
            cursor.execute(
              "INSERT INTO members(schedule_id, member_name, key_name, pubkey) " +
                "values (?, ?, ?, ?)",
              (scheduleId,
               sqlite3.Binary(bytearray(memberName.wireEncode(TlvWireFormat.get()).buf())),
               sqlite3.Binary(bytearray(keyName.wireEncode(TlvWireFormat.get()).buf())),
               sqlite3.Binary(bytearray(key.buf()))))
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.addMember: SQLite error: " + str(ex))
Esempio n. 3
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.
        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        # Now process as Interest or Data.
        if data != None:
            if self._onBtleData:
                self._onBtleData(data)
    def addMember(self, scheduleName, keyName, key):
        """
        Add a new member with the given key named keyName into a schedule named
        scheduleName. The member's identity name is keyName.getPrefix(-1).

        :param str scheduleName: The schedule name.
        :param Name keyName: The name of the key.
        :param Blob key: A Blob of the public key DER.
        :raises GroupManagerDb.Error: If there's no schedule named scheduleName,
          if the member's identity name already exists, or other database error.
        """
        scheduleId = self._getScheduleId(scheduleName)
        if scheduleId == -1:
            raise GroupManagerDb.Error("The schedule does not exist")

        # Needs to be changed in the future.
        memberName = keyName.getPrefix(-1)

        try:
            cursor = self._database.cursor()
            cursor.execute(
                "INSERT INTO members(schedule_id, member_name, key_name, pubkey) " + "values (?, ?, ?, ?)",
                (
                    scheduleId,
                    sqlite3.Binary(bytearray(memberName.wireEncode(TlvWireFormat.get()).buf())),
                    sqlite3.Binary(bytearray(keyName.wireEncode(TlvWireFormat.get()).buf())),
                    sqlite3.Binary(bytearray(key.buf())),
                ),
            )
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise GroupManagerDb.Error("Sqlite3GroupManagerDb.addMember: SQLite error: " + str(ex))
Esempio n. 5
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.
        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        # Now process as Interest or Data.
        if data != None:
            if self._onBtleData:
                self._onBtleData(data)
Esempio n. 6
0
    def _nfdRegisterPrefix(
      self, registeredPrefixId, prefix, onInterest, onRegisterFailed, flags,
      commandKeyChain, commandCertificateName, face):
        """
        Do the work of registerPrefix to register with NFD.

        :param int registeredPrefixId: The getNextEntryId() which registerPrefix
          got so it could return it to the caller. If this is 0, then don't add
          to _registeredPrefixTable (assuming it has already been done).
        """
        if commandKeyChain == None:
            raise RuntimeError(
              "registerPrefix: The command KeyChain has not been set. You must call setCommandSigningInfo.")
        if commandCertificateName.size() == 0:
            raise RuntimeError(
              "registerPrefix: The command certificate name has not been set. You must call setCommandSigningInfo.")

        controlParameters = ControlParameters()
        controlParameters.setName(prefix)
        controlParameters.setForwardingFlags(flags)

        commandInterest = Interest()
        if self.isLocal():
            commandInterest.setName(Name("/localhost/nfd/rib/register"))
            # The interest is answered by the local host, so set a short timeout.
            commandInterest.setInterestLifetimeMilliseconds(2000.0)
        else:
            commandInterest.setName(Name("/localhop/nfd/rib/register"))
            # The host is remote, so set a longer timeout.
            commandInterest.setInterestLifetimeMilliseconds(4000.0)
        # NFD only accepts TlvWireFormat packets.
        commandInterest.getName().append(controlParameters.wireEncode(TlvWireFormat.get()))
        self.makeCommandInterest(
          commandInterest, commandKeyChain, commandCertificateName,
          TlvWireFormat.get())

        if registeredPrefixId != 0:
            interestFilterId = 0
            if onInterest != None:
                # registerPrefix was called with the "combined" form that includes
                # the callback, so add an InterestFilterEntry.
                interestFilterId = self.getNextEntryId()
                self.setInterestFilter(
                  interestFilterId, InterestFilter(prefix), onInterest, face)

            self._registeredPrefixTable.append(Node._RegisteredPrefix(
              registeredPrefixId, prefix, interestFilterId))

        # Send the registration interest.
        response = Node._RegisterResponse(
          self, prefix, onInterest, onRegisterFailed, flags,
          TlvWireFormat.get(), True, face)
        self.expressInterest(
          self.getNextEntryId(), commandInterest, response.onData,
          response.onTimeout, TlvWireFormat.get(), face)
Esempio n. 7
0
    def _nfdRegisterPrefix(self, registeredPrefixId, prefix, onInterest,
                           onRegisterFailed, onRegisterSuccess,
                           registrationOptions, commandKeyChain,
                           commandCertificateName, face):
        """
        Do the work of registerPrefix to register with NFD.

        :param int registeredPrefixId: The getNextEntryId() which registerPrefix
          got so it could return it to the caller. If this is 0, then don't add
          to _registeredPrefixTable (assuming it has already been done).
        """
        if commandKeyChain == None:
            raise RuntimeError(
                "registerPrefix: The command KeyChain has not been set. You must call setCommandSigningInfo."
            )
        if commandCertificateName.size() == 0:
            raise RuntimeError(
                "registerPrefix: The command certificate name has not been set. You must call setCommandSigningInfo."
            )

        controlParameters = ControlParameters()
        controlParameters.setName(prefix)
        controlParameters.setForwardingFlags(registrationOptions)
        if (registrationOptions.getOrigin() != None
                and registrationOptions.getOrigin() >= 0):
            controlParameters.setOrigin(registrationOptions.getOrigin())
            # Remove the origin value from the flags since it is not used to encode.
            controlParameters.getForwardingFlags().setOrigin(None)

        commandInterest = Interest()
        commandInterest.setCanBePrefix(True)
        commandInterest.setMustBeFresh(True)
        if self.isLocal():
            commandInterest.setName(Name("/localhost/nfd/rib/register"))
            # The interest is answered by the local host, so set a short timeout.
            commandInterest.setInterestLifetimeMilliseconds(2000.0)
        else:
            commandInterest.setName(Name("/localhop/nfd/rib/register"))
            # The host is remote, so set a longer timeout.
            commandInterest.setInterestLifetimeMilliseconds(4000.0)
        # NFD only accepts TlvWireFormat packets.
        commandInterest.getName().append(
            controlParameters.wireEncode(TlvWireFormat.get()))
        self.makeCommandInterest(commandInterest, commandKeyChain,
                                 commandCertificateName, TlvWireFormat.get())

        # Send the registration interest.
        response = Node._RegisterResponse(prefix, onRegisterFailed,
                                          onRegisterSuccess,
                                          registeredPrefixId, self, onInterest,
                                          face)
        self.expressInterest(self.getNextEntryId(), commandInterest,
                             response.onData, response.onTimeout, None,
                             TlvWireFormat.get(), face)
Esempio n. 8
0
    def _nfdRegisterPrefix(
      self, registeredPrefixId, prefix, onInterest, onRegisterFailed,
      onRegisterSuccess, registrationOptions, commandKeyChain,
      commandCertificateName, face):
        """
        Do the work of registerPrefix to register with NFD.

        :param int registeredPrefixId: The getNextEntryId() which registerPrefix
          got so it could return it to the caller. If this is 0, then don't add
          to _registeredPrefixTable (assuming it has already been done).
        """
        if commandKeyChain == None:
            raise RuntimeError(
              "registerPrefix: The command KeyChain has not been set. You must call setCommandSigningInfo.")
        if commandCertificateName.size() == 0:
            raise RuntimeError(
              "registerPrefix: The command certificate name has not been set. You must call setCommandSigningInfo.")

        controlParameters = ControlParameters()
        controlParameters.setName(prefix)
        controlParameters.setForwardingFlags(registrationOptions)
        if (registrationOptions.getOrigin() != None and
              registrationOptions.getOrigin() >= 0):
            controlParameters.setOrigin(registrationOptions.getOrigin())
            # Remove the origin value from the flags since it is not used to encode.
            controlParameters.getForwardingFlags().setOrigin(None)

        commandInterest = Interest()
        commandInterest.setCanBePrefix(True)
        if self.isLocal():
            commandInterest.setName(Name("/localhost/nfd/rib/register"))
            # The interest is answered by the local host, so set a short timeout.
            commandInterest.setInterestLifetimeMilliseconds(2000.0)
        else:
            commandInterest.setName(Name("/localhop/nfd/rib/register"))
            # The host is remote, so set a longer timeout.
            commandInterest.setInterestLifetimeMilliseconds(4000.0)
        # NFD only accepts TlvWireFormat packets.
        commandInterest.getName().append(controlParameters.wireEncode(TlvWireFormat.get()))
        self.makeCommandInterest(
          commandInterest, commandKeyChain, commandCertificateName,
          TlvWireFormat.get())

        # Send the registration interest.
        response = Node._RegisterResponse(
          prefix, onRegisterFailed, onRegisterSuccess, registeredPrefixId, self,
          onInterest, face)
        self.expressInterest(
          self.getNextEntryId(), commandInterest, response.onData,
          response.onTimeout, None, TlvWireFormat.get(), face)
Esempio n. 9
0
    def listAllMembers(self):
        """
        List all the members.

        :return: A new List of Name with the names of all members.
        :rtype: Array<Name>
        :raises GroupManagerDb.Error: For a database error.
        """
        list = []

        try:
            cursor = self._database.cursor()
            cursor.execute("SELECT member_name FROM members", ())
            results = cursor.fetchall()
            for (nameEncoding, ) in results:
                identity = Name()
                identity.wireDecode(bytearray(nameEncoding),
                                    TlvWireFormat.get())
                list.append(identity)
            cursor.close()

            return list
        except Exception as ex:
            raise GroupManagerDb.Error(
                "Sqlite3GroupManagerDb.listAllMembers: SQLite error: " +
                str(ex))
Esempio n. 10
0
    def hasMember(self, identity):
        """
        Check if there is a member with the given identity name.

        :param Name identity: The member's identity name.
        :return: True if there is a member.
        :rtype: bool
        :raises GroupManagerDb.Error: For a database error.
        """
        result = False

        try:
            cursor = self._database.cursor()
            cursor.execute(
                "SELECT member_id FROM members WHERE member_name=?",
                (sqlite3.Binary(
                    bytearray(identity.wireEncode(
                        TlvWireFormat.get()).buf())), ))
            if cursor.fetchone() != None:
                result = True

            cursor.close()
            return result
        except Exception as ex:
            raise GroupManagerDb.Error(
                "Sqlite3GroupManagerDb.hasMember: SQLite error: " + str(ex))
Esempio n. 11
0
    def hasEKey(self, eKeyName):
        """
        Check if there is an EKey with the name eKeyName in the database.

        :param Name eKeyName: The name of the EKey.
        :return: True if the EKey exists.
        :rtype: bool
        :raises GroupManagerDb.Error: For a database error.
        """
        result = False

        try:
            cursor = self._database.cursor()
            cursor.execute(
                "SELECT ekey_id FROM ekeys where ekey_name=?", (sqlite3.Binary(
                    bytearray(eKeyName.wireEncode(
                        TlvWireFormat.get()).buf())), ))
            if cursor.fetchone() != None:
                result = True

            cursor.close()
            return result
        except Exception as ex:
            raise GroupManagerDb.Error(
                "Sqlite3GroupManagerDb.hasEKey: SQLite error: " + str(ex))
Esempio n. 12
0
    def updateMemberSchedule(self, identity, scheduleName):
        """
        Change the name of the schedule for the given member's identity name.

        :param Name identity: The member's identity name.
        :param str scheduleName: The new schedule name.
        :raises GroupManagerDb.Error: If there's no member with the given
          identity name in the database, or there's no schedule named
          scheduleName, or other database error.
        """
        scheduleId = self._getScheduleId(scheduleName)
        if scheduleId == -1:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.updateMemberSchedule: The schedule does not exist");

        try:
            cursor = self._database.cursor()
            cursor.execute(
              "UPDATE members SET schedule_id=? WHERE member_name=?",
              (scheduleId,
               sqlite3.Binary(bytearray(identity.wireEncode(TlvWireFormat.get()).buf()))))
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.updateMemberSchedule: SQLite error: " + str(ex))
Esempio n. 13
0
    def wireDecode(self, input):
        """
        Decode the input as an NDN-TLV SafeBag and update this object.

        :param input: The array with the bytes to decode.
        :type input: A Blob or an array type with int elements
        """
        if isinstance(input, Blob):
            input = input.buf()

        # Decode directly as TLV. We don't support the WireFormat abstraction
        # because this isn't meant to go directly on the wire.
        decoder = TlvDecoder(input)
        endOffset = decoder.readNestedTlvsStart(Tlv.SafeBag_SafeBag)

        # Get the bytes of the certificate and decode.
        certificateBeginOffset = decoder.getOffset()
        certificateEndOffset = decoder.readNestedTlvsStart(Tlv.Data)
        decoder.seek(certificateEndOffset)
        self._certificate = Data()
        self._certificate.wireDecode(
            decoder.getSlice(certificateBeginOffset, certificateEndOffset),
            TlvWireFormat.get())

        self._privateKeyBag = Blob(
            decoder.readBlobTlv(Tlv.SafeBag_EncryptedKeyBag), True)

        decoder.finishNestedTlvs(endOffset)
Esempio n. 14
0
    def wireDecode(self, input):
        """
        Decode the input as an NDN-TLV SafeBag and update this object.

        :param input: The array with the bytes to decode.
        :type input: A Blob or an array type with int elements
        """
        if isinstance(input, Blob):
          input = input.buf()

        # Decode directly as TLV. We don't support the WireFormat abstraction
        # because this isn't meant to go directly on the wire.
        decoder = TlvDecoder(input)
        endOffset = decoder.readNestedTlvsStart(Tlv.SafeBag_SafeBag)

        # Get the bytes of the certificate and decode.
        certificateBeginOffset = decoder.getOffset()
        certificateEndOffset = decoder.readNestedTlvsStart(Tlv.Data)
        decoder.seek(certificateEndOffset)
        self._certificate = Data()
        self._certificate.wireDecode(
          decoder.getSlice(certificateBeginOffset, certificateEndOffset),
          TlvWireFormat.get())

        self._privateKeyBag = Blob(
          decoder.readBlobTlv(Tlv.SafeBag_EncryptedKeyBag), True)

        decoder.finishNestedTlvs(endOffset)
Esempio n. 15
0
    def getKey(self, keyName):
        """
        Get the key with keyName from the database.

        :param Name keyName: The key name.
        :return: A Blob with the encoded key, or an isNull Blob if cannot find
          the key with keyName.
        :rtype: Blob
        :raises ConsumerDb.Error: For a database error.
        """
        try:
            cursor = self._database.cursor()
            cursor.execute(
                "SELECT key_buf FROM decryptionkeys WHERE key_name=?",
                (sqlite3.Binary(
                    bytearray(keyName.wireEncode(
                        TlvWireFormat.get()).buf())), ))
            result = cursor.fetchone()
            key = Blob()
            if result != None:
                return Blob(bytearray(result[0]), False)
            cursor.close()

            return key
        except Exception as ex:
            raise ConsumerDb.Error("Sqlite3ConsumerDb.getKey: SQLite error: " +
                                   str(ex))
    def getEKey(self, eKeyName):
        """
        Get the group key pair with the name eKeyName from the database.

        :param Name eKeyName: The name of the EKey.
        :return: A tuple (privateKeyBlob, publicKeyBlob) where "privateKeyBlob"
          is the encoding Blob of the private key and "publicKeyBlob" is the
          encoding Blob of the public key.
        :rtype: (Blob, Blob)
        :raises GroupManagerDb.Error: If the key with name eKeyName does not
          exist in the database, or other database error.
        """
        publicKey = None
        try:
            cursor = self._database.cursor()
            cursor.execute(
              "SELECT pub_key FROM ekeys where ekey_name=?",
              (sqlite3.Binary(bytearray(eKeyName.wireEncode(TlvWireFormat.get()).buf())), ))
            result = cursor.fetchone()
            if result != None:
                publicKey = Blob(bytearray(result[0]), False)
            cursor.close()
        except Exception as ex:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.getMemberSchedule: SQLite error: " + str(ex))

        if publicKey == None:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.getEKey: Cannot get the result from the database")

        return (publicKey, self._privateKeyBase[Name(eKeyName)])
    def getScheduleMembers(self, name):
        """
        For each member using the given schedule, get the name and public key
        DER of the member's key.

        :param str name: The name of the schedule.
        :return: a new dictionary where the dictionary's key is the Name of the
          public key and the value is the Blob of the public key DER. Note that
          the member's identity name is keyName.getPrefix(-1). If the schedule
          name is not found, the dictionary is empty.
        :rtype: dictionary<Name, Blob>
        :raises GroupManagerDb.Error: For a database error.
        """
        dictionary = {}

        try:
            cursor = self._database.cursor()
            cursor.execute(
              "SELECT key_name, pubkey " +
              "FROM members JOIN schedules ON members.schedule_id=schedules.schedule_id " +
              "WHERE schedule_name=?",
              (name, ))
            results = cursor.fetchall()
            for (keyNameEncoding, keyEncoding) in results:
                keyName = Name()
                keyName.wireDecode(bytearray(keyNameEncoding), TlvWireFormat.get())
                dictionary[keyName] = Blob(bytearray(keyEncoding), False)
            cursor.close()

            return dictionary
        except Exception as ex:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.getScheduleMembers: SQLite error: " + str(ex))
    def getScheduleMembers(self, name):
        """
        For each member using the given schedule, get the name and public key
        DER of the member's key.

        :param str name: The name of the schedule.
        :return: a new dictionary where the dictionary's key is the Name of the
          public key and the value is the Blob of the public key DER. Note that
          the member's identity name is keyName.getPrefix(-1). If the schedule
          name is not found, the dictionary is empty.
        :rtype: dictionary<Name, Blob>
        :raises GroupManagerDb.Error: For a database error.
        """
        dictionary = {}

        try:
            cursor = self._database.cursor()
            cursor.execute(
                "SELECT key_name, pubkey "
                + "FROM members JOIN schedules ON members.schedule_id=schedules.schedule_id "
                + "WHERE schedule_name=?",
                (name,),
            )
            results = cursor.fetchall()
            for (keyNameEncoding, keyEncoding) in results:
                keyName = Name()
                keyName.wireDecode(bytearray(keyNameEncoding), TlvWireFormat.get())
                dictionary[keyName] = Blob(bytearray(keyEncoding), False)
            cursor.close()

            return dictionary
        except Exception as ex:
            raise GroupManagerDb.Error("Sqlite3GroupManagerDb.getScheduleMembers: SQLite error: " + str(ex))
    def updateMemberSchedule(self, identity, scheduleName):
        """
        Change the name of the schedule for the given member's identity name.

        :param Name identity: The member's identity name.
        :param str scheduleName: The new schedule name.
        :raises GroupManagerDb.Error: If there's no member with the given
          identity name in the database, or there's no schedule named
          scheduleName, or other database error.
        """
        scheduleId = self._getScheduleId(scheduleName)
        if scheduleId == -1:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.updateMemberSchedule: The schedule does not exist");

        try:
            cursor = self._database.cursor()
            cursor.execute(
              "UPDATE members SET schedule_id=? WHERE member_name=?",
              (scheduleId,
               sqlite3.Binary(bytearray(identity.wireEncode(TlvWireFormat.get()).buf()))))
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.updateMemberSchedule: SQLite error: " + str(ex))
Esempio n. 20
0
        def onData(self, interest, responseData):
            """
            We received the response.
            """
            # Decode responseData.getContent() and check for a success code.
            controlResponse = ControlResponse()
            try:
                controlResponse.wireDecode(responseData.getContent(),
                                           TlvWireFormat.get())
            except ValueError as ex:
                logging.getLogger(__name__).info(
                    "Register prefix failed: Error decoding the NFD response: %s",
                    str(ex))
                try:
                    self._onRegisterFailed(self._prefix)
                except:
                    logging.exception("Error in onRegisterFailed")
                return

            # Status code 200 is "OK".
            if controlResponse.getStatusCode() != 200:
                logging.getLogger(__name__).info(
                    "Register prefix failed: Expected NFD status code 200, got: %d",
                    controlResponse.getStatusCode())
                try:
                    self._onRegisterFailed(self._prefix)
                except:
                    logging.exception("Error in onRegisterFailed")
                return

            # Success, so we can add to the registered prefix table.
            if self._registeredPrefixId != 0:
                interestFilterId = 0
                if self._onInterest != None:
                    # registerPrefix was called with the "combined" form that includes
                    # the callback, so add an InterestFilterEntry.
                    interestFilterId = self._parent.getNextEntryId()
                    self._parent.setInterestFilter(
                        interestFilterId, InterestFilter(self._prefix),
                        self._onInterest, self._face)

                if not self._parent._registeredPrefixTable.add(
                        self._registeredPrefixId, self._prefix,
                        interestFilterId):
                    # removeRegisteredPrefix was already called with the registeredPrefixId.
                    if interestFilterId > 0:
                        # Remove the related interest filter we just added.
                        self._parent.unsetInterestFilter(interestFilterId)

                    return

            logging.getLogger(__name__).info(
                "Register prefix succeeded with the NFD forwarder for prefix %s",
                self._prefix.toUri())
            if self._onRegisterSuccess != None:
                try:
                    self._onRegisterSuccess(self._prefix,
                                            self._registeredPrefixId)
                except:
                    logging.exception("Error in onRegisterSuccess")
    def getMemberSchedule(self, identity):
        """
        Get the name of the schedule for the given member's identity name.

        :param Name identity: The member's identity name.
        :return: The name of the schedule.
        :rtype: str
        :raises GroupManagerDb.Error: If there's no member with the given
          identity name in the database, or other database error.
        """
        scheduleName = None

        try:
            cursor = self._database.cursor()
            cursor.execute(
              "SELECT schedule_name " +
              "FROM schedules JOIN members ON schedules.schedule_id = members.schedule_id " +
              "WHERE member_name=?",
              (sqlite3.Binary(bytearray(identity.wireEncode(TlvWireFormat.get()).buf())), ))
            result = cursor.fetchone()
            if result != None:
                scheduleName = result[0]
            cursor.close()
        except Exception as ex:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.getMemberSchedule: SQLite error: " + str(ex))

        if scheduleName == None:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.getMemberSchedule: Cannot get the result from the database")

        return scheduleName
Esempio n. 22
0
    def getKey(self, keyName):
        """
        Get the key with keyName from the database.

        :param Name keyName: The key name.
        :return: A Blob with the encoded key, or an isNull Blob if cannot find
          the key with keyName.
        :rtype: Blob
        :raises ConsumerDb.Error: For a database error.
        """
        try:
            cursor = self._database.cursor()
            cursor.execute(
              "SELECT key_buf FROM decryptionkeys WHERE key_name=?",
              (sqlite3.Binary(bytearray(keyName.wireEncode(TlvWireFormat.get()).buf())), ))
            result = cursor.fetchone()
            key = Blob()
            if result != None:
                return Blob(bytearray(result[0]), False)
            cursor.close()

            return key
        except Exception as ex:
            raise ConsumerDb.Error(
              "Sqlite3ConsumerDb.getKey: SQLite error: " + str(ex))
    def getMemberSchedule(self, identity):
        """
        Get the name of the schedule for the given member's identity name.

        :param Name identity: The member's identity name.
        :return: The name of the schedule.
        :rtype: str
        :raises GroupManagerDb.Error: If there's no member with the given
          identity name in the database, or other database error.
        """
        scheduleName = None

        try:
            cursor = self._database.cursor()
            cursor.execute(
                "SELECT schedule_name "
                + "FROM schedules JOIN members ON schedules.schedule_id = members.schedule_id "
                + "WHERE member_name=?",
                (sqlite3.Binary(bytearray(identity.wireEncode(TlvWireFormat.get()).buf())),),
            )
            result = cursor.fetchone()
            if result != None:
                scheduleName = result[0]
            cursor.close()
        except Exception as ex:
            raise GroupManagerDb.Error("Sqlite3GroupManagerDb.getMemberSchedule: SQLite error: " + str(ex))

        if scheduleName == None:
            raise GroupManagerDb.Error(
                "Sqlite3GroupManagerDb.getMemberSchedule: Cannot get the result from the database"
            )

        return scheduleName
Esempio n. 24
0
        def onData(self, interest, responseData):
            """
            We received the response.
            """
            # Decode responseData.getContent() and check for a success code.
            controlResponse = ControlResponse()
            try:
                controlResponse.wireDecode(responseData.getContent(), TlvWireFormat.get())
            except ValueError as ex:
                logging.getLogger(__name__).info(
                  "Register prefix failed: Error decoding the NFD response: %s",
                  str(ex))
                try:
                    self._onRegisterFailed(self._prefix)
                except:
                    logging.exception("Error in onRegisterFailed")
                return

            # Status code 200 is "OK".
            if controlResponse.getStatusCode() != 200:
                logging.getLogger(__name__).info(
                  "Register prefix failed: Expected NFD status code 200, got: %d",
                  controlResponse.getStatusCode())
                try:
                    self._onRegisterFailed(self._prefix)
                except:
                    logging.exception("Error in onRegisterFailed")
                return

            # Success, so we can add to the registered prefix table.
            if self._registeredPrefixId != 0:
                interestFilterId = 0
                if self._onInterest != None:
                    # registerPrefix was called with the "combined" form that includes
                    # the callback, so add an InterestFilterEntry.
                    interestFilterId = self._parent.getNextEntryId()
                    self._parent.setInterestFilter(
                      interestFilterId, InterestFilter(self._prefix),
                      self._onInterest, self._face)

                if not self._parent._registeredPrefixTable.add(
                      self._registeredPrefixId, self._prefix, interestFilterId):
                    # removeRegisteredPrefix was already called with the registeredPrefixId.
                    if interestFilterId > 0:
                        # Remove the related interest filter we just added.
                        self._parent.unsetInterestFilter(interestFilterId)

                    return

            logging.getLogger(__name__).info(
              "Register prefix succeeded with the NFD forwarder for prefix %s",
              self._prefix.toUri())
            if self._onRegisterSuccess != None:
                try:
                    self._onRegisterSuccess(self._prefix, self._registeredPrefixId)
                except:
                    logging.exception("Error in onRegisterSuccess")
Esempio n. 25
0
    def _nfdRegisterPrefix(self, registeredPrefixId, prefix, onInterest,
                           onRegisterFailed, flags, commandKeyChain,
                           commandCertificateName):
        """
        Do the work of registerPrefix to register with NFD.
        
        :param int registeredPrefixId: The 
          _RegisteredPrefix.getNextRegisteredPrefixId() which registerPrefix got
          so it could return it to the caller. If this is 0, then don't add to 
          registeredPrefixTable_ (assuming it has already been done).  
        """
        if commandKeyChain == None:
            raise RuntimeError(
                "registerPrefix: The command KeyChain has not been set. You must call setCommandSigningInfo."
            )
        if commandCertificateName.size() == 0:
            raise RuntimeError(
                "registerPrefix: The command certificate name has not been set. You must call setCommandSigningInfo."
            )

        controlParameters = ControlParameters()
        controlParameters.setName(prefix)

        commandInterest = Interest(Name("/localhost/nfd/rib/register"))
        # NFD only accepts TlvWireFormat packets.
        commandInterest.getName().append(
            controlParameters.wireEncode(TlvWireFormat.get()))
        self.makeCommandInterest(commandInterest, commandKeyChain,
                                 commandCertificateName, TlvWireFormat.get())
        # The interest is answered by the local host, so set a short timeout.
        commandInterest.setInterestLifetimeMilliseconds(2000.0)

        if registeredPrefixId != 0:
            # Save the onInterest callback and send the registration interest.
            self._registeredPrefixTable.append(
                Node._RegisteredPrefix(registeredPrefixId, prefix, onInterest))

        response = Node._RegisterResponse(self, prefix, onInterest,
                                          onRegisterFailed, flags,
                                          TlvWireFormat.get(), True)
        self.expressInterest(commandInterest, response.onData,
                             response.onTimeout, TlvWireFormat.get())
Esempio n. 26
0
    def _nfdRegisterPrefix(
      self, registeredPrefixId, prefix, onInterest, onRegisterFailed, flags,
      commandKeyChain, commandCertificateName):
        """
        Do the work of registerPrefix to register with NFD.

        :param int registeredPrefixId: The
          _RegisteredPrefix.getNextRegisteredPrefixId() which registerPrefix got
          so it could return it to the caller. If this is 0, then don't add to
          _registeredPrefixTable (assuming it has already been done).
        """
        if commandKeyChain == None:
            raise RuntimeError(
              "registerPrefix: The command KeyChain has not been set. You must call setCommandSigningInfo.")
        if commandCertificateName.size() == 0:
            raise RuntimeError(
              "registerPrefix: The command certificate name has not been set. You must call setCommandSigningInfo.")

        controlParameters = ControlParameters()
        controlParameters.setName(prefix)

        commandInterest = Interest(Name("/localhost/nfd/rib/register"))
        # NFD only accepts TlvWireFormat packets.
        commandInterest.getName().append(controlParameters.wireEncode(TlvWireFormat.get()))
        self.makeCommandInterest(
          commandInterest, commandKeyChain, commandCertificateName,
          TlvWireFormat.get())
        # The interest is answered by the local host, so set a short timeout.
        commandInterest.setInterestLifetimeMilliseconds(2000.0)

        if registeredPrefixId != 0:
            # Save the onInterest callback and send the registration interest.
            self._registeredPrefixTable.append(Node._RegisteredPrefix(
              registeredPrefixId, prefix, onInterest))

        response = Node._RegisterResponse(
          self, prefix, onInterest, onRegisterFailed, flags,
          TlvWireFormat.get(), True)
        self.expressInterest(
          commandInterest, response.onData, response.onTimeout,
          TlvWireFormat.get())
Esempio n. 27
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.
        
        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """
        # The type codes for TLV Interest and Data packets are chosen to not
        #   conflict with the first byte of a binary XML packet, so we canjust
        #   look at the first byte.
        if not (element[0] == Tlv.Interest or element[0] == Tlv.Data):
            # Ignore non-TLV elements.
            return

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

        # Now process as Interest or Data.
        if interest != None:
            entry = self._getEntryForRegisteredPrefix(interest.getName())
            if entry != None:
                entry.getOnInterest()(entry.getPrefix(), interest,
                                      self._transport,
                                      entry.getRegisteredPrefixId())
        elif data != None:
            pendingInterests = self._extractEntriesForExpressedInterest(
                data.getName())
            for pendingInterest in pendingInterests:
                pendingInterest.getOnData()(pendingInterest.getInterest(),
                                            data)
Esempio n. 28
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """
        # The type codes for TLV Interest and Data packets are chosen to not
        #   conflict with the first byte of a binary XML packet, so we canjust
        #   look at the first byte.
        if not (element[0] == Tlv.Interest or element[0] == Tlv.Data):
            # Ignore non-TLV elements.
            return

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

        # Now process as Interest or Data.
        if interest != None:
            entry = self._getEntryForRegisteredPrefix(interest.getName())
            if entry != None:
                entry.getOnInterest()(
                  entry.getPrefix(), interest, self._transport,
                  entry.getRegisteredPrefixId())
        elif data != None:
            pendingInterests = self._extractEntriesForExpressedInterest(
              data.getName())
            for pendingInterest in pendingInterests:
                pendingInterest.getOnData()(pendingInterest.getInterest(), data)
    def deleteMember(self, identity):
        """
        Delete a member with the given identity name. If there is no member with
        the identity name, then do nothing.

        :param Name identity: The member's identity name.
        :raises GroupManagerDb.Error: For a database error.
        """
        try:
            cursor = self._database.cursor()
            cursor.execute(
                "DELETE FROM members WHERE member_name=?",
                (sqlite3.Binary(bytearray(identity.wireEncode(TlvWireFormat.get()).buf())),),
            )
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise GroupManagerDb.Error("Sqlite3GroupManagerDb.deleteMember: SQLite error: " + str(ex))
Esempio n. 30
0
    def deleteKey(self, keyName):
        """
        Delete the key with keyName from the database. If there is no key with
        keyName, do nothing.

        :param Name keyName: The key name.
        :raises ConsumerDb.Error: For a database error.
        """
        try:
            cursor = self._database.cursor()
            cursor.execute(
              "DELETE FROM decryptionkeys WHERE key_name=?",
              (sqlite3.Binary(bytearray(keyName.wireEncode(TlvWireFormat.get()).buf())), ))
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise ConsumerDb.Error(
              "Sqlite3ConsumerDb.deleteKey: SQLite error: " + str(ex))
Esempio n. 31
0
    def deleteKey(self, keyName):
        """
        Delete the key with keyName from the database. If there is no key with
        keyName, do nothing.

        :param Name keyName: The key name.
        :raises ConsumerDb.Error: For a database error.
        """
        try:
            cursor = self._database.cursor()
            cursor.execute(
              "DELETE FROM decryptionkeys WHERE key_name=?",
              (sqlite3.Binary(bytearray(keyName.wireEncode(TlvWireFormat.get()).buf())), ))
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise ConsumerDb.Error(
              "Sqlite3ConsumerDb.deleteKey: SQLite error: " + str(ex))
    def deleteMember(self, identity):
        """
        Delete a member with the given identity name. If there is no member with
        the identity name, then do nothing.

        :param Name identity: The member's identity name.
        :raises GroupManagerDb.Error: For a database error.
        """
        try:
            cursor = self._database.cursor()
            cursor.execute(
              "DELETE FROM members WHERE member_name=?",
              (sqlite3.Binary(bytearray(identity.wireEncode(TlvWireFormat.get()).buf())), ))
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.deleteMember: SQLite error: " + str(ex))
    def deleteEKey(self, eKeyName):
        """
        Delete the EKey with name eKeyName from the database. If no key with the
        name exists in the database, do nothing.

        :param Name eKeyName: The name of the EKey.
        :raises GroupManagerDb.Error: For a database error.
        """
        try:
            cursor = self._database.cursor()
            cursor.execute(
              "DELETE FROM ekeys WHERE ekey_name=?",
              (sqlite3.Binary(bytearray(eKeyName.wireEncode(TlvWireFormat.get()).buf())), ))
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.deleteEKey: SQLite error: " + str(ex))

        del self._privateKeyBase[eKeyName]
Esempio n. 34
0
    def addKey(self, keyName, keyBlob):
        """
        Add the key with keyName and keyBlob to the database.

        :param Name keyName: The key name.
        :param Blob keyBlob: The encoded key.
        :raises ConsumerDb.Error: If a key with the same keyName already exists
          in the database, or other database error.
        """
        try:
            cursor = self._database.cursor()
            cursor.execute(
              "INSERT INTO decryptionkeys(key_name, key_buf) values (?, ?)",
              (sqlite3.Binary(bytearray(keyName.wireEncode(TlvWireFormat.get()).buf())),
               sqlite3.Binary(bytearray(keyBlob.buf()))))
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise ConsumerDb.Error(
              "Sqlite3ConsumerDb.addKey: SQLite error: " + str(ex))
Esempio n. 35
0
    def addKey(self, keyName, keyBlob):
        """
        Add the key with keyName and keyBlob to the database.

        :param Name keyName: The key name.
        :param Blob keyBlob: The encoded key.
        :raises ConsumerDb.Error: If a key with the same keyName already exists
          in the database, or other database error.
        """
        try:
            cursor = self._database.cursor()
            cursor.execute(
              "INSERT INTO decryptionkeys(key_name, key_buf) values (?, ?)",
              (sqlite3.Binary(bytearray(keyName.wireEncode(TlvWireFormat.get()).buf())),
               sqlite3.Binary(bytearray(keyBlob.buf()))))
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise ConsumerDb.Error(
              "Sqlite3ConsumerDb.addKey: SQLite error: " + str(ex))
Esempio n. 36
0
    def _encodeLpNack(interest, networkNack):
        """
        Encode the interest into an NDN-TLV LpPacket as a NACK with the reason
        code in the networkNack object.
        TODO: Generalize this and move to WireFormat.encodeLpPacket.
        
        :param Interest interest: The Interest to put in the LpPacket fragment.
        :param NetworkNack networkNack: The NetworkNack with the reason code.
        :return: A Blob containing the encoding.
        :rtype: Blob
        """
        encoder = TlvEncoder(256)
        saveLength = len(encoder)

        # Encode backwards.
        # Encode the fragment with the Interest.
        encoder.writeBlobTlv(
          Tlv.LpPacket_Fragment, interest.wireEncode(TlvWireFormat.get()).buf())

        # Encode the reason.
        if (networkNack.getReason() == NetworkNack.Reason.NONE or
             networkNack.getReason() == NetworkNack.Reason.CONGESTION or
             networkNack.getReason() == NetworkNack.Reason.DUPLICATE or
             networkNack.getReason() == NetworkNack.Reason.NO_ROUTE):
            # The Reason enum is set up with the correct integer for each NDN-TLV Reason.
            reason = networkNack.getReason()
        elif networkNack.getReason() == NetworkNack.Reason.OTHER_CODE:
            reason = networkNack.getOtherReasonCode()
        else:
            # We don't expect this to happen.
            raise RuntimeError("unrecognized NetworkNack.getReason() value")

        nackSaveLength = len(encoder)
        encoder.writeNonNegativeIntegerTlv(Tlv.LpPacket_NackReason, reason)
        encoder.writeTypeAndLength(
          Tlv.LpPacket_Nack, len(encoder) - nackSaveLength)

        encoder.writeTypeAndLength(
          Tlv.LpPacket_LpPacket, len(encoder) - saveLength)

        return Blob(encoder.getOutput(), False)
Esempio n. 37
0
    def _encodeLpNack(interest, networkNack):
        """
        Encode the interest into an NDN-TLV LpPacket as a NACK with the reason
        code in the networkNack object.
        TODO: Generalize this and move to WireFormat.encodeLpPacket.
        
        :param Interest interest: The Interest to put in the LpPacket fragment.
        :param NetworkNack networkNack: The NetworkNack with the reason code.
        :return: A Blob containing the encoding.
        :rtype: Blob
        """
        encoder = TlvEncoder(256)
        saveLength = len(encoder)

        # Encode backwards.
        # Encode the fragment with the Interest.
        encoder.writeBlobTlv(Tlv.LpPacket_Fragment,
                             interest.wireEncode(TlvWireFormat.get()).buf())

        # Encode the reason.
        if (networkNack.getReason() == NetworkNack.Reason.NONE
                or networkNack.getReason() == NetworkNack.Reason.CONGESTION
                or networkNack.getReason() == NetworkNack.Reason.DUPLICATE
                or networkNack.getReason() == NetworkNack.Reason.NO_ROUTE):
            # The Reason enum is set up with the correct integer for each NDN-TLV Reason.
            reason = networkNack.getReason()
        elif networkNack.getReason() == NetworkNack.Reason.OTHER_CODE:
            reason = networkNack.getOtherReasonCode()
        else:
            # We don't expect this to happen.
            raise RuntimeError("unrecognized NetworkNack.getReason() value")

        nackSaveLength = len(encoder)
        encoder.writeNonNegativeIntegerTlv(Tlv.LpPacket_NackReason, reason)
        encoder.writeTypeAndLength(Tlv.LpPacket_Nack,
                                   len(encoder) - nackSaveLength)

        encoder.writeTypeAndLength(Tlv.LpPacket_LpPacket,
                                   len(encoder) - saveLength)

        return Blob(encoder.getOutput(), False)
Esempio n. 38
0
File: node.py Progetto: MAHIS/PyNDN2
        def onData(self, interest, responseData):
            """
            We received the response. Do a quick check of expected name
            components.
            """
            # Decode responseData.getContent() and check for a success code.
            controlResponse = ControlResponse()
            try:
                controlResponse.wireDecode(responseData.getContent(), TlvWireFormat.get())
            except ValueError as ex:
                logging.getLogger(__name__).info(
                  "Register prefix failed: Error decoding the NFD response: %s",
                  str(ex))
                try:
                    self._onRegisterFailed(self._prefix)
                except:
                    logging.exception("Error in onRegisterFailed")
                return

            # Status code 200 is "OK".
            if controlResponse.getStatusCode() != 200:
                logging.getLogger(__name__).info(
                  "Register prefix failed: Expected NFD status code 200, got: %d",
                  controlResponse.getStatusCode())
                try:
                    self._onRegisterFailed(self._prefix)
                except:
                    logging.exception("Error in onRegisterFailed")
                return

            logging.getLogger(__name__).info(
              "Register prefix succeeded with the NFD forwarder for prefix %s",
              self._prefix.toUri())
            if self._onRegisterSuccess != None:
                try:
                    self._onRegisterSuccess(self._prefix, self._registeredPrefixId)
                except:
                    logging.exception("Error in onRegisterSuccess")
Esempio n. 39
0
    def wireEncode(self, wireFormat=None):
        """
        Encode this as an NDN-TLV SafeBag.

        :return: The encoded byte array as a Blob.
        :rtype: Blob
        """
        # Encode directly as TLV. We don't support the WireFormat abstraction
        # because this isn't meant to go directly on the wire.
        encoder = TlvEncoder(256)
        saveLength = len(encoder)

        # Encode backwards.
        encoder.writeBlobTlv(Tlv.SafeBag_EncryptedKeyBag,
                             self._privateKeyBag.buf())
        # Add the entire Data packet encoding as is.
        encoder.writeBuffer(
            self._certificate.wireEncode(TlvWireFormat.get()).buf())

        encoder.writeTypeAndLength(Tlv.SafeBag_SafeBag,
                                   len(encoder) - saveLength)

        return Blob(encoder.getOutput(), False)
    def addEKey(self, eKeyName, publicKey, privateKey):
        """
        Add the EKey with name eKeyName to the database.

        :param Name eKeyName: The name of the EKey. This copies the Name.
        :param Blob publicKey: The encoded public key of the group key pair.
        :param Blob privateKey: The encoded private key of the group key pair.
        :raises GroupManagerDb.Error: If a key with name eKeyName already exists
          in the database, or other database error.
        """
        try:
            cursor = self._database.cursor()
            cursor.execute(
              "INSERT INTO ekeys(ekey_name, pub_key) values (?, ?)",
              (sqlite3.Binary(bytearray(eKeyName.wireEncode(TlvWireFormat.get()).buf())),
               sqlite3.Binary(bytearray(publicKey.buf()))))
            self._database.commit()
            cursor.close()
        except Exception as ex:
            raise GroupManagerDb.Error(
              "Sqlite3GroupManagerDb.addEKey: SQLite error: " + str(ex))

        self._privateKeyBase[Name(eKeyName)] = privateKey
    def listAllMembers(self):
        """
        List all the members.

        :return: A new List of Name with the names of all members.
        :rtype: Array<Name>
        :raises GroupManagerDb.Error: For a database error.
        """
        list = []

        try:
            cursor = self._database.cursor()
            cursor.execute("SELECT member_name FROM members", ())
            results = cursor.fetchall()
            for (nameEncoding,) in results:
                identity = Name()
                identity.wireDecode(bytearray(nameEncoding), TlvWireFormat.get())
                list.append(identity)
            cursor.close()

            return list
        except Exception as ex:
            raise GroupManagerDb.Error("Sqlite3GroupManagerDb.listAllMembers: SQLite error: " + str(ex))
Esempio n. 42
0
    def wireEncode(self, wireFormat = None):
        """
        Encode this as an NDN-TLV SafeBag.

        :return: The encoded byte array as a Blob.
        :rtype: Blob
        """
        # Encode directly as TLV. We don't support the WireFormat abstraction
        # because this isn't meant to go directly on the wire.
        encoder = TlvEncoder(256)
        saveLength = len(encoder)

        # Encode backwards.
        encoder.writeBlobTlv(
          Tlv.SafeBag_EncryptedKeyBag, self._privateKeyBag.buf())
        # Add the entire Data packet encoding as is.
        encoder.writeBuffer(
          self._certificate.wireEncode(TlvWireFormat.get()).buf())

        encoder.writeTypeAndLength(
          Tlv.SafeBag_SafeBag, len(encoder) - saveLength)

        return Blob(encoder.getOutput(), False)
    def hasMember(self, identity):
        """
        Check if there is a member with the given identity name.

        :param Name identity: The member's identity name.
        :return: True if there is a member.
        :rtype: bool
        :raises GroupManagerDb.Error: For a database error.
        """
        result = False

        try:
            cursor = self._database.cursor()
            cursor.execute(
                "SELECT member_id FROM members WHERE member_name=?",
                (sqlite3.Binary(bytearray(identity.wireEncode(TlvWireFormat.get()).buf())),),
            )
            if cursor.fetchone() != None:
                result = True

            cursor.close()
            return result
        except Exception as ex:
            raise GroupManagerDb.Error("Sqlite3GroupManagerDb.hasMember: SQLite error: " + str(ex))
Esempio n. 44
0
    def encryptData(data, payload, keyName, key, params):
        """
        Prepare an encrypted data packet by encrypting the payload using the key
        according to the params. In addition, this prepares the encoded
        EncryptedContent with the encryption result using keyName and params.
        The encoding is set as the content of the data packet. If params defines
        an asymmetric encryption algorithm and the payload is larger than the
        maximum plaintext size, this encrypts the payload with a symmetric key
        that is asymmetrically encrypted and provided as a nonce in the content
        of the data packet. The packet's <dataName>/ is updated to be
        <dataName>/FOR/<keyName>

        :param Data data: The data packet which is updated.
        :param Blob payload: The payload to encrypt.
        :param Name keyName: The key name for the EncryptedContent.
        :param Blob key: The encryption key value.
        :param EncryptParams params: The parameters for encryption.
        """
        data.getName().append(Encryptor.NAME_COMPONENT_FOR).append(keyName)

        algorithmType = params.getAlgorithmType()

        if (algorithmType == EncryptAlgorithmType.AesCbc
                or algorithmType == EncryptAlgorithmType.AesEcb):
            content = Encryptor._encryptSymmetric(payload, key, keyName,
                                                  params)
            data.setContent(content.wireEncode(TlvWireFormat.get()))
        elif (algorithmType == EncryptAlgorithmType.RsaPkcs
              or algorithmType == EncryptAlgorithmType.RsaOaep):
            # Cryptography doesn't have a direct way to get the maximum plain text
            # size, so try to encrypt the payload first and catch the error if
            # it is too big.
            try:
                content = Encryptor._encryptAsymmetric(payload, key, keyName,
                                                       params)
                data.setContent(content.wireEncode(TlvWireFormat.get()))
                return
            except ValueError as ex:
                message = ex.args[0]
                if not ("Data too long for key size" in message):
                    raise ex
                # Else the payload is larger than the maximum plaintext size. Continue.

            # 128-bit nonce.
            nonceKeyBuffer = bytearray(16)
            for i in range(16):
                nonceKeyBuffer[i] = _systemRandom.randint(0, 0xff)
            nonceKey = Blob(nonceKeyBuffer, False)

            nonceKeyName = Name(keyName)
            nonceKeyName.append("nonce")

            symmetricParams = EncryptParams(EncryptAlgorithmType.AesCbc,
                                            AesAlgorithm.BLOCK_SIZE)

            nonceContent = Encryptor._encryptSymmetric(payload, nonceKey,
                                                       nonceKeyName,
                                                       symmetricParams)

            payloadContent = Encryptor._encryptAsymmetric(
                nonceKey, key, keyName, params)

            nonceContentEncoding = nonceContent.wireEncode()
            payloadContentEncoding = payloadContent.wireEncode()
            content = bytearray(nonceContentEncoding.size() +
                                payloadContentEncoding.size())
            content[0:payloadContentEncoding.size(
            )] = payloadContentEncoding.buf()
            content[payloadContentEncoding.size():] = nonceContentEncoding.buf(
            )

            data.setContent(Blob(content, False))
        else:
            raise RuntimeError("Unsupported encryption method")
Esempio n. 45
0
    def encryptData(data, payload, keyName, key, params):
        """
        Prepare an encrypted data packet by encrypting the payload using the key
        according to the params. In addition, this prepares the encoded
        EncryptedContent with the encryption result using keyName and params.
        The encoding is set as the content of the data packet. If params defines
        an asymmetric encryption algorithm and the payload is larger than the
        maximum plaintext size, this encrypts the payload with a symmetric key
        that is asymmetrically encrypted and provided as a nonce in the content
        of the data packet. The packet's <dataName>/ is updated to be
        <dataName>/FOR/<keyName>

        :param Data data: The data packet which is updated.
        :param Blob payload: The payload to encrypt.
        :param Name keyName: The key name for the EncryptedContent.
        :param Blob key: The encryption key value.
        :param EncryptParams params: The parameters for encryption.
        """
        data.getName().append(Encryptor.NAME_COMPONENT_FOR).append(keyName)

        algorithmType = params.getAlgorithmType()

        if (algorithmType == EncryptAlgorithmType.AesCbc or
            algorithmType == EncryptAlgorithmType.AesEcb):
            content = Encryptor._encryptSymmetric(payload, key, keyName, params)
            data.setContent(content.wireEncode(TlvWireFormat.get()))
        elif (algorithmType == EncryptAlgorithmType.RsaPkcs or
              algorithmType == EncryptAlgorithmType.RsaOaep):
            # Cryptography doesn't have a direct way to get the maximum plain text
            # size, so try to encrypt the payload first and catch the error if
            # it is too big.
            try:
                content = Encryptor._encryptAsymmetric(payload, key, keyName, params)
                data.setContent(content.wireEncode(TlvWireFormat.get()))
                return
            except ValueError as ex:
                message = ex.args[0]
                if not ("Data too long for key size" in message):
                    raise ex
                # Else the payload is larger than the maximum plaintext size. Continue.

            # 128-bit nonce.
            nonceKeyBuffer = bytearray(16)
            for i in range(16):
                nonceKeyBuffer[i] = _systemRandom.randint(0, 0xff)
            nonceKey = Blob(nonceKeyBuffer, False)

            nonceKeyName = Name(keyName)
            nonceKeyName.append("nonce")

            symmetricParams =  EncryptParams(
              EncryptAlgorithmType.AesCbc, AesAlgorithm.BLOCK_SIZE)

            nonceContent = Encryptor._encryptSymmetric(
              payload, nonceKey, nonceKeyName, symmetricParams)

            payloadContent = Encryptor._encryptAsymmetric(
              nonceKey, key, keyName, params)

            nonceContentEncoding = nonceContent.wireEncode()
            payloadContentEncoding = payloadContent.wireEncode()
            content = bytearray(
              nonceContentEncoding.size() + payloadContentEncoding.size())
            content[0:payloadContentEncoding.size()] = payloadContentEncoding.buf()
            content[payloadContentEncoding.size():] = nonceContentEncoding.buf()

            data.setContent(Blob(content, False))
        else:
            raise RuntimeError("Unsupported encryption method")
Esempio n. 46
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                interest.setLpPacket(lpPacket)
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        if lpPacket != None:
            # We have decoded the fragment, so remove the wire encoding to save
            #   memory.
            lpPacket.setFragmentWireEncoding(Blob())

            networkNack = NetworkNack.getFirstHeader(lpPacket)
            if networkNack != None:
                if interest == None:
                    # We got a Nack but not for an Interest, so drop the packet.
                    return

                pendingInterests = []
                self._pendingInterestTable.extractEntriesForNackInterest(
                    interest, pendingInterests)
                for pendingInterest in pendingInterests:
                    try:
                        pendingInterest.getOnNetworkNack()(
                            pendingInterest.getInterest(), networkNack)
                    except:
                        logging.exception("Error in onNetworkNack")

                # We have processed the network Nack packet.
                return

        # Now process as Interest or Data.
        if interest != None:
            self._dispatchInterest(interest)
        elif data != None:
            self._satisfyPendingInterests(data)
Esempio n. 47
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                interest.setLpPacket(lpPacket)
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        if lpPacket != None:
            # We have decoded the fragment, so remove the wire encoding to save
            #   memory.
            lpPacket.setFragmentWireEncoding(Blob())

            networkNack = NetworkNack.getFirstHeader(lpPacket)
            if networkNack != None:
                if interest == None:
                    # We got a Nack but not for an Interest, so drop the packet.
                    return

                pendingInterests = []
                self._pendingInterestTable.extractEntriesForNackInterest(
                  interest, pendingInterests)
                for pendingInterest in pendingInterests:
                    try:
                        pendingInterest.getOnNetworkNack()(
                          pendingInterest.getInterest(), networkNack)
                    except:
                        logging.exception("Error in onNetworkNack")

                # We have processed the network Nack packet.
                return

        # Now process as Interest or Data.
        if interest != None:
            self._dispatchInterest(interest)
        elif data != None:
            self._satisfyPendingInterests(data)
Esempio n. 48
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                interest.setLpPacket(lpPacket)
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        if lpPacket != None:
            # We have decoded the fragment, so remove the wire encoding to save
            #   memory.
            lpPacket.setFragmentWireEncoding(Blob())

            networkNack = NetworkNack.getFirstHeader(lpPacket)
            if networkNack != None:
                if interest == None:
                    # We got a Nack but not for an Interest, so drop the packet.
                    return

                pendingInterests = []
                self._pendingInterestTable.extractEntriesForNackInterest(
                    interest, pendingInterests)
                for pendingInterest in pendingInterests:
                    try:
                        pendingInterest.getOnNetworkNack()(
                            pendingInterest.getInterest(), networkNack)
                    except:
                        logging.exception("Error in onNetworkNack")

                # We have processed the network Nack packet.
                return

        # Now process as Interest or Data.
        if interest != None:
            # Call all interest filter callbacks which match.
            matchedFilters = []
            self._interestFilterTable.getMatchedFilters(
                interest, matchedFilters)
            for i in range(len(matchedFilters)):
                entry = matchedFilters[i]
                includeFilter = True
                onInterestCall = entry.getOnInterest()
                # If onInterest is not a function nor a method assumes it is a
                # calleable object
                if (not inspect.isfunction(onInterestCall)
                        and not inspect.ismethod(onInterestCall)):
                    onInterestCall = onInterestCall.__call__
                # Use getcallargs to test if onInterest accepts 5 args.
                try:
                    inspect.getcallargs(onInterestCall, None, None, None, None,
                                        None)
                except TypeError:
                    # Assume onInterest is old-style with 4 arguments.
                    includeFilter = False

                if includeFilter:
                    try:
                        entry.getOnInterest()(entry.getFilter().getPrefix(),
                                              interest, entry.getFace(),
                                              entry.getInterestFilterId(),
                                              entry.getFilter())
                    except:
                        logging.exception("Error in onInterest")
                else:
                    # Old-style onInterest without the filter argument. We
                    # still pass a Face instead of Transport since Face also
                    # has a send method.
                    try:
                        entry.getOnInterest()(entry.getFilter().getPrefix(),
                                              interest, entry.getFace(),
                                              entry.getInterestFilterId())
                    except:
                        logging.exception("Error in onInterest")
        elif data != None:
            pendingInterests = []
            self._pendingInterestTable.extractEntriesForExpressedInterest(
                data, pendingInterests)
            for pendingInterest in pendingInterests:
                try:
                    pendingInterest.getOnData()(pendingInterest.getInterest(),
                                                data)
                except:
                    logging.exception("Error in onData")
Esempio n. 49
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """
        # The type codes for TLV Interest and Data packets are chosen to not
        #   conflict with the first byte of a binary XML packet, so we canjust
        #   look at the first byte.
        if not (element[0] == Tlv.Interest or element[0] == Tlv.Data):
            # Ignore non-TLV elements.
            # Assume it is Binary XML.
            if not WireFormat.ENABLE_NDNX:
                raise RuntimeError(
                  "BinaryXmlWireFormat (NDNx) is deprecated. To enable while you upgrade your network to use NDN-TLV, set WireFormat.ENABLE_NDNX = True")

            return

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

        # Now process as Interest or Data.
        if interest != None:
            # Call all interest filter callbacks which match.
            for i in range(len(self._interestFilterTable)):
                entry = self._interestFilterTable[i]
                if entry.getFilter().doesMatch(interest.getName()):
                    includeFilter = True
                    # Use getcallargs to test if onInterest accepts 5 args.
                    try:
                        inspect.getcallargs(entry.getOnInterest(),
                          None, None, None, None, None)
                    except TypeError:
                        # Assume onInterest is old-style with 4 arguments.
                        includeFilter = False

                    if includeFilter:
                        entry.getOnInterest()(
                          entry.getFilter().getPrefix(), interest,
                          entry.getFace(), entry.getInterestFilterId(),
                          entry.getFilter())
                    else:
                        # Old-style onInterest without the filter argument. We
                        # still pass a Face instead of Transport since Face also
                        # has a send method.
                        entry.getOnInterest()(
                          entry.getFilter().getPrefix(), interest,
                          entry.getFace(), entry.getInterestFilterId())
        elif data != None:
            pendingInterests = self._extractEntriesForExpressedInterest(
              data.getName())
            for pendingInterest in pendingInterests:
                pendingInterest.getOnData()(pendingInterest.getInterest(), data)
Esempio n. 50
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                interest.setLpPacket(lpPacket)
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        if lpPacket != None:
            # We have decoded the fragment, so remove the wire encoding to save
            #   memory.
            lpPacket.setFragmentWireEncoding(Blob())

            networkNack = NetworkNack.getFirstHeader(lpPacket)
            if networkNack != None:
                if interest == None:
                    # We got a Nack but not for an Interest, so drop the packet.
                    return

                pendingInterests = []
                self._pendingInterestTable.extractEntriesForNackInterest(
                  interest, pendingInterests)
                for pendingInterest in pendingInterests:
                    try:
                        pendingInterest.getOnNetworkNack()(
                          pendingInterest.getInterest(), networkNack)
                    except:
                        logging.exception("Error in onNetworkNack")

                # We have processed the network Nack packet.
                return

        # Now process as Interest or Data.
        if interest != None:
            # Call all interest filter callbacks which match.
            matchedFilters = []
            self._interestFilterTable.getMatchedFilters(interest, matchedFilters)
            for i in range(len(matchedFilters)):
                entry = matchedFilters[i]
                includeFilter = True
                onInterestCall = entry.getOnInterest()
                # If onInterest is not a function nor a method assumes it is a
                # calleable object
                if (not inspect.isfunction(onInterestCall) and
                    not inspect.ismethod(onInterestCall)):
                    onInterestCall = onInterestCall.__call__
                # Use getcallargs to test if onInterest accepts 5 args.
                try:
                    inspect.getcallargs(onInterestCall,
                      None, None, None, None, None)
                except TypeError:
                    # Assume onInterest is old-style with 4 arguments.
                    includeFilter = False

                if includeFilter:
                    try:
                        entry.getOnInterest()(
                          entry.getFilter().getPrefix(), interest,
                          entry.getFace(), entry.getInterestFilterId(),
                          entry.getFilter())
                    except:
                        logging.exception("Error in onInterest")
                else:
                    # Old-style onInterest without the filter argument. We
                    # still pass a Face instead of Transport since Face also
                    # has a send method.
                    try:
                        entry.getOnInterest()(
                          entry.getFilter().getPrefix(), interest,
                          entry.getFace(), entry.getInterestFilterId())
                    except:
                        logging.exception("Error in onInterest")
        elif data != None:
            pendingInterests = []
            self._pendingInterestTable.extractEntriesForExpressedInterest(
              data, pendingInterests)
            for pendingInterest in pendingInterests:
                try:
                    pendingInterest.getOnData()(pendingInterest.getInterest(), data)
                except:
                    logging.exception("Error in onData")