def startTrustSchemaUpdate(self, appPrefix, onUpdateSuccess = None, onUpdateFailed = None): """ Starts trust schema update for under an application prefix: initial interest asks for the rightMostChild, and later interests are sent with previous version excluded. Each verified trust schema will trigger onUpdateSuccess and update the ConfigPolicyManager for the keyChain in this instance, and unverified ones will trigger onUpdateFailed. The keyChain and trust anchor should be set up using setupDefaultIdentityAndRoot before calling this method. :param appPrefix: the prefix to ask trust schema for. (interest name: /<prefix>/_schema) :type appPrefix: Name :param onUpdateSuccess: (optional) onUpdateSuccess(trustSchemaStr, isInitial) is called when update succeeds :type onUpdateSuccess: function object :param onUpdateFailed: (optional) onUpdateFailed(msg) is called when update fails :type onUpdateFailed: function object """ namespace = appPrefix.toUri() if namespace in self._trustSchemas: if self._trustSchemas[namespace]["following"] == True: print "Already following trust schema under this namespace!" return self._trustSchemas[namespace]["following"] = True else: self._trustSchemas[namespace] = {"following": True, "version": 0, "is-initial": True} initialInterest = Interest(Name(namespace).append("_schema")) initialInterest.setChildSelector(1) self._face.expressInterest(initialInterest, lambda interest, data: self.onTrustSchemaData(interest, data, onUpdateSuccess, onUpdateFailed), lambda interest: self.onTrustSchemaTimeout(interest, onUpdateSuccess, onUpdateFailed)) return
def startPublishingAggregation(self, params, childrenList, dataType, aggregationType): if __debug__: print('Start publishing for ' + dataType + '-' + aggregationType) # aggregation calculating and publishing mechanism publishingPrefix = Name(self._identityName).append(DATA_COMPONENT).append(dataType).append(AGGREGATION_COMPONENT).append(aggregationType) self._dataQueue[dataType + aggregationType] = DataQueue(params, childrenList, publishingPrefix) if len(childrenList.keys()) == 0: # TODO: make start_time optional for leaf nodes self._loop.call_later(int(params['producer_interval']), self.calculateAggregation, dataType, aggregationType, childrenList, int(params['start_time']), int(params['producer_interval']), publishingPrefix, True) else: # express interest for children who produce the same data and aggregation type for childName in childrenList.keys(): name = Name(self._identityName).append(childName).append(DATA_COMPONENT).append(dataType).append(AGGREGATION_COMPONENT).append(aggregationType) interest = Interest(name) # if start_time is specified, we ask for data starting at start_time; # if not, we ask for the right most child and go from there if ('start_time' in childrenList[childName]): endTime = int(childrenList[childName]['start_time']) + int(childrenList[childName]['producer_interval']) interest.getName().append(str(childrenList[childName]['start_time'])).append(str(endTime)) else: # TODO: For now we are playing with historical data, for each run we don't want to miss any data, thus we start with leftMost interest.setChildSelector(0) interest.setMustBeFresh(True) interest.setInterestLifetimeMilliseconds(DEFAULT_INTEREST_LIFETIME) if __debug__: print(' Issue interest: ' + interest.getName().toUri()) self._face.expressInterest(interest, self.onData, self.onTimeout) return
def _sendCertificateRequest(self, keyIdentity): """ We compose a command interest with our public key info so the controller can sign us a certificate that can be used with other nodes in the network. """ try: defaultKey = self._identityStorage.getDefaultKeyNameForIdentity(keyIdentity) except SecurityException: defaultKey = self._identityManager.generateRSAKeyPairAsDefault(keyIdentity) self.log.debug("Key name: " + defaultKey.toUri()) message = CertificateRequestMessage() publicKey = self._identityManager.getPublicKey(defaultKey) message.command.keyType = publicKey.getKeyType() message.command.keyBits = publicKey.getKeyDer().toRawStr() for component in range(defaultKey.size()): message.command.keyName.components.append(defaultKey.get(component).toEscapedString()) paramComponent = ProtobufTlv.encode(message) interestName = Name(self._policyManager.getTrustRootIdentity()).append("certificateRequest").append(paramComponent) interest = Interest(interestName) interest.setInterestLifetimeMilliseconds(10000) # takes a tick to verify and sign self._hmacHandler.signInterest(interest, keyName=self.prefix) self.log.info("Sending certificate request to controller") self.log.debug("Certificate request: "+interest.getName().toUri()) self.face.expressInterest(interest, self._onCertificateReceived, self._onCertificateTimeout)
def main(): # Silence the warning from Interest wire encode. Interest.setDefaultCanBePrefix(True) # The default Face will connect using a Unix socket, or to "localhost". face = Face() counter = Counter() if sys.version_info[0] <= 2: word = raw_input("Enter a word to echo: ") else: word = input("Enter a word to echo: ") name = Name("/testecho") name.append(word) dump("Express name ", name.toUri()) face.expressInterest(name, counter.onData, counter.onTimeout) while counter._callbackCount < 1: face.processEvents() # We need to sleep for a few milliseconds so we don't use 100% of the CPU. time.sleep(0.01) face.shutdown()
def _scanForUnconfiguredDevices(self): # unconfigured devices should register '/localhop/configure' # we keep asking for unconfigured devices until we stop getting replies foundDevices = [] self.ui.alert("Scanning for unconfigured devices...", False) def onDeviceTimeout(interest): # assume we're done - everyone is excluded self.unconfiguredDevices = foundDevices self.loop.call_soon(self._showConfigurationList) def onDeviceResponse(interest, data): updatedInterest = Interest(interest) deviceSerial = str(data.getContent()) if len(deviceSerial) > 0: foundDevices.append(deviceSerial) updatedInterest.getExclude().appendComponent(Name.Component(deviceSerial)) # else ignore the malformed response self.face.expressInterest(updatedInterest, onDeviceResponse, onDeviceTimeout) interest = Interest(Name("/localhop/configure")) interest.setInterestLifetimeMilliseconds(2000) self.face.expressInterest(interest, onDeviceResponse, onDeviceTimeout)
def _updateCapabilities(self): """ Send the controller a list of our commands. """ fullCommandName = Name(self._policyManager.getTrustRootIdentity() ).append('updateCapabilities') capabilitiesMessage = UpdateCapabilitiesCommandMessage() for command in self._commands: commandName = Name(self.prefix).append(Name(command.suffix)) capability = capabilitiesMessage.capabilities.add() for i in range(commandName.size()): capability.commandPrefix.components.append( str(commandName.get(i).getValue())) for kw in command.keywords: capability.keywords.append(kw) capability.needsSignature = command.isSigned encodedCapabilities = ProtobufTlv.encode(capabilitiesMessage) fullCommandName.append(encodedCapabilities) interest = Interest(fullCommandName) interest.setInterestLifetimeMilliseconds(5000) self.face.makeCommandInterest(interest) signature = self._policyManager._extractSignature(interest) self.log.info("Sending capabilities to controller") self.face.expressInterest(interest, self._onCapabilitiesAck, self._onCapabilitiesTimeout) # update twice a minute self.loop.call_later(30, self._updateCapabilities)
def expressInterest(self, interestTemplate = None): """ Call expressInterest on this (or a parent's) Face where the interest name is the name of this Namespace node. When the Data packet is received this calls setData, so you should use a callback with addOnContentSet. This uses ExponentialReExpress to re-express a timed-out interest with longer lifetimes. TODO: How to alert the application on a final interest timeout? TODO: Replace this by a mechanism for requesting a Data object which is more general than a Face network operation. :raises RuntimeError: If a Face object has not been set for this or a parent Namespace node. :param Interest interestTemplate: (optional) The interest template for expressInterest. If omitted, just use a default interest lifetime. """ face = self._getFace() if face == None: raise ValueError("A Face object has not been set for this or a parent.") def onData(interest, data): self[data.name].setData(data) if interestTemplate == None: interestTemplate = Interest() interestTemplate.setInterestLifetimeMilliseconds(4000) face.expressInterest( self._name, interestTemplate, onData, ExponentialReExpress.makeOnTimeout(face, onData, None))
def consume(self, prefix, onVerified, onVerifyFailed, onTimeout): """ Consume data continuously under a given prefix, maintaining pipelineSize number of interest in the pipeline :param name: prefix to consume data under :type name: Name :param onData: onData(data) gets called after received data's onVerifyFailed :type onData: function object :param onVerifyFailed: onVerifyFailed(data) gets called if received data cannot be verified :type onVerifyFailed: function object :param onTimeout: onTimeout(interest) gets called if a consumer interest times out :type onTimeout: function object """ num = self._emptySlot for i in range(0, num): name = Name(prefix).append(str(self._currentSeqNumber)) interest = Interest(name) # interest configuration / template? interest.setInterestLifetimeMilliseconds(self._defaultInterestLifetime) self._face.expressInterest(interest, lambda i, d : self.onData(i, d, onVerified, onVerifyFailed, onTimeout), lambda i: self.beforeReplyTimeout(i, onVerified, onVerifyFailed, onTimeout)) self._currentSeqNumber += 1 self._emptySlot -= 1 return
def onHeartbeatTimeout(self, interest): if self.incrementTimeoutCnt(interest.getName().toUri()): print "Remove: " + interest.getName().toUri() + " because of consecutive timeout cnt exceeded" else: newInterest = Interest(interest.getName()) newInterest.setInterestLifetimeMilliseconds(4000) self._face.expressInterest(newInterest, self.onHeartbeatData, self.onHeartbeatTimeout)
def main(): # The default Face connects to the local NFD. face = Face() interest = Interest(Name("/localhost/nfd/faces/list")) interest.setInterestLifetimeMilliseconds(4000) dump("Express interest", interest.getName().toUri()) enabled = [True] def onComplete(content): enabled[0] = False printFaceStatuses(content) def onError(errorCode, message): enabled[0] = False dump(message) SegmentFetcher.fetch( face, interest, SegmentFetcher.DontVerifySegment, onComplete, onError) # Loop calling processEvents until a callback sets enabled[0] = False. while enabled[0]: face.processEvents() # We need to sleep for a few milliseconds so we don't use 100% of the CPU. time.sleep(0.01)
def main(): # Silence the warning from Interest wire encode. Interest.setDefaultCanBePrefix(True) loop = asyncio.get_event_loop() face = ThreadsafeFace(loop, "memoria.ndn.ucla.edu") # Counter will stop the ioService after callbacks for all expressInterest. counter = Counter(loop, 3) # Try to fetch anything. name1 = Name("/") dump("Express name ", name1.toUri()) # These call to exressIinterest is thread safe because face is a ThreadsafeFace. face.expressInterest(name1, counter.onData, counter.onTimeout) # Try to fetch using a known name. name2 = Name("/ndn/edu/ucla/remap/demo/ndn-js-test/hello.txt/%FDU%8D%9DM") dump("Express name ", name2.toUri()) face.expressInterest(name2, counter.onData, counter.onTimeout) # Expect this to time out. name3 = Name("/test/timeout") dump("Express name ", name3.toUri()) face.expressInterest(name3, counter.onData, counter.onTimeout) # Run until the Counter calls stop(). loop.run_forever() face.shutdown()
def helper(identityName, signerName): try: self._defaultIdentity = identityName self._defaultCertificateName = self._identityManager.getDefaultCertificateNameForIdentity(self._defaultIdentity) self._defaultKeyName = self._identityManager.getDefaultKeyNameForIdentity(identityName) except SecurityException: msg = "Identity " + identityName.toUri() + " in configuration does not exist. Please configure the device with this identity first." if onSetupFailed: onSetupFailed(msg) return if not self._defaultCertificateName: msg = "Unable to get default certificate name for identity " + identityName.toUri() + ". Please configure the device with this identity first." if onSetupFailed: onSetupFailed(msg) return if not self._defaultKeyName: msg = "Unable to get default key name for identity " + identityName.toUri() + ". Please configure the device with this identity first." if onSetupFailed: onSetupFailed(msg) return # Note we'll not be able to issue face commands before this point self._face.setCommandSigningInfo(self._keyChain, self._defaultCertificateName) # Serve our own certificate self._certificateContentCache.registerPrefix(Name(self._defaultCertificateName).getPrefix(-1), self.onRegisterFailed) self._certificateContentCache.add(self._keyChain.getCertificate(self._defaultCertificateName)) actualSignerName = self._keyChain.getCertificate(self._defaultCertificateName).getSignature().getKeyLocator().getKeyName() if not signerName: print "Deriving from " + actualSignerName.toUri() + " for controller name" else: if signerName and actualSignerName.toUri() != signerName.toUri(): msg = "Configuration signer names mismatch: expected " + signerName.toUri() + "; got " + actualSignerName.toUri() print msg if onSetupFailed: onSetupFailed(msg) self._controllerName = self.getIdentityNameFromCertName(actualSignerName) print "Controller name: " + self._controllerName.toUri() try: self._controllerCertificate = self._keyChain.getCertificate(self._identityManager.getDefaultCertificateNameForIdentity(self._controllerName)) # TODO: this does not seem a good approach, implementation-wise and security implication self._policyManager._certificateCache.insertCertificate(self._controllerCertificate) if onSetupComplete: onSetupComplete(Name(self._defaultCertificateName), self._keyChain) except SecurityException as e: print "don't have controller certificate " + actualSignerName.toUri() + " yet" controllerCertInterest = Interest(Name(actualSignerName)) controllerCertInterest.setInterestLifetimeMilliseconds(4000) controllerCertRetries = 3 self._face.expressInterest(controllerCertInterest, lambda interest, data: self.onControllerCertData(interest, data, onSetupComplete, onSetupFailed), lambda interest: self.onControllerCertTimeout(interest, onSetupComplete, onSetupFailed, controllerCertRetries)) return
def _onData(self, interest, data): """ Process the incoming Chat data. """ # TODO: Check if this works in Python 3. content = chatbuf_pb2.ChatMessage() content.ParseFromString(data.getContent().toRawStr()) if self.getNowMilliseconds() - content.timestamp * 1000.0 < 120000.0: # Use getattr because "from" is a reserved keyword. name = getattr(content, "from") prefix = data.getName().getPrefix(-2).toUri() sessionNo = int(data.getName().get(-2).toEscapedString()) sequenceNo = int(data.getName().get(-1).toEscapedString()) nameAndSession = name + str(sessionNo) l = 0 # Update roster. while l < len(self._roster): entry = self._roster[l] tempName = entry[0:len(entry) - 10] tempSessionNo = int(entry[len(entry) - 10:]) if (name != tempName and content.type != chatbuf_pb2.ChatMessage.LEAVE): l += 1 else: if name == tempName and sessionNo > tempSessionNo: self._roster[l] = nameAndSession break if l == len(self._roster): self._roster.append(nameAndSession) print(name + ": Join") # Set the alive timeout using the Interest timeout mechanism. # TODO: Are we sure using a "/local/timeout" interest is the best # future call approach? timeout = Interest(Name("/local/timeout")) timeout.setInterestLifetimeMilliseconds(120000) self._face.expressInterest( timeout, self._dummyOnData, self._makeAlive(sequenceNo, name, sessionNo, prefix)) # isRecoverySyncState_ was set by sendInterest. # TODO: If isRecoverySyncState_ changed, this assumes that we won't get # data from an interest sent before it changed. # Use getattr because "from" is a reserved keyword. if (content.type == chatbuf_pb2.ChatMessage.CHAT and not self._isRecoverySyncState and getattr(content, "from") != self._screenName): print(getattr(content, "from") + ": " + content.data) elif content.type == chatbuf_pb2.ChatMessage.LEAVE: # leave message try: n = self._roster.index(nameAndSession) if name != self._screenName: self._roster.pop(n) print(name + ": Leave") except ValueError: pass
def requestCertificate(self, keyIdentity): """ We compose a command interest with our public key info so the controller can sign us a certificate that can be used with other nodes in the network. Name format : /home/<device-category>/KEY/<device-id>/<key-id>/<publickey>/ID-CERT/<version-number> """ certificateRequestName = self._keyChain.getDefaultIdentity() deviceIdComponent = certificateRequestName.get(-1) keyIdComponent = keyIdentity.get(-1) certificateRequestName = certificateRequestName certificateRequestName.append("KEY") #certificateRequestName.append(deviceIdComponent) certificateRequestName.append(keyIdComponent) key = self._identityManager.getPublicKey(keyIdentity) keyInfo = {} keyInfo["keyType"] = key.getKeyType() keyInfo["keyDer"] = key.getKeyDer().toRawStr() certificateRequestName.append(json.dumps(keyInfo, encoding="latin-1")) certificateRequestName.append("ID-CERT") certificateRequest = Interest(certificateRequestName) certificateRequest.setInterestLifetimeMilliseconds(5000) self._hmacHelper.signInterest(certificateRequest) dump("Sending certificate request : ",certificateRequestName) self.face.expressInterest(certificateRequest, self.onCertificateData, self.onTimeout)
class TestInterestDump(ut.TestCase): def setUp(self): self.referenceInterest = Interest() self.referenceInterest.wireDecode(codedInterest) def test_dump(self): # see if the dump format is the same as we expect decodedDump = dumpInterest(self.referenceInterest) self.assertEqual(initialDump, decodedDump, 'Initial dump does not have expected format') def test_redecode(self): # check that we encode and decode correctly encoding = self.referenceInterest.wireEncode() reDecodedInterest = Interest() reDecodedInterest.wireDecode(encoding) redecodedDump = dumpInterest(reDecodedInterest) self.assertEqual(initialDump, redecodedDump, 'Re-decoded interest does not match original') def test_create_fresh(self): freshInterest = createFreshInterest() freshDump = dumpInterest(freshInterest) self.assertTrue(interestDumpsEqual(initialDump, freshDump), 'Fresh interest does not match original') reDecodedFreshInterest = Interest() reDecodedFreshInterest.wireDecode(freshInterest.wireEncode()) reDecodedFreshDump = dumpInterest(reDecodedFreshInterest) self.assertTrue(interestDumpsEqual(freshDump, reDecodedFreshDump), 'Redecoded fresh interest does not match original')
def test_redecode(self): # check that we encode and decode correctly encoding = self.referenceInterest.wireEncode() reDecodedInterest = Interest() reDecodedInterest.wireDecode(encoding) redecodedDump = dumpInterest(reDecodedInterest) self.assertEqual(initialDump, redecodedDump, 'Re-decoded interest does not match original')
def test_set_removes_nonce(self): # Ensure that changing a value on an interest clears the nonce. self.assertFalse(self.referenceInterest.getNonce().isNull()) interest = Interest(self.referenceInterest) # Change a child object. interest.getExclude().clear() self.assertTrue(interest.getNonce().isNull(), 'Interest should not have a nonce after changing fields')
def consume(self, prefix, onVerified, onVerifyFailed, onTimeout): """ Consume data continuously under a given prefix, each time sending interest with the last timestamp excluded :param name: prefix to consume data under :type name: Name :param onData: onData(data) gets called after received data's onVerifyFailed :type onData: function object :param onVerifyFailed: onVerifyFailed(data) gets called if received data cannot be verified :type onVerifyFailed: function object :param onTimeout: onTimeout(interest) gets called if a consumer interest times out :type onTimeout: function object """ name = Name(prefix) interest = Interest(name) interest.setInterestLifetimeMilliseconds(self._defaultInterestLifetime) if self._currentTimestamp: exclude = Exclude() exclude.appendAny() exclude.appendComponent(Name.Component.fromVersion(self._currentTimestamp)) interest.setExclude(exclude) self._face.expressInterest(interest, lambda i, d : self.onData(i, d, onVerified, onVerifyFailed, onTimeout), lambda i: self.beforeReplyTimeout(i, onVerified, onVerifyFailed, onTimeout)) return
def main(): # The default Face will connect using a Unix socket, or to "localhost". face = Face() keyChain = KeyChain() face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName()) dataPrefix = "/home/test1/data" repoDataPrefix = "/home/test1/data" # Set up repo-ng, register prefix for repo-ng's fetch prefix # Per configuration file in /usr/local/etc/ndn/repo-ng.conf # memCache is not used for now; repo is hoping that the piece of data in question is still being held at nfd #memCache = MemoryContentCache(face, 100000) #memCache.registerPrefix(Name(repoDataPrefix), onRegisterFailed, onDataNotFound) counter = Counter(face, repoDataPrefix) interest = Interest(Name(dataPrefix)) interest.setChildSelector(1) interest.setInterestLifetimeMilliseconds(defaultInterestLifetime) face.expressInterest(interest, counter.onData, counter.onTimeout) while True: face.processEvents() # We need to sleep for a few milliseconds so we don't use 100% of the CPU. time.sleep(1) face.shutdown()
def test_find_by_interest(self): self.anchorContainer.insert("group1", self.certificatePath1, 400.0) interest = Interest(self.identity1.getName()) self.assertTrue(self.anchorContainer.find(interest) != None) interest1 = Interest(self.identity1.getName().getPrefix(-1)) self.assertTrue(self.anchorContainer.find(interest1) != None) interest2 = Interest(Name(self.identity1.getName()).appendVersion(1)) self.assertTrue(self.anchorContainer.find(interest2) == None) certificate3 = self.fixture.addCertificate( self.identity1.getDefaultKey(), "3") certificate4 = self.fixture.addCertificate( self.identity1.getDefaultKey(), "4") certificate5 = self.fixture.addCertificate( self.identity1.getDefaultKey(), "5") certificate3Copy = CertificateV2(certificate3) self.anchorContainer.insert("group2", certificate3Copy) self.anchorContainer.insert("group3", certificate4) self.anchorContainer.insert("group4", certificate5) interest3 = Interest(certificate3.getKeyName()) foundCertificate = self.anchorContainer.find(interest3) self.assertTrue(foundCertificate != None) self.assertTrue(interest3.getName().isPrefixOf(foundCertificate.getName())) self.assertTrue(certificate3.getName().equals(foundCertificate.getName())) interest3.getExclude().appendComponent( certificate3.getName().get(CertificateV2.ISSUER_ID_OFFSET)) foundCertificate = self.anchorContainer.find(interest3) self.assertTrue(foundCertificate != None) self.assertTrue(interest3.getName().isPrefixOf(foundCertificate.getName())) self.assertTrue(not foundCertificate.getName().equals(certificate3.getName()))
def onTrustSchemaTimeout(self, interest, onUpdateSuccess, onUpdateFailed): print("Trust schema interest times out: " + interest.getName().toUri()) newInterest = Interest(interest) newInterest.refreshNonce() self._face.expressInterest(newInterest, lambda interest, data: self.onTrustSchemaData(interest, data, onUpdateSuccess, onUpdateFailed), lambda interest: self.onTrustSchemaTimeout(interest, onUpdateSuccess, onUpdateFailed)) return
def onProfileRequestTimeout(self, interest): dump("Time out for device profile request, send again") interestName = interest.getName().getPrefix(-2) profileRequest = Interest(interestName) profileRequest.setInterestLifetimeMilliseconds(3000) self._accessControlManager.signInterestWithHMACKey(profileRequest,self._newDevice['configurationToken']) self.face.expressInterest(profileRequest, self.onProfile, self.onProfileRequestTimeout)
def beforeReplyTimeout(self, interest, onVerified, onVerifyFailed, onTimeout): newInterest = Interest(interest) newInterest.refreshNonce() self._face.expressInterest(newInterest, lambda i, d : self.onData(i, d, onVerified, onVerifyFailed, onTimeout), lambda i: self.beforeReplyTimeout(i, onVerified, onVerifyFailed, onTimeout)) onTimeout(interest) return
def onDeviceResponse(interest, data): updatedInterest = Interest(interest) deviceSerial = str(data.getContent()) if len(deviceSerial) > 0: foundDevices.append(deviceSerial) updatedInterest.getExclude().appendComponent(Name.Component(deviceSerial)) # else ignore the malformed response self.face.expressInterest(updatedInterest, onDeviceResponse, onDeviceTimeout)
def onEntityData(self, interest, data): self.addObject(interest.getName().toUri(), True) self.notifyObserver(interest.getName().toUri(), "ADD", ""); dummyInterest = Interest(Name("/local/timeout")) dummyInterest.setInterestLifetimeMilliseconds(4000) self._face.expressInterest(dummyInterest, self.onDummyData, lambda a : self.expressHeartbeatInterest(a, interest)) return
def test_sign_verify_interest(self): freshInterest = Interest(Name("/home/controller")) self.h.signInterest(freshInterest, self.raw_key_name) s = freshInterest.extractInterestSignature() k = s.getKeyLocator().getName().toUri() result = self.h.verifyInterest(freshInterest) self.assertEqual(result, True, 'verifiedInterest does not match original interest')
def issueListCommand(self,excludeDevice=None): if excludeDevice == None: interestName = Name(self.listPrefix) #when the controller receive the list from a storage device, it will exclude it from broadcast list. else: interestName = Name(self.listPrefix).append(str("exc")+excludeDevice) command = Interest(interestName) command.setInterestLifetimeMilliseconds(4000) self.face.expressInterest(command,self.onListResponse,self.onListTimeout)
def expressProfileRequest(self,deviceName): profileRequest = Interest(deviceName.append("profile")) profileRequest.setInterestLifetimeMilliseconds(3000) dump("Request device Profile: ", profileRequest.toUri()) #sign profile request with configuration token self._accessControlManager.signInterestWithHMACKey(profileRequest,self._newDevice['configurationToken']) self.face.expressInterest(profileRequest, self.onProfile, self.onProfileRequestTimeout)
def test_create_fresh(self): freshInterest = createFreshInterest() freshDump = dumpInterest(freshInterest) self.assertTrue(interestDumpsEqual(initialDump, freshDump), 'Fresh interest does not match original') reDecodedFreshInterest = Interest() reDecodedFreshInterest.wireDecode(freshInterest.wireEncode()) reDecodedFreshDump = dumpInterest(reDecodedFreshInterest) self.assertTrue(interestDumpsEqual(freshDump, reDecodedFreshDump), 'Redecoded fresh interest does not match original')
def main(): # Silence the warning from Interest wire encode. Interest.setDefaultCanBePrefix(True) interest = Interest() interest.wireDecode(TlvInterest) # Use a hard-wired secret for testing. In a real application the signer # ensures that the verifier knows the shared key and its keyName. key = Blob(bytearray([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 ])) if KeyChain.verifyInterestWithHmacWithSha256(interest, key): dump("Hard-coded interest signature verification: VERIFIED") else: dump("Hard-coded interest signature verification: FAILED") freshInterest = Interest(Name("/ndn/abc")) freshInterest.setMustBeFresh(False) keyName = Name("key1") dump("Signing fresh interest", freshInterest.getName().toUri()) KeyChain.signWithHmacWithSha256(freshInterest, key, keyName) if KeyChain.verifyInterestWithHmacWithSha256(freshInterest, key): dump("Freshly-signed interest signature verification: VERIFIED") else: dump("Freshly-signed interest signature verification: FAILED")
def test_name_too_short(self): interest1 = Interest(Name("/name/too/short")) self.validateExpectFailure(interest1, "Should fail (name is too short)")
async def fetch_segmented_data(face: Face, prefix: Name, start_block_id: Optional[int], end_block_id: Optional[int], semaphore: asyncio.Semaphore, after_fetched: Callable): """ Fetch segmented data starting from start_block_id. If start_block_id is not set, start from sequence 0. If end_block_id is set, or a data packet returns FinalBlockId, the function will fetch all data until that id. Otherwise, it will return until number of failures reach a threshold. Upon receiving each data, call after_fetched. TODO: Remove hard-coded part """ FETCHER_RETRY_INTERVAL = 0 FETCHER_MAX_ATTEMPT_NUMBER = 3 FETCHER_FAIL_EXIT_THRESHOLD = 5 async def retry_or_fail(interest: Interest): """ Retry for up to FETCHER_MAX_ATTEMPT_NUMBER times, and write to storage """ nonlocal n_success, n_fail, cur_id, final_id seq = int(str(interest.getName()[-1])) if seq > final_id: semaphore.release() return logging.info('retry_or_fail(): {}'.format(interest.getName())) # print('retry_or_fail(): {}'.format(interest.getName())) for _ in range(FETCHER_MAX_ATTEMPT_NUMBER): response = await fetch_data_packet(face, interest) success = False if isinstance(response, Data): final_id_component = response.metaInfo.getFinalBlockId() if final_id_component.isSegment(): final_id = final_id_component.toSegment() logging.info('final_id is set to {}'.format(final_id)) success = True break else: await asyncio.sleep(FETCHER_RETRY_INTERVAL / 1000.0) if success: n_success += 1 else: n_fail += 1 # Exit if all data fetched, or n_fail reaches a threshold if n_fail >= FETCHER_FAIL_EXIT_THRESHOLD or n_success + n_fail >= final_id - start_block_id + 1: done.set() semaphore.release() after_fetched(response) print('Fetching: {}'.format(prefix)) cur_id = (start_block_id if start_block_id else 0) final_id = (end_block_id if (end_block_id is not None) else 0x7fffffff) n_success = 0 n_fail = 0 event_loop = asyncio.get_event_loop() done = asyncio.Event() tasks = [] while cur_id <= final_id: # Need to acquire semaphore before adding task to event loop, otherwise an unlimited # number of tasks would be added await semaphore.acquire() interest = Interest(Name(prefix).append(str(cur_id))) interest.setInterestLifetimeMilliseconds(500) # Because asyncio is non-preemptive, need to explicitly release control here to give asyncio # a chance to process incoming data await asyncio.sleep(0) tasks.append(event_loop.create_task(retry_or_fail(interest))) cur_id += 1 # Give up? if done.is_set(): break await asyncio.gather(*tasks) await done.wait()
from pyndn import NDN, Name, Interest, Closure from time import sleep worked = False class MyClosure(Closure): def upcall(self, kind, upcallInfo): global worked print("Got response") print(kind) print(upcallInfo) worked = True n = Name("ndn:/ndnx/ping") i = Interest() closure = MyClosure() c = NDN() res = c.expressInterest(n, closure, i) print(res) #causes crashes c.run(10) print("Ha!") assert(worked)
def main(): interest = Interest() interest.wireDecode(TlvInterest) dump("Interest:") dumpInterest(interest) # Set the name again to clear the cached encoding so we encode again. interest.setName(interest.getName()) encoding = interest.wireEncode() dump("") dump("Re-encoded interest", encoding.toHex()) reDecodedInterest = Interest() reDecodedInterest.wireDecode(encoding) dump("Re-decoded Interest:") dumpInterest(reDecodedInterest) freshInterest = (Interest( Name("/ndn/abc")).setMustBeFresh(False).setMinSuffixComponents( 4).setMaxSuffixComponents(6).setInterestLifetimeMilliseconds( 30000).setChildSelector(1).setMustBeFresh(True)) freshInterest.getKeyLocator().setType(KeyLocatorType.KEY_LOCATOR_DIGEST) freshInterest.getKeyLocator().setKeyData( bytearray([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F ])) freshInterest.getExclude().appendComponent(Name("abc")[0]).appendAny() freshInterest.getForwardingHint().add(1, Name("/A")) dump(freshInterest.toUri()) # Set up the KeyChain. keyChain = KeyChain("pib-memory:", "tpm-memory:") keyChain.importSafeBag( SafeBag(Name("/testname/KEY/123"), Blob(DEFAULT_RSA_PRIVATE_KEY_DER, False), Blob(DEFAULT_RSA_PUBLIC_KEY_DER, False))) validator = Validator(ValidationPolicyFromPib(keyChain.getPib())) # Make a Face just so that we can sign the interest. face = Face("localhost") face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName()) face.makeCommandInterest(freshInterest) reDecodedFreshInterest = Interest() reDecodedFreshInterest.wireDecode(freshInterest.wireEncode()) dump("") dump("Re-decoded fresh Interest:") dumpInterest(reDecodedFreshInterest) validator.validate(reDecodedFreshInterest, makeSuccessCallback("Freshly-signed Interest"), makeFailureCallback("Freshly-signed Interest"))
def onDataNotFound(self, prefix, interest, face, interestFilterId, filter): print "Data not found for interest: " + interest.getName().toUri() if interest.getName().get( -3).toEscapedString() == "bout" or interest.getName().get( -3).toEscapedString() == "genericfunctions": if interest.getName().toUri() in self.remainingTasks: # We are already trying to process this task, so we don't add it to the list of tasks pass else: self.remainingTasks[interest.getName().toUri()] = "in-progress" else: print "Got unexpected interest: " + interest.getName().toUri() # .../SAMPLE/<timestamp> timestamp = interest.getName().get(-1) catalogInterest = Interest(self.catalogPrefix) # Traverse catalogs in range from leftmost child catalogInterest.setChildSelector(0) catalogInterest.setMustBeFresh(True) catalogInterest.setInterestLifetimeMilliseconds(4000) exclude = Exclude() exclude.appendAny() exclude.appendComponent(timestamp) catalogInterest.setExclude(catalogInterest) self.face.expressInterest(catalogInterest, self.onCatalogData, self.onCatalogTimeout) print "Expressed catalog interest " + catalogInterest.getName().toUri() return
def setUp(self): self.referenceInterest = Interest() self.referenceInterest.wireDecode(codedInterest)
def test_append_parameters_digest(self): name = Name("/local/ndn/prefix") interest = Interest(name) self.assertTrue(not interest.hasApplicationParameters()) # No parameters yet, so it should do nothing. interest.appendParametersDigestToName() self.assertEqual("/local/ndn/prefix", interest.getName().toUri()) applicationParameters = Blob(bytearray([ 0x23, 0x01, 0xC0 ])) interest.setApplicationParameters(applicationParameters) self.assertTrue(interest.hasApplicationParameters()) interest.appendParametersDigestToName() self.assertEqual(name.size() + 1, interest.getName().size()) self.assertTrue(interest.getName().getPrefix(-1).equals(name)) SHA256_LENGTH = 32 self.assertEqual(SHA256_LENGTH, interest.getName().get(-1).getValue().size()) self.assertEqual(interest.getName().toUri(), "/local/ndn/prefix/" + "params-sha256=a16cc669b4c9ef6801e1569488513f9523ffb28a39e53aa6e11add8d00a413fc")
def checkVerificationPolicy(self, dataOrInterest, stepCount, onVerified, onVerifyFailed, wireFormat=None): """ If there is a rule matching the data or interest, and the matching certificate is missing, download it. If there is no matching rule, verification fails. Otherwise, verify the signature using the public key in the IdentityStorage. :param dataOrInterest: The Data object or interest with the signature to check. :type dataOrInterest: Data or Interest :param int stepCount: The number of verification steps that have been done, used to track the verification progress. :param onVerified: If the signature is verified, this calls onVerified(dataOrInterest). :type onVerified: function object :param onVerifyFailed: If the signature check fails, this calls onVerifyFailed(dataOrInterest). :type onVerifyFailed: function object :return: None for no further step for looking up a certificate chain. :rtype: ValidationRequest """ if stepCount > self._maxDepth: onVerifyFailed(dataOrInterest) return None signature = self._extractSignature(dataOrInterest, wireFormat) # no signature -> fail if signature is None: onVerifyFailed(dataOrInterest) return None if not KeyLocator.canGetFromSignature(signature): # We only support signature types with key locators. onVerifyFailed(dataOrInterest) return None keyLocator = None try: keyLocator = KeyLocator.getFromSignature(signature) except: # No key locator -> fail. onVerifyFailed(dataOrInterest) return None signatureName = keyLocator.getKeyName() # no key name in KeyLocator -> fail if signatureName.size() == 0: onVerifyFailed(dataOrInterest) return None objectName = dataOrInterest.getName() matchType = "data" #for command interests, we need to ignore the last 4 components when matching the name if isinstance(dataOrInterest, Interest): objectName = objectName.getPrefix(-4) matchType = "interest" # first see if we can find a rule to match this packet try: matchedRule = self._findMatchingRule(objectName, matchType) except: matchedRule = None # no matching rule -> fail if matchedRule is None: onVerifyFailed(dataOrInterest) return None signatureMatches = self._checkSignatureMatch(signatureName, objectName, matchedRule) if not signatureMatches: onVerifyFailed(dataOrInterest) return None # before we look up keys, refresh any certificate directories self._refreshManager.refreshAnchors() # now finally check that the data or interest was signed correctly # if we don't actually have the certificate yet, create a # ValidationRequest for it foundCert = self._refreshManager.getCertificate(signatureName) if foundCert is None: foundCert = self._certificateCache.getCertificate(signatureName) if foundCert is None: certificateInterest = Interest(signatureName) def onCertificateDownloadComplete(certificate): certificate = IdentityCertificate(certificate) self._certificateCache.insertCertificate(certificate) self.checkVerificationPolicy(dataOrInterest, stepCount + 1, onVerified, onVerifyFailed) nextStep = ValidationRequest(certificateInterest, onCertificateDownloadComplete, onVerifyFailed, 2, stepCount + 1) return nextStep # for interests, we must check that the timestamp is fresh enough # I do this after (possibly) downloading the certificate to avoid # filling the cache with bad keys if isinstance(dataOrInterest, Interest): keyName = foundCert.getPublicKeyName() timestamp = dataOrInterest.getName().get(-4).toNumber() if not self._interestTimestampIsFresh(keyName, timestamp): onVerifyFailed(dataOrInterest) return None # certificate is known, verify the signature if self._verify(signature, dataOrInterest.wireEncode()): onVerified(dataOrInterest) if isinstance(dataOrInterest, Interest): self._updateTimestampForKey(keyName, timestamp) else: onVerifyFailed(dataOrInterest)
def create_feature_req_interest(self, feature_req_interest_name): interest = Interest(feature_req_interest_name) interest.setMustBeFresh(True) interest.setInterestLifetimeMilliseconds(4000) return interest
def test_no_selectors_must_be_fresh(self): interest = Interest() interest.wireDecode(codedInterestNoSelectors) self.assertEqual(False, interest.getMustBeFresh(), "MustBeFresh should be false if no selectors")
class TestInterestDump(ut.TestCase): def setUp(self): self.referenceInterest = Interest() self.referenceInterest.wireDecode(codedInterest) def test_dump(self): # see if the dump format is the same as we expect decodedDump = dumpInterest(self.referenceInterest) self.assertEqual(initialDump, decodedDump, 'Initial dump does not have expected format') def test_redecode(self): # check that we encode and decode correctly encoding = self.referenceInterest.wireEncode() reDecodedInterest = Interest() reDecodedInterest.wireDecode(encoding) redecodedDump = dumpInterest(reDecodedInterest) self.assertEqual(initialDump, redecodedDump, 'Re-decoded interest does not match original') def test_redecode_implicit_digest_exclude(self): # Check that we encode and decode correctly with an implicit digest exclude. interest = Interest(Name("/A")) interest.getExclude().appendComponent(Name("/sha256digest=" + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").get(0)) dump = dumpInterest(interest) encoding = interest.wireEncode() reDecodedInterest = Interest() reDecodedInterest.wireDecode(encoding) redecodedDump = dumpInterest(reDecodedInterest) self.assertTrue(interestDumpsEqual(dump, redecodedDump), "Re-decoded interest does not match original") def test_create_fresh(self): freshInterest = createFreshInterest() freshDump = dumpInterest(freshInterest) self.assertTrue(interestDumpsEqual(initialDump, freshDump), 'Fresh interest does not match original') reDecodedFreshInterest = Interest() reDecodedFreshInterest.wireDecode(freshInterest.wireEncode()) reDecodedFreshDump = dumpInterest(reDecodedFreshInterest) self.assertTrue(interestDumpsEqual(freshDump, reDecodedFreshDump), 'Redecoded fresh interest does not match original') def test_no_selectors_must_be_fresh(self): interest = Interest() interest.wireDecode(codedInterestNoSelectors) self.assertEqual(False, interest.getMustBeFresh(), "MustBeFresh should be false if no selectors") def test_decode_v03_as_v02(self): interest1 = Interest() interest1.wireDecode(simpleCodedInterestV03) dump1 = dumpInterest(interest1) self.assertEqual(dump1, simpleCodedInterestV03Dump, "Decoded simpleCodedInterestV03 does not match the dump") interest2 = Interest() interest2.wireDecode(fullCodedInterestV03) dump2 = dumpInterest(interest2) self.assertEqual(dump2, fullCodedInterestV03Dump, "Decoded fullCodedInterestV03Dump does not match the dump")
def ndnInit(self): Interest.setDefaultCanBePrefix(True) # TODO: Bug? Does not auto retry TCP if unix socket fails as says in docs. # self.face = Face("localhost", 6363) self.face = Face() self.primary_prefix = "/ndn"
class Request(object): def __init__(self, node, name, timeout=30, intermediate_interval=1, on_data=None, on_timeout=None, on_intermediate=None): # TODO: allow interest to be a string uri or an Interest object and convert to self.uri AND self.interest in both cases. self.node = node self.name = name self.interest = Interest(Name(name)) self.timeout = timeout self.intermediate_interval = intermediate_interval self.later_timer = None self.on_data = on_data if on_data is not None else self.on_data_fallback self.on_timeout = on_timeout if on_timeout is not None else self.on_timeout_fallback self.on_intermediate = on_intermediate self.redirect = None self.final_segment = None self.highest_requested_segment = -1 self.pending_segments = set() self.segments = {} self.highest_gim_sent = -1 self.highest_gim_received = -1 self.cim_timer = None self.cim_name = self.name if self.cim_name.endswith("/NFN"): self.cim_name = self.cim_name[:-4] + "/R2C/CIM/NFN" def send(self): if self.timeout is None: self.interest.setInterestLifetimeMilliseconds(None) else: self.interest.setInterestLifetimeMilliseconds(1000 * self.timeout) self.node.face.expressInterest(self.interest, self.on_interest_data, self.on_interest_timeout) Log.info("Sent interest '{}'".format(self.name)) if self.intermediate_interval > 0 and self.on_intermediate is not None: self.cim_timer = threading.Timer(self.intermediate_interval, self.cim_timer_fired) self.cim_timer.start() def send_later(self, delay): self.later_timer = threading.Timer(delay, self.send) self.later_timer.start() def cancel(self): if self.later_timer is not None: self.later_timer.cancel() if self.cim_timer is not None: self.cim_timer.cancel() def cim_timer_fired(self): Request(self.node, self.cim_name, timeout=self.intermediate_interval, on_data=self.on_cim_data).send() self.cim_timer = threading.Timer(self.intermediate_interval, self.cim_timer_fired) self.cim_timer.start() def on_cim_data(self, request, data): content = data.getContent().toRawStr() if not content: Log.info("No intermediate results available yet.") return highest_available = int(content) for i in range(self.highest_gim_sent + 1, highest_available + 1): self.request_intermediate(i) self.highest_gim_sent = highest_available def request_intermediate(self, index): gim_uri = self.name if gim_uri.endswith("/NFN"): gim_uri = gim_uri[:-4] + "/R2C/GIM " + str(index) + "/NFN" Request(self.node, gim_uri, on_data=self.on_intermediate_data).send() def on_intermediate_data(self, request, data): index = Util.get_intermediate_index(request.interest) if index < 0: Log.error("Invalid intermediate result.") return if index < self.highest_gim_received: Log.warn("Received old intermediate out of order. Ignore.") return self.highest_gim_received = index self.on_intermediate(self, index, data) def on_interest_data(self, interest, data): if self.cim_timer is not None: self.cim_timer.cancel() content = data.getContent().toRawStr() redirectPrefix = "redirect:" if content.startswith(redirectPrefix): name = content[len(redirectPrefix):] self.redirect = Interest(Name(name)) Log.info("Received redirect for interest '{}' -> '{}':\n{}".format( Util.interest_to_string(interest), Util.interest_to_string(self.redirect), urllib.parse.unquote(content))) self.request_next_segments() else: Log.info("Received data for interest '{}':\n{}".format( Util.interest_to_string(interest), urllib.parse.unquote(content))) self.on_data(self, data) def on_interest_timeout(self, interest): Log.warn("Interest timed out '{}'".format( Util.interest_to_string(interest))) self.on_timeout(self) pass def request_next_segments(self): if self.final_segment is None: self.request_segment(self.highest_requested_segment + 1) else: while self.highest_requested_segment < self.final_segment: self.request_segment(self.highest_requested_segment + 1) def request_segment(self, index): if index > self.highest_requested_segment: self.highest_requested_segment = index self.pending_segments.add(index) segment_name = Name(self.redirect.getName()) segment_name.appendSegment(index) interest = Interest(segment_name) Log.info("Sent segment interest '{}'".format( Util.interest_to_string(interest))) self.node.face.expressInterest(interest, self.on_segment_data, self.on_segment_timeout) def on_segment_data(self, interest, data): if self.final_segment is None: self.final_segment = data.getMetaInfo().getFinalBlockId().toNumber( ) content = data.getContent() if not content.isNull(): size = content.size() name = interest.getName() segmentNumber = Util.find_segment_number(name) Log.info("Received data ({} bytes) for segment '{}'.".format( size, Util.interest_to_string(interest))) self.segments[segmentNumber] = data self.pending_segments.remove(segmentNumber) allSegmentsReceived = self.final_segment is not None \ and self.highest_requested_segment >= int(self.final_segment) \ and self.pending_segments.__len__() == 0 if allSegmentsReceived: self.handle_completion() else: self.request_next_segments() else: Log.warn("Received EMPTY data for segment '{}'.".format( Util.interest_to_string(interest))) def on_segment_timeout(self, interest): Log.warn("Interest timed out '{}'".format( Util.interest_to_string(interest))) self.on_timeout(self) def handle_completion(self): content = bytearray() for i in sorted(self.segments): segment = self.segments[i] content.extend(segment.getContent().buf()) interest = Interest(Name(self.name)) blob = Blob(content) size = blob.size() Log.info( "Received all segments ({} bytes) for interest '{}':\n{}".format( size, Util.interest_to_string(interest), urllib.parse.unquote(blob.toRawStr()))) data = Data(interest.getName()) data.setContent(blob) self.on_data(self, data) def on_data_fallback(self, request, data): pass def on_timeout_fallback(self, request): pass def on_intermediate_fallback(self, request, index, data): pass
def createSongCommand(self, command): interestName = Name(self.listPrefix).append(self.device) interestName = interestName.append(command) interest = Interest(interestName) interest.setInterestLifetimeMilliseconds(4000) return interest
def main(): """Runs a consumer with the specified properties.""" # silence the warning from interest wire encode Interest.setDefaultCanBePrefix(True) # handle and specify arguments parser = argparse.ArgumentParser() parser.add_argument("-p", "--prefix", help="the prefix to request data from", action="append", default=["/ndn/external/test"]) parser.add_argument("-c", "--count", help="the number of interests to send", type=int, default=10) parser.add_argument("-i", "--ipaddress", help="the ip address to tunnel to", default="10.10.1.1") parser.add_argument("-v", "--verbosity", help="increase output verbosity", choices=[0, 1, 2], type=int, default=0) # TODO: add rate functionality back in if needed # parser.add_argument("-r", "--rate", help="the rate at which interests are sent", type=rate_parser, default="0.00001") parser.add_argument("-r", "--repeat", help="the number of interest bursts to send", type=int, default=1) parser.add_argument("-f", "--filename", help="the output file to store data to (in CSV form)") args = parser.parse_args() # clean up prefix argument if len(args.prefix) > 1: args.prefix.pop(0) # create a list of dictionaries to store data in data = [] # send interest burst a specified number of times for i in range(0, args.repeat): # create a consumer and send interests with it for each prefix provided for namespace in args.prefix: consumer = Consumer(args.ipaddress, verbose=args.verbosity) # TODO: add rate functionality back in if needed data.append(consumer.send_interests(namespace, args.count)) time.sleep(0.25) # create dataframe from list of dictionaries df = pd.DataFrame(data) # store output to file if filename option is enabled if args.filename is not None: df.to_csv(args.filename) print(df)
def test_copy_constructor(self): interest = Interest(self.referenceInterest) self.assertTrue(interestDumpsEqual(dumpInterest(interest), dumpInterest(self.referenceInterest)), 'Interest constructed as deep copy does not match original')
async def run(cmd: str): async def face_loop(): nonlocal face, running while running: face.processEvents() await asyncio.sleep(0.01) running = True face = Face() keychain = KeyChain() face.setCommandSigningInfo(keychain, keychain.getDefaultCertificateName()) event_loop = asyncio.get_event_loop() face_task = event_loop.create_task(face_loop()) if cmd == "track-repo": if len(sys.argv) < 3: print("Usage:", sys.argv[0], "track-repo <repo>", file=sys.stderr) else: repo = sys.argv[2] interest = Interest( Name(LOCAL_CMD_PREFIX).append("track-repo").append(repo)) data = await fetch_data_packet(face, interest) if isinstance(data, Data): result = struct.unpack("i", data.content.toBytes())[0] if result == 1: print("OK") elif result == 2: print("FAILED") else: print("PENDING") else: print("error: Couldn't connect to", interest.name.toUri(), file=sys.stderr) elif cmd == "create-branch": if len(sys.argv) < 4: print("Usage:", sys.argv[0], "create-branch <repo> <branch>", file=sys.stderr) else: repo = sys.argv[2] branch = sys.argv[3] interest = Interest( Name(LOCAL_CMD_PREFIX).append("create-branch").append( repo).append(branch)) data = await fetch_data_packet(face, interest) if isinstance(data, Data): result = struct.unpack("i", data.content.toBytes())[0] if result == 1: print("OK") elif result == 2: print("FAILED") else: print("PENDING") else: print("error: Couldn't connect to", interest.name.toUri(), file=sys.stderr) elif cmd == "mount": if len(sys.argv) < 4: print("Usage:", sys.argv[0], "mount <repo> <branch>", file=sys.stderr) else: repo = sys.argv[2] branch = sys.argv[3] interest = Interest( Name(LOCAL_CMD_PREFIX).append("mount").append(repo).append( branch)) data = await fetch_data_packet(face, interest) if isinstance(data, Data): print("Finished.") else: print("error: Couldn't connect to", interest.name.toUri(), file=sys.stderr) elif cmd == "unmount": if len(sys.argv) < 4: print("Usage:", sys.argv[0], "unmount <repo> <branch>", file=sys.stderr) else: repo = sys.argv[2] branch = sys.argv[3] interest = Interest( Name(LOCAL_CMD_PREFIX).append("unmount").append(repo).append( branch)) data = await fetch_data_packet(face, interest) if isinstance(data, Data): print("Finished.") else: print("error: Couldn't connect to", interest.name.toUri(), file=sys.stderr) elif cmd == "commit": if len(sys.argv) < 6: print("Usage:", sys.argv[0], "commit <repo> <branch> <dest-branch> <message>", file=sys.stderr) else: repo = sys.argv[2] branch = sys.argv[3] dest_branch = sys.argv[4] commit_msg = sys.argv[5] interest = Interest(Name(LOCAL_CMD_PREFIX).append("commit")) interest.applicationParameters = b'\x00'.join([ repo.encode(), branch.encode(), dest_branch.encode(), commit_msg.encode() ]) interest.appendParametersDigestToName() data = await fetch_data_packet(face, interest) if isinstance(data, Data): print("Finished.") else: print("error: Couldn't connect to", interest.name.toUri(), file=sys.stderr) else: print("Unrecognized command:", cmd, file=sys.stderr) running = False await face_task
def test_matches_data(self): interest = Interest(Name("/A")) interest.setMinSuffixComponents(2) interest.setMaxSuffixComponents(2) interest.getKeyLocator().setType(KeyLocatorType.KEYNAME) interest.getKeyLocator().setKeyName(Name("/B")) interest.getExclude().appendComponent(Name.Component("J")) interest.getExclude().appendAny() data = Data(Name("/A/D")) signature = Sha256WithRsaSignature() signature.getKeyLocator().setType(KeyLocatorType.KEYNAME) signature.getKeyLocator().setKeyName(Name("/B")) data.setSignature(signature) self.assertEqual(interest.matchesData(data), True) # Check violating MinSuffixComponents. data1 = Data(data) data1.setName(Name("/A")) self.assertEqual(interest.matchesData(data1), False) interest1 = Interest(interest) interest1.setMinSuffixComponents(1) self.assertEqual(interest1.matchesData(data1), True) # Check violating MaxSuffixComponents. data2 = Data(data) data2.setName(Name("/A/E/F")) self.assertEqual(interest.matchesData(data2), False) interest2 = Interest(interest) interest2.setMaxSuffixComponents(3) self.assertEqual(interest2.matchesData(data2), True) # Check violating PublisherPublicKeyLocator. data3 = Data(data) signature3 = Sha256WithRsaSignature() signature3.getKeyLocator().setType(KeyLocatorType.KEYNAME) signature3.getKeyLocator().setKeyName(Name("/G")) data3.setSignature(signature3) self.assertEqual(interest.matchesData(data3), False) interest3 = Interest(interest) interest3.getKeyLocator().setType(KeyLocatorType.KEYNAME) interest3.getKeyLocator().setKeyName(Name("/G")) self.assertEqual(interest3.matchesData(data3), True) data4 = Data(data) data4.setSignature(DigestSha256Signature()) self.assertEqual(interest.matchesData(data4), False) interest4 = Interest(interest) interest4.setKeyLocator(KeyLocator()) self.assertEqual(interest4.matchesData(data4), True) # Check violating Exclude. data5 = Data(data) data5.setName(Name("/A/J")) self.assertEqual(interest.matchesData(data5), False) interest5 = Interest(interest) interest5.getExclude().clear() interest5.getExclude().appendComponent(Name.Component("K")) interest5.getExclude().appendAny() self.assertEqual(interest5.matchesData(data5), True) # Check violating Name. data6 = Data(data) data6.setName(Name("/H/I")) self.assertEqual(interest.matchesData(data6), False) data7 = Data(data) data7.setName(Name("/A/B")) interest7 = Interest( Name("/A/B/sha256digest=" + "54008e240a7eea2714a161dfddf0dd6ced223b3856e9da96792151e180f3b128")) self.assertEqual(interest7.matchesData(data7), True) # Check violating the implicit digest. interest7b = Interest( Name("/A/B/%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00" + "%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00")) self.assertEqual(interest7b.matchesData(data7), False) # Check excluding the implicit digest. interest8 = Interest(Name("/A/B")) interest8.getExclude().appendComponent(interest7.getName().get(2)) self.assertEqual(interest8.matchesData(data7), False)
def sendProbeInterest(self): probeInterest = Interest( Name(self.caPrefix).append("CA").append("_PROBE")) probeInterest.setMustBeFresh(True) probeInterest.setCanBePrefix(False) probeInterest.setApplicationParameters( json.dumps({"email": "*****@*****.**"}, indent=4)) probeInterest.appendParametersDigestToName() print("Expressing interest: {}".format(probeInterest.getName())) self.face.expressInterest(probeInterest, self.onProbeData, self.onTimeout)
def nfdRegisterPrefix(self, registeredPrefixId, prefix, onInterest, onRegisterFailed, onRegisterSuccess, 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) controlParameters.setOrigin(65) 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()) # 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)
def expressInterestPirAndRepeat(self): self.log.debug("callbackCountUniqueData: " + str(self._callbackCountUniqueData) + ", callbackCountTimeout: " + str(self._callbackCountTimeout)) # Express interest for each pir we have discovered for pir in self.getPirs(): interest = Interest(Name(pir.id)) interest.setExclude(pir.status.getExclude()) interest.setInterestLifetimeMilliseconds(1000.0) interest.setChildSelector(1) self.face.expressInterest(interest, self.onDataPir, self.onTimeoutPir) self._countExpressedInterests += 1 debugStr = "Sent interest: " + interest.getName().toUri() debugStr += "\tExclude: " + interest.getExclude().toUri() debugStr += "\tLifetime: " + str(interest.getInterestLifetimeMilliseconds()) self.log.debug(debugStr) # Reschedule again in 0.5 sec self.loop.call_later(1.0, self.expressInterestPirAndRepeat)
class TestInterestMethods(ut.TestCase): def setUp(self): self.referenceInterest = Interest() self.referenceInterest.wireDecode(codedInterest) def test_copy_constructor(self): interest = Interest(self.referenceInterest) self.assertTrue(interestDumpsEqual(dumpInterest(interest), dumpInterest(self.referenceInterest)), 'Interest constructed as deep copy does not match original') def test_empty_nonce(self): # make sure a freshly created interest has no nonce freshInterest = createFreshInterest() self.assertTrue(freshInterest.getNonce().isNull(), 'Freshly created interest should not have a nonce') def test_set_removes_nonce(self): # Ensure that changing a value on an interest clears the nonce. self.assertFalse(self.referenceInterest.getNonce().isNull()) interest = Interest(self.referenceInterest) # Change a child object. interest.getExclude().clear() self.assertTrue(interest.getNonce().isNull(), 'Interest should not have a nonce after changing fields') def test_refresh_nonce(self): interest = Interest(self.referenceInterest) oldNonce = interest.getNonce() self.assertEqual(4, oldNonce.size()) interest.refreshNonce() self.assertEqual(oldNonce.size(), interest.getNonce().size(), "The refreshed nonce should be the same size") self.assertFalse(interest.getNonce().equals(oldNonce), "The refreshed nonce should be different") def test_exclude_matches(self): exclude = Exclude() exclude.appendComponent(Name("%00%02").get(0)) exclude.appendAny() exclude.appendComponent(Name("%00%20").get(0)) component = Name("%00%01").get(0) self.assertFalse(exclude.matches(component), component.toEscapedString() + " should not match " + exclude.toUri()) component = Name("%00%0F").get(0) self.assertTrue(exclude.matches(component), component.toEscapedString() + " should match " + exclude.toUri()) component = Name("%00%21").get(0) self.assertFalse(exclude.matches(component), component.toEscapedString() + " should not match " + exclude.toUri()) def test_verify_digest_sha256(self): # Create a KeyChain but we don't need to add keys. identityStorage = MemoryIdentityStorage() keyChain = KeyChain( IdentityManager(identityStorage, MemoryPrivateKeyStorage()), SelfVerifyPolicyManager(identityStorage)) interest = Interest(Name("/test/signed-interest")) keyChain.signWithSha256(interest) # We create 'mock' objects to replace callbacks since we're not # interested in the effect of the callbacks themselves. failedCallback = Mock() verifiedCallback = Mock() keyChain.verifyInterest(interest, verifiedCallback, failedCallback) self.assertEqual(failedCallback.call_count, 0, 'Signature verification failed') self.assertEqual(verifiedCallback.call_count, 1, 'Verification callback was not used.') def test_matches_data(self): interest = Interest(Name("/A")) interest.setMinSuffixComponents(2) interest.setMaxSuffixComponents(2) interest.getKeyLocator().setType(KeyLocatorType.KEYNAME) interest.getKeyLocator().setKeyName(Name("/B")) interest.getExclude().appendComponent(Name.Component("J")) interest.getExclude().appendAny() data = Data(Name("/A/D")) signature = Sha256WithRsaSignature() signature.getKeyLocator().setType(KeyLocatorType.KEYNAME) signature.getKeyLocator().setKeyName(Name("/B")) data.setSignature(signature) self.assertEqual(interest.matchesData(data), True) # Check violating MinSuffixComponents. data1 = Data(data) data1.setName(Name("/A")) self.assertEqual(interest.matchesData(data1), False) interest1 = Interest(interest) interest1.setMinSuffixComponents(1) self.assertEqual(interest1.matchesData(data1), True) # Check violating MaxSuffixComponents. data2 = Data(data) data2.setName(Name("/A/E/F")) self.assertEqual(interest.matchesData(data2), False) interest2 = Interest(interest) interest2.setMaxSuffixComponents(3) self.assertEqual(interest2.matchesData(data2), True) # Check violating PublisherPublicKeyLocator. data3 = Data(data) signature3 = Sha256WithRsaSignature() signature3.getKeyLocator().setType(KeyLocatorType.KEYNAME) signature3.getKeyLocator().setKeyName(Name("/G")) data3.setSignature(signature3) self.assertEqual(interest.matchesData(data3), False) interest3 = Interest(interest) interest3.getKeyLocator().setType(KeyLocatorType.KEYNAME) interest3.getKeyLocator().setKeyName(Name("/G")) self.assertEqual(interest3.matchesData(data3), True) data4 = Data(data) data4.setSignature(DigestSha256Signature()) self.assertEqual(interest.matchesData(data4), False) interest4 = Interest(interest) interest4.setKeyLocator(KeyLocator()) self.assertEqual(interest4.matchesData(data4), True) # Check violating Exclude. data5 = Data(data) data5.setName(Name("/A/J")) self.assertEqual(interest.matchesData(data5), False) interest5 = Interest(interest) interest5.getExclude().clear() interest5.getExclude().appendComponent(Name.Component("K")) interest5.getExclude().appendAny() self.assertEqual(interest5.matchesData(data5), True) # Check violating Name. data6 = Data(data) data6.setName(Name("/H/I")) self.assertEqual(interest.matchesData(data6), False) data7 = Data(data) data7.setName(Name("/A/B")) interest7 = Interest( Name("/A/B/sha256digest=" + "54008e240a7eea2714a161dfddf0dd6ced223b3856e9da96792151e180f3b128")) self.assertEqual(interest7.matchesData(data7), True) # Check violating the implicit digest. interest7b = Interest( Name("/A/B/%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00" + "%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00")) self.assertEqual(interest7b.matchesData(data7), False) # Check excluding the implicit digest. interest8 = Interest(Name("/A/B")) interest8.getExclude().appendComponent(interest7.getName().get(2)) self.assertEqual(interest8.matchesData(data7), False) def test_interest_filter_matching(self): self.assertEqual(True, InterestFilter("/a").doesMatch(Name("/a/b"))) self.assertEqual(True, InterestFilter("/a/b").doesMatch(Name("/a/b"))) self.assertEqual(False, InterestFilter("/a/b/c").doesMatch(Name("/a/b"))) self.assertEqual(True, InterestFilter("/a", "<b>").doesMatch(Name("/a/b"))) self.assertEqual(False, InterestFilter("/a/b", "<b>").doesMatch(Name("/a/b"))) self.assertEqual(False, InterestFilter("/a/b", "<c>").doesMatch(Name("/a/b/c/d"))) self.assertEqual(False, InterestFilter("/a/b", "<b>").doesMatch(Name("/a/b/c/b"))) self.assertEqual(True, InterestFilter("/a/b", "<>*<b>").doesMatch(Name("/a/b/c/b"))) self.assertEqual(False, InterestFilter("/a", "<b>").doesMatch(Name("/a/b/c/d"))) self.assertEqual(True, InterestFilter("/a", "<b><>*").doesMatch(Name("/a/b/c/d"))) self.assertEqual(True, InterestFilter("/a", "<b><>*").doesMatch(Name("/a/b"))) self.assertEqual(False, InterestFilter("/a", "<b><>+").doesMatch(Name("/a/b"))) self.assertEqual(True, InterestFilter("/a", "<b><>+").doesMatch(Name("/a/b/c"))) def test_set_application_parameters(self): interest = Interest("/ndn") self.assertTrue(not interest.hasApplicationParameters()) applicationParameters = Blob(bytearray([ 0x23, 0x00 ])) interest.setApplicationParameters(applicationParameters) self.assertTrue(interest.hasApplicationParameters()) self.assertTrue(interest.getApplicationParameters().equals (applicationParameters)) decodedInterest = Interest() decodedInterest.wireDecode(interest.wireEncode()) self.assertTrue(decodedInterest.getApplicationParameters().equals (applicationParameters)) interest.setApplicationParameters(Blob()) self.assertTrue(not interest.hasApplicationParameters()) def test_append_parameters_digest(self): name = Name("/local/ndn/prefix") interest = Interest(name) self.assertTrue(not interest.hasApplicationParameters()) # No parameters yet, so it should do nothing. interest.appendParametersDigestToName() self.assertEqual("/local/ndn/prefix", interest.getName().toUri()) applicationParameters = Blob(bytearray([ 0x23, 0x01, 0xC0 ])) interest.setApplicationParameters(applicationParameters) self.assertTrue(interest.hasApplicationParameters()) interest.appendParametersDigestToName() self.assertEqual(name.size() + 1, interest.getName().size()) self.assertTrue(interest.getName().getPrefix(-1).equals(name)) SHA256_LENGTH = 32 self.assertEqual(SHA256_LENGTH, interest.getName().get(-1).getValue().size()) self.assertEqual(interest.getName().toUri(), "/local/ndn/prefix/" + "params-sha256=a16cc669b4c9ef6801e1569488513f9523ffb28a39e53aa6e11add8d00a413fc")
def on_interest(self, _prefix, interest: Interest, face, _filter_id, _filter): name = str(interest.getName()) if name in self.name_str_to_data: self.face.putData(self.name_str_to_data[name]) logging.info('Serve data: {}'.format(name))
def exec_ndn_ping(): nonlocal last_ping_data name = request.form['name'] can_be_prefix = request.form['can_be_prefix'] == 'true' must_be_fresh = request.form['must_be_fresh'] == 'true' try: interest_lifetime = float( request.form['interest_lifetime']) * 1000.0 except ValueError: interest_lifetime = 4000.0 interest = Interest(name) interest.canBePrefix = can_be_prefix interest.mustBeFresh = must_be_fresh interest.interestLifetimeMilliseconds = interest_lifetime st_time = time.time() ret = run_until_complete(fetch_data_packet(server.face, interest)) ed_time = time.time() response_time = '{:.3f}s'.format(ed_time - st_time) if isinstance(ret, Data): response_type = 'Data' name = ret.name.toUri() if ret.metaInfo.type is not None: content_type = decode_content_type(ret.metaInfo.type) else: content_type = "None" if ret.metaInfo.freshnessPeriod is not None: freshness_period = "{:.3f}s".format( ret.metaInfo.freshnessPeriod / 1000.0) else: freshness_period = "None" if ret.metaInfo.finalBlockId is not None: final_block_id = ret.metaInfo.finalBlockId.toEscapedString() else: final_block_id = "None" signature_type = type(ret.signature).__name__ last_ping_data = ret.content.toBytes() return redirect( url_for('ndn_ping', response_time=response_time, response_type=response_type, name=name, content_type=content_type, freshness_period=freshness_period, final_block_id=final_block_id, signature_type=signature_type, download='/download/ping-data')) elif isinstance(ret, NetworkNack): response_type = 'NetworkNack' reason = decode_nack_reason(ret.getReason()) return redirect( url_for('ndn_ping', response_time=response_time, response_type=response_type, name=name, reason=reason)) elif ret is None: response_type = 'Timeout' return redirect( url_for('ndn_ping', response_time=response_time, response_type=response_type, name=name)) else: logging.info("No response: ndn-ping") return redirect('/')
def onNewData(self, interest, data): """ !! Again \n in public key?? Got data: { "ecdh-pub": "Aqxofe3QdsAfgbtS8TMxv31oudNKoSV307ci5gNXm88h\n", "salt": "12935684137560555161", "request-id": "14275252044236690531", "status": "0", "challenges": [ { "challenge-id": "Email" } ] } 1. Verify data 2. Derive shared secret """ content = data.getContent() print("Got data: ", content) if not VerificationHelpers.verifyDataSignature(data, self.anchor): print("Cannot verify signature from: {}".format(self.caPrefix)) else: print("Successfully verified data with hard-coded certificate") contentJson = json.loads(content.__str__()) peerKeyBase64 = contentJson['ecdh-pub'] self.status = contentJson['status'] self.requestId = contentJson['request-id'] self.challenges = contentJson['challenges'] print(peerKeyBase64) serverPubKey = ec.EllipticCurvePublicKey.from_encoded_point( ec.SECP256R1(), b64decode(peerKeyBase64)) shared_key = self.ecdh.private_key.exchange(ec.ECDH(), serverPubKey) derived_key = HKDF(algorithm=hashes.SHA256(), length=32, salt=contentJson['salt'].encode(), info=b'handshake data', backend=default_backend()).derive(shared_key) self.ecdh.derived_key = derived_key print(shared_key) for t in shared_key: print(t) challengeInterestName = Name( self.caPrefix).append("CA").append("_CHALLENGE").append( self.requestId) challengeInterest = Interest(challengeInterestName) challengeInterest.setMustBeFresh(True) challengeInterest.setCanBePrefix(False) # Encrypt the interest parameters challengeJson = json.dumps( { "selected-challenge": "Email", "email": "*****@*****.**" }, indent=4) raw = self.pad(challengeJson, 16) print("raw", raw) iv = Random.new().read(AES.block_size) #cipher = AES.new(self.ecdh.derived_key, AES.MODE_CBC, iv) cipher = AES.new(shared_key, AES.MODE_CBC, iv) print(iv) xx = cipher.encrypt(raw) print(cipher.decrypt(xx)) print("Printing iv:") for t in iv: print(t) encoder = TlvEncoder(256) saveLength = len(encoder) encoder.writeBlobTlv(632, iv) encoder.writeBlobTlv(630, cipher.encrypt(raw)) #encoder.writeTypeAndLength(36, len(encoder) - saveLength) challengeInterest.setApplicationParameters(Blob(encoder.getOutput())) challengeInterest.appendParametersDigestToName() self.keyChain.sign(challengeInterest, SigningInfo(self.key)) with open('foobar.tlv', 'wb') as f: f.write(challengeInterest.wireEncode().buf()) self.face.expressInterest(challengeInterest, self.onChallengeData, self.onTimeout)
def main(): interest = Interest() interest.wireDecode(TlvInterest) dump("Interest:") dumpInterest(interest) # Set the name again to clear the cached encoding so we encode again. interest.setName(interest.getName()) encoding = interest.wireEncode() dump("") dump("Re-encoded interest", encoding.toHex()) reDecodedInterest = Interest() reDecodedInterest.wireDecode(encoding) dump("Re-decoded Interest:") dumpInterest(reDecodedInterest) freshInterest = (Interest( Name("/ndn/abc")).setMustBeFresh(False).setMinSuffixComponents( 4).setMaxSuffixComponents(6).setInterestLifetimeMilliseconds( 30000).setChildSelector(1).setMustBeFresh(True)) freshInterest.getKeyLocator().setType(KeyLocatorType.KEY_LOCATOR_DIGEST) freshInterest.getKeyLocator().setKeyData( bytearray([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F ])) freshInterest.getExclude().appendComponent(Name("abc")[0]).appendAny() dump(freshInterest.toUri()) identityStorage = MemoryIdentityStorage() privateKeyStorage = MemoryPrivateKeyStorage() keyChain = KeyChain(IdentityManager(identityStorage, privateKeyStorage), SelfVerifyPolicyManager(identityStorage)) # Initialize the storage. keyName = Name("/testname/DSK-123") certificateName = keyName.getSubName( 0, keyName.size() - 1).append("KEY").append( keyName[-1]).append("ID-CERT").append("0") identityStorage.addKey(keyName, KeyType.RSA, Blob(DEFAULT_RSA_PUBLIC_KEY_DER)) privateKeyStorage.setKeyPairForKeyName(keyName, KeyType.RSA, DEFAULT_RSA_PUBLIC_KEY_DER, DEFAULT_RSA_PRIVATE_KEY_DER) # Make a Face just so that we can sign the interest. face = Face("localhost") face.setCommandSigningInfo(keyChain, certificateName) face.makeCommandInterest(freshInterest) reDecodedFreshInterest = Interest() reDecodedFreshInterest.wireDecode(freshInterest.wireEncode()) dump("") dump("Re-decoded fresh Interest:") dumpInterest(reDecodedFreshInterest) keyChain.verifyInterest(reDecodedFreshInterest, makeOnVerified("Freshly-signed Interest"), makeOnVerifyFailed("Freshly-signed Interest"))
def generateKeyAndSendNewInterest(self, probeTokenData): """ """ pib = self.keyChain.getPib() try: identity = pib.getIdentity(self.identityName) self.key = self.keyChain.createKey(identity) except Exception as e: identity = self.keyChain.createIdentityV2(self.identityName) self.key = identity.getDefaultKey() cert = CertificateV2() cert.setName( Name(self.key.getName()).append("cert-request").appendVersion( int(time.time()))) cert.getMetaInfo().setType(ContentType.KEY) cert.getMetaInfo().setFreshnessPeriod(24 * 3600) cert.setContent(self.key.getPublicKey()) signingInfo = SigningInfo(self.key) now = Common.getNowMilliseconds() signingInfo.setValidityPeriod( ValidityPeriod(now, now + 24 * 3600 * 1000.0)) self.keyChain.sign(cert, signingInfo) #cert = self.keyChain.selfSign(self.key) # Does not work because validity period is greater than certserver default interestName = Name(self.caPrefix).append("CA").append("_NEW") newInterest = Interest(interestName) newInterest.setMustBeFresh(True) newInterest.setCanBePrefix(False) ecdhPub = "{}\n".format(self.ecdh.getBase64PubKey()) ecdhCertReq = "{}\n".format( b64encode(cert.wireEncode().toBytes()).decode('utf-8')) probeToken = "{}\n".format( b64encode(probeTokenData.wireEncode().toBytes()).decode('utf-8')) jsonDump = json.dumps( { "ecdh-pub": ecdhPub, "cert-request": ecdhCertReq, "probe-token": probeToken }, indent=4) print(jsonDump) newInterest.setApplicationParameters(jsonDump) newInterest.appendParametersDigestToName() self.keyChain.sign(newInterest, SigningInfo(self.key)) print(newInterest.getName()) self.face.expressInterest(newInterest, self.onNewData, self.onTimeout)
def onCatalogData(self, interest, data): # Find the next catalog print "Received catalog data " + data.getName().toUri() catalogTimestamp = data.getName().get(-2) exclude = Exclude() exclude.appendAny() exclude.appendComponent(catalogTimestamp) nextCatalogInterest = Interest(interest.getName()) nextCatalogInterest.setExclude(exclude) nextCatalogInterest.setChildSelector(0) nextCatalogInterest.setMustBeFresh(True) nextCatalogInterest.setInterestLifetimeMilliseconds(2000) self.face.expressInterest(nextCatalogInterest, self.onCatalogData, self.onCatalogTimeout) print "Expressed catalog interest " + nextCatalogInterest.getName( ).toUri() # We ignore the version in the catalog if self.encrypted: self.consumer.consume(contentName, self.onCatalogConsumeComplete, self.onConsumeFailed) else: self.onCatalogConsumeComplete(data, data.getContent())
def test_set_application_parameters(self): interest = Interest("/ndn") self.assertTrue(not interest.hasApplicationParameters()) applicationParameters = Blob(bytearray([ 0x23, 0x00 ])) interest.setApplicationParameters(applicationParameters) self.assertTrue(interest.hasApplicationParameters()) self.assertTrue(interest.getApplicationParameters().equals (applicationParameters)) decodedInterest = Interest() decodedInterest.wireDecode(interest.wireEncode()) self.assertTrue(decodedInterest.getApplicationParameters().equals (applicationParameters)) interest.setApplicationParameters(Blob()) self.assertTrue(not interest.hasApplicationParameters())
def test_validate_interests_but_bypass_for_data(self): interest = Interest( Name("/Security/V2/ValidatorFixture/Sub1/Sub2/Interest")) data = Data( Name("/Security/V2/ValidatorFixture/Sub1/Sub2/Interest")) self.validateExpectFailure(interest, "Unsigned") self.validateExpectSuccess( data, "The policy requests to bypass validation for all data") self.assertEqual(0, len(self._fixture._face._sentInterests)) self._fixture._face._sentInterests = [] interest = Interest( Name("/Security/V2/ValidatorFixture/Sub1/Sub2/Interest")) self._fixture._keyChain.sign( interest, SigningInfo(SigningInfo.SignerType.SHA256)) self._fixture._keyChain.sign( data, SigningInfo(SigningInfo.SignerType.SHA256)) self.validateExpectFailure(interest, "Required KeyLocator/Name is missing (not passed to the policy)") self.validateExpectSuccess( data, "The policy requests to bypass validation for all data") self.assertEqual(0, len(self._fixture._face._sentInterests)) self._fixture._face._sentInterests = [] interest = Interest( Name("/Security/V2/ValidatorFixture/Sub1/Sub2/Interest")) self._fixture._keyChain.sign(interest, SigningInfo(self._fixture._identity)) self._fixture._keyChain.sign(data, SigningInfo(self._fixture._identity)) self.validateExpectSuccess(interest, "Should be successful since it is signed by the anchor") self.validateExpectSuccess( data, "The policy requests to bypass validation for all data") self.assertEqual(0, len(self._fixture._face._sentInterests)) self._fixture._face._sentInterests = [] interest = Interest( Name("/Security/V2/ValidatorFixture/Sub1/Sub2/Interest")) self._fixture._keyChain.sign(interest, SigningInfo(self._fixture._subIdentity)) self._fixture._keyChain.sign(data, SigningInfo(self._fixture._subIdentity)) self.validateExpectFailure(interest, "Should fail since the policy is not allowed to create new trust anchors") self.validateExpectSuccess( data, "The policy requests to bypass validation for all data") self.assertEqual(1, len(self._fixture._face._sentInterests)) self._fixture._face._sentInterests = [] interest = Interest( Name("/Security/V2/ValidatorFixture/Sub1/Sub2/Interest")) self._fixture._keyChain.sign(interest, SigningInfo(self._fixture._otherIdentity)) self._fixture._keyChain.sign(data, SigningInfo(self._fixture._otherIdentity)) self.validateExpectFailure(interest, "Should fail since it is signed by a policy-violating certificate") self.validateExpectSuccess( data, "The policy requests to bypass validation for all data") # No network operations are expected since the certificate is not # validated by the policy. self.assertEqual(0, len(self._fixture._face._sentInterests)) self._fixture._face._sentInterests = [] # Make the trusted cache simulate a time 2 hours later, after expiration. self._fixture._validator._setCacheNowOffsetMilliseconds(2 * 3600 * 1000.0) interest = Interest( Name("/Security/V2/ValidatorFixture/Sub1/Sub2/Interest")) self._fixture._keyChain.sign(interest, SigningInfo(self._fixture._subSelfSignedIdentity)) self._fixture._keyChain.sign(data, SigningInfo(self._fixture._subSelfSignedIdentity)) self.validateExpectFailure(interest, "Should fail since the policy is not allowed to create new trust anchors") self.validateExpectSuccess(data, "The policy requests to bypass validation for all data") self.assertEqual(1, len(self._fixture._face._sentInterests)) self._fixture._face._sentInterests = []