import time
from Plugin import PluginManager
from BootstrapperDb import BootstrapperDb
from Crypt import CryptRsa
if "db" not in locals().keys(): # Share durin reloads
db = BootstrapperDb()
@PluginManager.registerTo("FileRequest")
class FileRequestPlugin(object):
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)
@PluginManager.registerTo("UiRequest")
class UiRequestPlugin(object):
def actionStatsBootstrapper(self):
self.sendHeader()
# Style
yield """
"""
hash_rows = db.execute("SELECT * FROM hash").fetchall()
for hash_row in hash_rows:
peer_rows = db.execute(
"SELECT * FROM peer LEFT JOIN peer_to_hash USING (peer_id) WHERE hash_id = :hash_id",
{"hash_id": hash_row["hash_id"]}
).fetchall()
yield "
%s (added: %s, peers: %s)
" % (
str(hash_row["hash"]).encode("hex"), hash_row["date_added"], len(peer_rows)
)
for peer_row in peer_rows:
yield " - {ip4: <30} {onion: <30} added: {date_added}, announced: {date_announced}
".format(**dict(peer_row))