def testSignOnion(self, tor_manager): address = tor_manager.addOnion() # Sign sign = CryptRsa.sign("hello", tor_manager.getPrivatekey(address)) assert len(sign) == 128 # Verify publickey = CryptRsa.privatekeyToPublickey(tor_manager.getPrivatekey(address)) assert len(publickey) == 140 assert CryptRsa.verify("hello", publickey, sign) assert not CryptRsa.verify("not hello", publickey, sign) # Pub to address assert CryptRsa.publickeyToOnion(publickey) == address # Delete tor_manager.delOnion(address)
def checkOnionSigns(self, onions, onion_signs, onion_sign_this): if not onion_signs or len(onion_signs) != len(set(onions)): return False if time.time() - float(onion_sign_this) > 3 * 60: return False # Signed out of allowed 3 minutes onions_signed = [] # Check onion signs for onion_publickey, onion_sign in onion_signs.items(): if CryptRsa.verify(onion_sign_this.encode(), onion_publickey, onion_sign): onions_signed.append(CryptRsa.publickeyToOnion(onion_publickey)) else: break # Check if the same onion addresses signed as the announced onces if sorted(onions_signed) == sorted(set(onions)): return True else: return False
def announceTracker(self, tracker_protocol, tracker_address, fileserver_port=0, add_types=[], my_peer_id="", mode="start"): if tracker_protocol != "zero": return super(SitePlugin, self).announceTracker( tracker_protocol, tracker_address, fileserver_port, add_types, my_peer_id, mode ) s = time.time() need_types = ["ip4"] if self.connection_server and self.connection_server.tor_manager and self.connection_server.tor_manager.enabled: need_types.append("onion") if mode == "start" or mode == "more": # Single: Announce only this site sites = [self] full_announce = False else: # Multi: Announce all currently serving site full_announce = True if time.time() - time_full_announced.get(tracker_address, 0) < 60 * 5: # No reannounce all sites within 5 minute return True time_full_announced[tracker_address] = time.time() from Site import SiteManager sites = [site for site in SiteManager.site_manager.sites.values() if site.settings["serving"]] # Create request request = { "hashes": [], "onions": [], "port": fileserver_port, "need_types": need_types, "need_num": 20, "add": add_types } for site in sites: if "onion" in add_types: onion = self.connection_server.tor_manager.getOnion(site.address) request["onions"].append(onion) request["hashes"].append(hashlib.sha256(site.address).digest()) # Tracker can remove sites that we don't announce if full_announce: request["delete"] = True # Sent request to tracker tracker = connection_pool.get(tracker_address) # Re-use tracker connection if possible if not tracker: tracker_ip, tracker_port = tracker_address.split(":") tracker = Peer(tracker_ip, tracker_port, connection_server=self.connection_server) connection_pool[tracker_address] = tracker res = tracker.request("announce", request) if not res or "peers" not in res: self.log.debug("Announce to %s failed: %s" % (tracker_address, res)) if full_announce: time_full_announced[tracker_address] = 0 return False # Add peers from response to site site_index = 0 for site_res in res["peers"]: site = sites[site_index] processPeerRes(site, site_res) site_index += 1 # Check if we need to sign prove the onion addresses if "onion_sign_this" in res: self.log.debug("Signing %s for %s to add %s onions" % (res["onion_sign_this"], tracker_address, len(sites))) request["onion_signs"] = {} request["onion_sign_this"] = res["onion_sign_this"] request["need_num"] = 0 for site in sites: onion = self.connection_server.tor_manager.getOnion(site.address) sign = CryptRsa.sign(res["onion_sign_this"], self.connection_server.tor_manager.getPrivatekey(onion)) request["onion_signs"][self.connection_server.tor_manager.getPublickey(onion)] = sign res = tracker.request("announce", request) if not res or "onion_sign_this" in res: self.log.debug("Announce onion address to %s failed: %s" % (tracker_address, res)) if full_announce: time_full_announced[tracker_address] = 0 return False if full_announce: tracker.remove() # Close connection, we don't need it in next 5 minute return time.time() - s
def announceTrackerZero(self, tracker_address, mode="start", num_want=10): global time_full_announced s = time.time() need_types = ["ip4"] if self.site.connection_server.tor_manager.enabled: need_types.append("onion") if mode == "start" or mode == "more": # Single: Announce only this site sites = [self.site] full_announce = False else: # Multi: Announce all currently serving site full_announce = True if time.time() - time_full_announced.get( tracker_address, 0) < 60 * 15: # No reannounce all sites within short time return None time_full_announced[tracker_address] = time.time() from Site import SiteManager sites = [ site for site in SiteManager.site_manager.sites.values() if site.settings["serving"] ] # Create request add_types = self.getOpenedServiceTypes() request = { "hashes": [], "onions": [], "port": self.fileserver_port, "need_types": need_types, "need_num": 20, "add": add_types } for site in sites: if "onion" in add_types: onion = self.site.connection_server.tor_manager.getOnion( site.address) request["onions"].append(onion) request["hashes"].append(site.address_hash) # Tracker can remove sites that we don't announce if full_announce: request["delete"] = True # Sent request to tracker tracker_peer = connection_pool.get( tracker_address) # Re-use tracker connection if possible if not tracker_peer: tracker_ip, tracker_port = tracker_address.split(":") tracker_peer = Peer(tracker_ip, tracker_port, connection_server=self.site.connection_server) tracker_peer.is_tracker_connection = True connection_pool[tracker_address] = tracker_peer res = tracker_peer.request("announce", request) if not res or "peers" not in res: if full_announce: time_full_announced[tracker_address] = 0 raise AnnounceError("Invalid response: %s" % res) # Add peers from response to site site_index = 0 peers_added = 0 for site_res in res["peers"]: site = sites[site_index] peers_added += processPeerRes(tracker_address, site, site_res) site_index += 1 # Check if we need to sign prove the onion addresses if "onion_sign_this" in res: self.site.log.debug( "Signing %s for %s to add %s onions" % (res["onion_sign_this"], tracker_address, len(sites))) request["onion_signs"] = {} request["onion_sign_this"] = res["onion_sign_this"] request["need_num"] = 0 for site in sites: onion = self.site.connection_server.tor_manager.getOnion( site.address) publickey = self.site.connection_server.tor_manager.getPublickey( onion) if publickey not in request["onion_signs"]: sign = CryptRsa.sign( res["onion_sign_this"], self.site.connection_server.tor_manager.getPrivatekey( onion)) request["onion_signs"][publickey] = sign res = tracker_peer.request("announce", request) if not res or "onion_sign_this" in res: if full_announce: time_full_announced[tracker_address] = 0 raise AnnounceError("Announce onion address to failed: %s" % res) if full_announce: tracker_peer.remove( ) # Close connection, we don't need it in next 5 minute self.site.log.debug( "Tracker announce result: zero://%s (sites: %s, new peers: %s) in %.3fs" % (tracker_address, site_index, peers_added, time.time() - s)) return True
def testAddOnion(self, file_server, site, bootstrapper_db, tor_manager): onion1 = tor_manager.addOnion() onion2 = tor_manager.addOnion() peer = Peer("127.0.0.1", 1544, connection_server=file_server) hash1 = hashlib.sha256("site1").digest() hash2 = hashlib.sha256("site2").digest() hash3 = hashlib.sha256("site3").digest() bootstrapper_db.peerAnnounce(ip4="1.2.3.4", port=1234, hashes=[hash1, hash2, hash3]) res = peer.request( "announce", { "onions": [onion1, onion1, onion2], "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert len(res["peers"][0]["ip4"]) == 1 # Onion address not added yet site_peers = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers["onion"]) == 0 assert "onion_sign_this" in res # Sign the nonces sign1 = CryptRsa.sign(res["onion_sign_this"], tor_manager.getPrivatekey(onion1)) sign2 = CryptRsa.sign(res["onion_sign_this"], tor_manager.getPrivatekey(onion2)) # Bad sign (different address) res = peer.request( "announce", { "onions": [onion1], "onion_sign_this": res["onion_sign_this"], "onion_signs": { tor_manager.getPublickey(onion2): sign2 }, "hashes": [hash1], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" in res site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 0 # Not added # Bad sign (missing one) res = peer.request( "announce", { "onions": [onion1, onion1, onion2], "onion_sign_this": res["onion_sign_this"], "onion_signs": { tor_manager.getPublickey(onion1): sign1 }, "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" in res site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 0 # Not added # Good sign res = peer.request( "announce", { "onions": [onion1, onion1, onion2], "onion_sign_this": res["onion_sign_this"], "onion_signs": { tor_manager.getPublickey(onion1): sign1, tor_manager.getPublickey(onion2): sign2 }, "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" not in res # Onion addresses added site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 1 site_peers2 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash2) assert len(site_peers2["onion"]) == 1 site_peers3 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash3) assert len(site_peers3["onion"]) == 1 assert site_peers1["onion"][0] == site_peers2["onion"][0] assert site_peers2["onion"][0] != site_peers3["onion"][0] assert helper.unpackOnionAddress( site_peers1["onion"][0])[0] == onion1 + ".onion" assert helper.unpackOnionAddress( site_peers2["onion"][0])[0] == onion1 + ".onion" assert helper.unpackOnionAddress( site_peers3["onion"][0])[0] == onion2 + ".onion" tor_manager.delOnion(onion1) tor_manager.delOnion(onion2)
def getPublickey(self, address): return CryptRsa.privatekeyToPublickey(self.privatekeys[address])
def actionAnnounce(self, params): time_started = time.time() s = time.time() hashes = params["hashes"] if "onion_signs" in params and len(params["onion_signs"]) == len(set(params["onions"])): # Check if all sign is correct if time.time() - float(params["onion_sign_this"]) < 3*60: # Peer has 3 minute to sign the message onions_signed = [] # Check onion signs for onion_publickey, onion_sign in params["onion_signs"].items(): if CryptRsa.verify(params["onion_sign_this"], onion_publickey, onion_sign): onions_signed.append(CryptRsa.publickeyToOnion(onion_publickey)) else: break # Check if the same onion addresses signed as the announced onces if sorted(onions_signed) == sorted(set(params["onions"])): all_onions_signed = True else: all_onions_signed = False else: # Onion sign this out of 3 minute all_onions_signed = False else: # Incorrect signs number all_onions_signed = False time_onion_check = time.time() - s if "ip4" in params["add"] and self.connection.ip != "127.0.0.1" and not self.connection.ip.endswith(".onion"): ip4 = self.connection.ip else: ip4 = None s = time.time() # Separatley add onions to sites or at once if no onions present i = 0 onion_to_hash = {} for onion in params.get("onions", []): if onion not in onion_to_hash: onion_to_hash[onion] = [] onion_to_hash[onion].append(hashes[i]) i += 1 hashes_changed = 0 db.execute("BEGIN") for onion, onion_hashes in onion_to_hash.iteritems(): hashes_changed += db.peerAnnounce( onion=onion, port=params["port"], hashes=onion_hashes, onion_signed=all_onions_signed ) db.execute("END") time_db_onion = time.time() - s s = time.time() # Announce all sites if ip4 defined if ip4: hashes_changed += db.peerAnnounce( ip4=ip4, port=params["port"], hashes=hashes, delete_missing_hashes=params.get("delete") ) time_db_ip4 = time.time() - s s = time.time() # Query sites back = {} peers = [] if params.get("onions") and not all_onions_signed and hashes_changed: back["onion_sign_this"] = "%.0f" % time.time() # Send back nonce for signing if len(hashes) > 500: limit = 5 order = False else: limit = 30 order = True for hash in hashes: if time.time() - time_started > 1: # 1 sec limit on request self.connection.log("Announce time limit exceeded after %s/%s sites" % (len(peers), len(hashes))) break hash_peers = db.peerList( hash, ip4=self.connection.ip, onions=onion_to_hash.keys(), port=params["port"], limit=min(limit, params["need_num"]), need_types=params["need_types"], order=order ) peers.append(hash_peers) time_peerlist = time.time() - s back["peers"] = peers self.connection.log( "Announce %s sites (onions: %s, onion_check: %.3fs, db_onion: %.3fs, db_ip4: %.3fs, peerlist: %.3fs)" % (len(hashes), len(onion_to_hash), time_onion_check, time_db_onion, time_db_ip4, time_peerlist) ) self.response(back)
def testAddOnion(self, file_server, site, bootstrapper_db, tor_manager): onion1 = tor_manager.addOnion() onion2 = tor_manager.addOnion() peer = Peer("127.0.0.1", 1544, connection_server=file_server) hash1 = hashlib.sha256("site1").digest() hash2 = hashlib.sha256("site2").digest() bootstrapper_db.peerAnnounce(ip4="1.2.3.4", port=1234, hashes=[hash1, hash2]) res = peer.request("announce", { "onions": [onion1, onion2], "hashes": [hash1, hash2], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert len(res["peers"][0]["ip4"]) == 1 assert "onion_sign_this" in res # Onion address not added yet site_peers = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers["onion"]) == 0 assert "onion_sign_this" in res # Sign the nonces sign1 = CryptRsa.sign(res["onion_sign_this"], tor_manager.getPrivatekey(onion1)) sign2 = CryptRsa.sign(res["onion_sign_this"], tor_manager.getPrivatekey(onion2)) # Bad sign (different address) res = peer.request("announce", { "onions": [onion1], "onion_sign_this": res["onion_sign_this"], "onion_signs": {tor_manager.getPublickey(onion2): sign2}, "hashes": [hash1], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" in res site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 0 # Not added # Bad sign (missing one) res = peer.request("announce", { "onions": [onion1, onion2], "onion_sign_this": res["onion_sign_this"], "onion_signs": {tor_manager.getPublickey(onion1): sign1}, "hashes": [hash1, hash2], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" in res site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 0 # Not added # Good sign res = peer.request("announce", { "onions": [onion1, onion2], "onion_sign_this": res["onion_sign_this"], "onion_signs": {tor_manager.getPublickey(onion1): sign1, tor_manager.getPublickey(onion2): sign2}, "hashes": [hash1, hash2], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"] }) assert "onion_sign_this" not in res # Onion addresses added site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1) assert len(site_peers1["onion"]) == 1 site_peers2 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash2) assert len(site_peers2["onion"]) == 1 assert site_peers1["onion"][0] != site_peers2["onion"][0] assert helper.unpackOnionAddress(site_peers1["onion"][0])[0] == onion1+".onion" assert helper.unpackOnionAddress(site_peers2["onion"][0])[0] == onion2+".onion" tor_manager.delOnion(onion1) tor_manager.delOnion(onion2)
def actionAnnounce(self, params): hashes = params["hashes"] if "onion_signs" in params and len(params["onion_signs"]) == len( set(params["onions"])): # Check if all sign is correct if time.time() - float( params["onion_sign_this"] ) < 3 * 60: # Peer has 3 minute to sign the message onions_signed = [] # Check onion signs for onion_publickey, onion_sign in params["onion_signs"].items( ): if CryptRsa.verify(params["onion_sign_this"], onion_publickey, onion_sign): onions_signed.append( CryptRsa.publickeyToOnion(onion_publickey)) else: break # Check if the same onion addresses signed as the announced onces if sorted(onions_signed) == sorted(set(params["onions"])): all_onions_signed = True else: all_onions_signed = False else: # Onion sign this out of 3 minute all_onions_signed = False else: # Incorrect signs number all_onions_signed = False if "ip4" in params[ "add"] and self.connection.ip != "127.0.0.1" and not self.connection.ip.endswith( ".onion"): ip4 = self.connection.ip else: ip4 = None # Separatley add onions to sites or at once if no onions present hashes_changed = 0 i = 0 for onion in params.get("onions", []): hashes_changed += db.peerAnnounce(onion=onion, port=params["port"], hashes=[hashes[i]], onion_signed=all_onions_signed) i += 1 # Announce all sites if ip4 defined if ip4: hashes_changed += db.peerAnnounce( ip4=ip4, port=params["port"], hashes=hashes, delete_missing_hashes=params.get("delete")) # Query sites back = {} peers = [] if params.get("onions") and not all_onions_signed and hashes_changed: back["onion_sign_this"] = "%.0f" % time.time( ) # Send back nonce for signing for hash in hashes: hash_peers = db.peerList(hash, ip4=self.connection.ip, onions=params.get("onions"), port=params["port"], limit=min(30, params["need_num"]), need_types=params["need_types"]) peers.append(hash_peers) back["peers"] = peers self.response(back)
def actionAnnounce(self, params): hashes = params["hashes"] if "onion_signs" in params and len(params["onion_signs"]) == len(hashes): # Check if all sign is correct if time.time() - float(params["onion_sign_this"]) < 3*60: # Peer has 3 minute to sign the message onions_signed = [] # Check onion signs for onion_publickey, onion_sign in params["onion_signs"].items(): if CryptRsa.verify(params["onion_sign_this"], onion_publickey, onion_sign): onions_signed.append(CryptRsa.publickeyToOnion(onion_publickey)) else: break # Check if the same onion addresses signed as the announced onces if sorted(onions_signed) == sorted(params["onions"]): all_onions_signed = True else: all_onions_signed = False else: # Onion sign this out of 3 minute all_onions_signed = False else: # Incorrect signs number all_onions_signed = False if "ip4" in params["add"] and self.connection.ip != "127.0.0.1" and not self.connection.ip.endswith(".onion"): ip4 = self.connection.ip else: ip4 = None # Separatley add onions to sites or at once if no onions present hashes_changed = 0 i = 0 for onion in params.get("onions", []): hashes_changed += db.peerAnnounce( onion=onion, port=params["port"], hashes=[hashes[i]], onion_signed=all_onions_signed ) i += 1 # Announce all sites if ip4 defined if ip4: hashes_changed += db.peerAnnounce( ip4=ip4, port=params["port"], hashes=hashes, delete_missing_hashes=params.get("delete") ) # Query sites back = {} peers = [] if params.get("onions") and not all_onions_signed and hashes_changed: back["onion_sign_this"] = "%.0f" % time.time() # Send back nonce for signing for hash in hashes: hash_peers = db.peerList( hash, ip4=self.connection.ip, onions=params.get("onions"), port=params["port"], limit=min(30, params["need_num"]), need_types=params["need_types"] ) peers.append(hash_peers) back["peers"] = peers self.response(back)
def actionAnnounce(self, params): time_started = time.time() s = time.time() hashes = params["hashes"] if "onion_signs" in params and len(params["onion_signs"]) == len( set(params["onions"])): # Check if all sign is correct if time.time() - float( params["onion_sign_this"] ) < 3 * 60: # Peer has 3 minute to sign the message onions_signed = [] # Check onion signs for onion_publickey, onion_sign in params["onion_signs"].items( ): if CryptRsa.verify(params["onion_sign_this"], onion_publickey, onion_sign): onions_signed.append( CryptRsa.publickeyToOnion(onion_publickey)) else: break # Check if the same onion addresses signed as the announced onces if sorted(onions_signed) == sorted(set(params["onions"])): all_onions_signed = True else: all_onions_signed = False else: # Onion sign this out of 3 minute all_onions_signed = False else: # Incorrect signs number all_onions_signed = False time_onion_check = time.time() - s if "ip4" in params[ "add"] and self.connection.ip != "127.0.0.1" and not self.connection.ip.endswith( ".onion"): ip4 = self.connection.ip else: ip4 = None s = time.time() # Separatley add onions to sites or at once if no onions present i = 0 onion_to_hash = {} for onion in params.get("onions", []): if onion not in onion_to_hash: onion_to_hash[onion] = [] onion_to_hash[onion].append(hashes[i]) i += 1 hashes_changed = 0 db.execute("BEGIN") for onion, onion_hashes in onion_to_hash.iteritems(): hashes_changed += db.peerAnnounce(onion=onion, port=params["port"], hashes=onion_hashes, onion_signed=all_onions_signed) db.execute("END") time_db_onion = time.time() - s s = time.time() # Announce all sites if ip4 defined if ip4: hashes_changed += db.peerAnnounce( ip4=ip4, port=params["port"], hashes=hashes, delete_missing_hashes=params.get("delete")) time_db_ip4 = time.time() - s s = time.time() # Query sites back = {} peers = [] if params.get("onions") and not all_onions_signed and hashes_changed: back["onion_sign_this"] = "%.0f" % time.time( ) # Send back nonce for signing if len(hashes) > 500 or not hashes_changed: limit = 5 order = False else: limit = 30 order = True for hash in hashes: if time.time() - time_started > 1: # 1 sec limit on request self.connection.log( "Announce time limit exceeded after %s/%s sites" % (len(peers), len(hashes))) break hash_peers = db.peerList(hash, ip4=self.connection.ip, onions=onion_to_hash.keys(), port=params["port"], limit=min(limit, params["need_num"]), need_types=params["need_types"], order=order) peers.append(hash_peers) time_peerlist = time.time() - s back["peers"] = peers self.connection.log( "Announce %s sites (onions: %s, onion_check: %.3fs, db_onion: %.3fs, db_ip4: %.3fs, peerlist: %.3fs, limit: %s)" % (len(hashes), len(onion_to_hash), time_onion_check, time_db_onion, time_db_ip4, time_peerlist, limit)) self.response(back)
def announceTrackerZero(self, tracker_address, mode="start", num_want=10): global time_full_announced s = time.time() need_types = ["ip4"] if self.site.connection_server.tor_manager.enabled: need_types.append("onion") if mode == "start" or mode == "more": # Single: Announce only this site sites = [self.site] full_announce = False else: # Multi: Announce all currently serving site full_announce = True if time.time() - time_full_announced.get(tracker_address, 0) < 60 * 5: # No reannounce all sites within 5 minute return [] time_full_announced[tracker_address] = time.time() from Site import SiteManager sites = [site for site in SiteManager.site_manager.sites.values() if site.settings["serving"]] # Create request add_types = self.getOpenedServiceTypes() request = { "hashes": [], "onions": [], "port": self.fileserver_port, "need_types": need_types, "need_num": 20, "add": add_types } for site in sites: if "onion" in add_types: onion = self.site.connection_server.tor_manager.getOnion(site.address) request["onions"].append(onion) request["hashes"].append(site.address_hash) # Tracker can remove sites that we don't announce if full_announce: request["delete"] = True # Sent request to tracker tracker = connection_pool.get(tracker_address) # Re-use tracker connection if possible if not tracker: tracker_ip, tracker_port = tracker_address.split(":") tracker = Peer(tracker_ip, tracker_port, connection_server=self.site.connection_server) connection_pool[tracker_address] = tracker res = tracker.request("announce", request) if not res or "peers" not in res: if full_announce: time_full_announced[tracker_address] = 0 raise AnnounceError("Invalid response: %s" % res) # Add peers from response to site site_index = 0 peers_added = 0 for site_res in res["peers"]: site = sites[site_index] peers_added += processPeerRes(tracker_address, site, site_res) site_index += 1 # Check if we need to sign prove the onion addresses if "onion_sign_this" in res: self.site.log.debug("Signing %s for %s to add %s onions" % (res["onion_sign_this"], tracker_address, len(sites))) request["onion_signs"] = {} request["onion_sign_this"] = res["onion_sign_this"] request["need_num"] = 0 for site in sites: onion = self.site.connection_server.tor_manager.getOnion(site.address) publickey = self.site.connection_server.tor_manager.getPublickey(onion) if publickey not in request["onion_signs"]: sign = CryptRsa.sign(res["onion_sign_this"], self.site.connection_server.tor_manager.getPrivatekey(onion)) request["onion_signs"][publickey] = sign res = tracker.request("announce", request) if not res or "onion_sign_this" in res: if full_announce: time_full_announced[tracker_address] = 0 raise AnnounceError("Announce onion address to failed: %s" % res) if full_announce: tracker.remove() # Close connection, we don't need it in next 5 minute self.site.log.debug( "Tracker announce result: zero://%s (sites: %s, new peers: %s) in %.3fs" % (tracker_address, site_index, peers_added, time.time() - s) ) return None