def querySeed(self, seed, pubkey): """ Query an HTTP seed and return a `list` if (ip, port) `tuple` pairs. Args: seed: A `string` consisting of "ip:port" or "hostname:port" pubkey: The hex encoded public key to verify the signature on the response """ nodes = [] c = httplib.HTTPConnection(seed) c.request("GET", "/") response = c.getresponse() self.log.info("Https response from %s: %s, %s" % (seed, response.status, response.reason)) data = response.read() reread_data = data.decode("zlib") proto = peers.PeerSeeds() try: proto.ParseFromString(reread_data) for peer in proto.peer_data: p = peers.PeerData() p.ParseFromString(peer) tup = (str(p.ip_address), p.port) nodes.append(tup) verify_key = nacl.signing.VerifyKey(pubkey, encoder=nacl.encoding.HexEncoder) verify_key.verify(proto.signature + "".join(proto.peer_data)) return nodes except Exception: self.log.error("Error parsing seed response.") return nodes
def querySeed(self, list_seed_pubkey): """ Query an HTTP seed for known vendors and save the vendors to the db. Args: Receives a list of one or more tuples Example [(seed, pubkey)] seed: A `string` consisting of "ip:port" or "hostname:port" pubkey: The hex encoded public key to verify the signature on the response """ for sp in list_seed_pubkey: seed, pubkey = sp try: self.log.debug("querying %s for vendors" % seed) c = httplib.HTTPConnection(seed) c.request("GET", "/?type=vendors") response = c.getresponse() self.log.debug("Http response from %s: %s, %s" % (seed, response.status, response.reason)) data = response.read() reread_data = data.decode("zlib") proto = peers.PeerSeeds() proto.ParseFromString(reread_data) v = self.db.VendorStore() for peer in proto.peer_data: p = peers.PeerData() p.ParseFromString(peer) v.save_vendor(p.guid.encode("hex"), p.ip_address, p.port, p.signedPubkey) verify_key = nacl.signing.VerifyKey( pubkey, encoder=nacl.encoding.HexEncoder) verify_key.verify("".join(proto.peer_data), proto.signature) except Exception, e: self.log.error("failed to query seed: %s" % str(e))
def querySeed(self, list_seed_pubkey): """ Query an HTTP seed and return a `list` if (ip, port) `tuple` pairs. Args: Receives a list of one or more tuples Example [(seed, pubkey)] seed: A `string` consisting of "ip:port" or "hostname:port" pubkey: The hex encoded public key to verify the signature on the response """ nodes = [] if not list_seed_pubkey: self.log.error('failed to query seed {0} from ob.cfg'.format( list_seed_pubkey)) return nodes else: for sp in list_seed_pubkey: seed, pubkey = sp try: self.log.info("querying %s for peers" % seed) c = httplib.HTTPConnection(seed) c.request("GET", "/") response = c.getresponse() self.log.debug("Http response from %s: %s, %s" % (seed, response.status, response.reason)) data = response.read() reread_data = data.decode("zlib") proto = peers.PeerSeeds() proto.ParseFromString(reread_data) for peer in proto.peer_data: p = peers.PeerData() p.ParseFromString(peer) tup = (str(p.ip_address), p.port) nodes.append(tup) verify_key = nacl.signing.VerifyKey( pubkey, encoder=nacl.encoding.HexEncoder) verify_key.verify("".join(proto.peer_data), proto.signature) self.log.info("%s returned %s addresses" % (seed, len(nodes))) except Exception, e: self.log.error("failed to query seed: %s" % str(e)) return nodes
def render_GET(self, request): nodes = self.nodes.values() shuffle(nodes) logger.info("Received a request for nodes, responding...") if "format" in request.args: if request.args["format"][0] == "json": json_list = [] if "type" in request.args and request.args["type"][ 0] == "vendors": for node in nodes: if node.vendor is True: node_dic = {} node_dic["ip"] = node.ip node_dic["port"] = node.port node_dic["guid"] = node.id.encode("hex") node_dic[ "signed_pubkey"] = node.signed_pubkey.encode( "hex") json_list.append(node_dic) sig = signing_key.sign(str(json_list)) resp = { "peers": json_list, "signature": hexlify(sig[:64]) } request.write(json.dumps(resp, indent=4)) else: for node in nodes[:50]: node_dic = {} node_dic["ip"] = node.ip node_dic["port"] = node.port json_list.append(node_dic) sig = signing_key.sign(str(json_list)) resp = { "peers": json_list, "signature": hexlify(sig[:64]) } request.write(json.dumps(resp, indent=4)) elif request.args["format"][0] == "protobuf": proto = peers.PeerSeeds() for node in nodes[:50]: peer = peers.PeerData() peer.ip_address = node.ip peer.port = node.port peer.vendor = node.vendor proto.peer_data.append(peer.SerializeToString()) sig = signing_key.sign("".join(proto.peer_data))[:64] proto.signature = sig uncompressed_data = proto.SerializeToString() request.write(uncompressed_data.encode("zlib")) else: proto = peers.PeerSeeds() if "type" in request.args and request.args["type"][ 0] == "vendors": for node in nodes: if node.vendor is True: peer = peers.PeerData() peer.ip_address = node.ip peer.port = node.port peer.vendor = node.vendor peer.guid = node.id peer.signedPubkey = node.signed_pubkey proto.peer_data.append(peer.SerializeToString()) sig = signing_key.sign("".join(proto.peer_data))[:64] proto.signature = sig uncompressed_data = proto.SerializeToString() request.write(uncompressed_data.encode("zlib")) else: for node in nodes[:50]: peer = peers.PeerData() peer.ip_address = node.ip peer.port = node.port peer.vendor = node.vendor proto.peer_data.append(peer.SerializeToString()) sig = signing_key.sign("".join(proto.peer_data))[:64] proto.signature = sig uncompressed_data = proto.SerializeToString() request.write(uncompressed_data.encode("zlib")) request.finish() return server.NOT_DONE_YET