def _getID(self): """ Returns a tuple: private key, public key, nodeID, private group ID, and public group ID from config. If these values don't exist in conf file, they are generated and added. """ # get the keys and IDs from the config file. # If these values don't exist, generate a pub/priv key pair, nodeID, # and groupIDs. if not self.configParser.has_section("identification"): self.configParser.add_section("identification") try: privkey = FludRSA.importPrivateKey( eval(self.configParser.get("identification","Kr"))) except: pubkey, privkey = FludCrypto.generateKeys() else: try: pubkey = FludRSA.importPublicKey( eval(self.configParser.get("identification","Ku"))) except: pubkey = privkey.publickey() try: nodeID = self.configParser.get("identification","nodeID") except: #nodeID = FludCrypto.hashstring(str(pubkey.exportPublicKey())) nodeID = pubkey.id() try: privgroupID = self.configParser.get("identification", "groupIDr")[:64] except: privgroupID = 'fludtest' # default groupID hardcoded try: pubgroupID = self.configParser.get("identification","groupIDu") except: pubgroupID = FludCrypto.hashstring(str(pubkey.exportPublicKey()) +privgroupID) # write the settings back out to config object self.configParser.set("identification","Kr",privkey.exportPrivateKey()) self.configParser.set("identification","Ku",pubkey.exportPublicKey()) self.configParser.set("identification","nodeID",nodeID) self.configParser.set("identification","groupIDr",privgroupID) self.configParser.set("identification","groupIDu",pubgroupID) # return the values return privkey, pubkey, nodeID, privgroupID, pubgroupID
def updateNodes(client, config, nodes): if nodes and not isinstance(nodes, list) and not isinstance(nodes, tuple): raise TypeError("updateNodes must be called with node list, tuple," " or kData dict") logger.debug("updateNodes(%s)" % nodes) for i in nodes: host = i[0] port = i[1] nID = i[2] nKu = FludRSA.importPublicKey(i[3]) updateNode(client, config, host, port, nKu, nID)
def _getID(self, response, factory, host, port): loggerid.debug( "received ID response: %s" % response) if not hasattr(factory, 'status'): raise failure.DefaultException( "SENDGETID FAILED: no status in factory") if eval(factory.status) != http.OK: raise failure.DefaultException("SENDGETID FAILED to "+self.dest+": " +"server sent status "+factory.status+", '"+response+"'") try: nKu = {} nKu = eval(response) nKu = FludRSA.importPublicKey(nKu) loggerid.info("SENDGETID PASSED to %s" % self.dest) updateNode(self.node.client, self.config, host, port, nKu) return nKu except: raise failure.DefaultException("SENDGETID FAILED to "+self.dest+": " +"received response, but it did not contain valid key")
def updateNode(client, config, host, port, nKu=None, nID=None): """ Updates this node's view of the given node. This includes updating the known-nodes record, trust, and routing table information """ def updateNodeFail(failure, host, port): logging.getLogger('flud').log(logging.INFO, "couldn't get nodeID from %s:%d: %s" % (host, port, failure)) def callUpdateNode(nKu, client, config, host, port, nID): return updateNode(client, config, host, port, nKu, nID) if isinstance(nID, long): nID = "%064x" % nID if nKu is None: #print "updateNode, no nKu" if nID is None: d = client.sendGetID(host, port) d.addCallback(callUpdateNode, client, config, host, port, nID) d.addErrback(updateNodeFail, host, port) else: #print "updateNode, no nKu but got a nID" if config.nodes.has_key(nID): return updateNode(client, config, host, port, FludRSA.importPublicKey(config.nodes[nID]['Ku']), nID) elif updateNodePendingGETID.has_key(nID): pass else: #print "updateNode, sending GETID" updateNodePendingGETID[nID] = True d = client.sendGetID(host, port) d.addCallback(callUpdateNode, client, config, host, port, nID) d.addErrback(updateNodeFail, host, port) elif isinstance(nKu, FludRSA): #print "updateNode with nKu" if updateNodePendingGETID.has_key(nID): del updateNodePendingGETID[nID] if nID == None: nID = nKu.id() elif nID != nKu.id(): raise ValueError("updateNode: given nID doesn't match given nKu." " '%s' != '%s'" % (nID, nKu.id())) # XXX: looks like an imposter -- instead of raising, mark host:port # pair as bad (trust-- on host:port alone, since we don't know id). if config.nodes.has_key(nID) == False: config.addNode(nID, host, port, nKu) # XXX: trust # routing node = (host, port, long(nID, 16), nKu.exportPublicKey()['n']) replacee = config.routing.updateNode(node) #logger.info("knownnodes now: %s" % config.routing.knownNodes()) #print "knownnodes now: %s" % config.routing.knownNodes() if replacee != None: logging.getLogger('flud').info( "determining if replacement in ktable is needed") s = SENDGETID(replacee[0], replacee[1]) s.addErrback(replaceNode, config.routing, replacee, node) else: #print "updateNode nKu=%s, type=%s" % (nKu, type(nKu)) logging.getLogger('flud').warn( "updateNode can't update without a public key or nodeID") frame = inspect.currentframe() # XXX: try/except here for debugging only try: stack = inspect.stack() for i in stack: print "from %s:%d" % (i[1], i[2]) except: print "couldn't get stack trace" raise ValueError("updateNode needs an nKu of type FludRSA" " (received %s) or an nID of type long or str (received %s)" % (type(nKu), type(nID)))
required = ('nodeID', 'Ku_e', 'Ku_n', 'port') params = requireParams(request, required) except Exception, inst: msg = "%s in request received by ID" % inst.args[0] loggerid.info(msg) request.setResponseCode(http.BAD_REQUEST, "Bad Request") return msg else: loggerid.info("received ID request from %s..." % params['nodeID'][:10]) loggerid.info("returning ID response") #try: reqKu = {} reqKu['e'] = long(params['Ku_e']) reqKu['n'] = long(params['Ku_n']) reqKu = FludRSA.importPublicKey(reqKu) if reqKu.id() != params['nodeID']: request.setResponseCode(http.BAD_REQUEST, "Bad Identity") return "requesting node's ID and public key do not match" host = getCanonicalIP(request.getClientIP()) updateNode(self.node.client, self.config, host, int(params['port']), reqKu, params['nodeID']) return str(self.config.Ku.exportPublicKey()) #except: # msg = "can't return ID" # loggerid.log(logging.WARN, msg) # request.setResponseCode(http.NO_CONTENT, msg) # return msg class FILE(ROOT): """ data storage file operations: POST, GET, DELETE """