TestBootstrapper.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import hashlib
  2. import os
  3. import pytest
  4. from Bootstrapper import BootstrapperPlugin
  5. from Bootstrapper.BootstrapperDb import BootstrapperDb
  6. from Peer import Peer
  7. from Crypt import CryptRsa
  8. from util import helper
  9. @pytest.fixture()
  10. def bootstrapper_db(request):
  11. BootstrapperPlugin.db.close()
  12. BootstrapperPlugin.db = BootstrapperDb()
  13. BootstrapperPlugin.db.createTables() # Reset db
  14. BootstrapperPlugin.db.cur.logging = True
  15. def cleanup():
  16. BootstrapperPlugin.db.close()
  17. os.unlink(BootstrapperPlugin.db.db_path)
  18. request.addfinalizer(cleanup)
  19. return BootstrapperPlugin.db
  20. @pytest.mark.usefixtures("resetSettings")
  21. class TestBootstrapper:
  22. def testIp4(self, file_server, bootstrapper_db):
  23. peer = Peer("127.0.0.1", 1544, connection_server=file_server)
  24. hash1 = hashlib.sha256("site1").digest()
  25. hash2 = hashlib.sha256("site2").digest()
  26. hash3 = hashlib.sha256("site3").digest()
  27. # Verify empty result
  28. res = peer.request("announce", {
  29. "hashes": [hash1, hash2],
  30. "port": 15441, "need_types": ["ip4"], "need_num": 10, "add": ["ip4"]
  31. })
  32. assert len(res["peers"][0]["ip4"]) == 0 # Empty result
  33. # Verify added peer on previous request
  34. bootstrapper_db.peerAnnounce(ip4="1.2.3.4", port=15441, hashes=[hash1, hash2], delete_missing_hashes=True)
  35. res = peer.request("announce", {
  36. "hashes": [hash1, hash2],
  37. "port": 15441, "need_types": ["ip4"], "need_num": 10, "add": ["ip4"]
  38. })
  39. assert len(res["peers"][0]["ip4"]) == 1
  40. assert len(res["peers"][1]["ip4"]) == 1
  41. # hash2 deleted from 1.2.3.4
  42. bootstrapper_db.peerAnnounce(ip4="1.2.3.4", port=15441, hashes=[hash1], delete_missing_hashes=True)
  43. res = peer.request("announce", {
  44. "hashes": [hash1, hash2],
  45. "port": 15441, "need_types": ["ip4"], "need_num": 10, "add": ["ip4"]
  46. })
  47. assert len(res["peers"][0]["ip4"]) == 1
  48. assert len(res["peers"][1]["ip4"]) == 0
  49. # Announce 3 hash again
  50. bootstrapper_db.peerAnnounce(ip4="1.2.3.4", port=15441, hashes=[hash1, hash2, hash3], delete_missing_hashes=True)
  51. res = peer.request("announce", {
  52. "hashes": [hash1, hash2, hash3],
  53. "port": 15441, "need_types": ["ip4"], "need_num": 10, "add": ["ip4"]
  54. })
  55. assert len(res["peers"][0]["ip4"]) == 1
  56. assert len(res["peers"][1]["ip4"]) == 1
  57. assert len(res["peers"][2]["ip4"]) == 1
  58. # Single hash announce
  59. res = peer.request("announce", {
  60. "hashes": [hash1], "port": 15441, "need_types": ["ip4"], "need_num": 10, "add": ["ip4"]
  61. })
  62. assert len(res["peers"][0]["ip4"]) == 1
  63. # Test DB cleanup
  64. assert bootstrapper_db.execute("SELECT COUNT(*) AS num FROM peer").fetchone()["num"] == 1 # 127.0.0.1 never get added to db
  65. # Delete peers
  66. bootstrapper_db.execute("DELETE FROM peer WHERE ip4 = '1.2.3.4'")
  67. assert bootstrapper_db.execute("SELECT COUNT(*) AS num FROM peer_to_hash").fetchone()["num"] == 0
  68. assert bootstrapper_db.execute("SELECT COUNT(*) AS num FROM hash").fetchone()["num"] == 3 # 3 sites
  69. assert bootstrapper_db.execute("SELECT COUNT(*) AS num FROM peer").fetchone()["num"] == 0 # 0 peer
  70. def testPassive(self, file_server, bootstrapper_db):
  71. peer = Peer("127.0.0.1", 1544, connection_server=file_server)
  72. hash1 = hashlib.sha256("hash1").digest()
  73. bootstrapper_db.peerAnnounce(ip4=None, port=15441, hashes=[hash1])
  74. res = peer.request("announce", {
  75. "hashes": [hash1], "port": 15441, "need_types": ["ip4"], "need_num": 10, "add": []
  76. })
  77. assert len(res["peers"][0]["ip4"]) == 0 # Empty result
  78. def testAddOnion(self, file_server, site, bootstrapper_db, tor_manager):
  79. onion1 = tor_manager.addOnion()
  80. onion2 = tor_manager.addOnion()
  81. peer = Peer("127.0.0.1", 1544, connection_server=file_server)
  82. hash1 = hashlib.sha256("site1").digest()
  83. hash2 = hashlib.sha256("site2").digest()
  84. hash3 = hashlib.sha256("site3").digest()
  85. bootstrapper_db.peerAnnounce(ip4="1.2.3.4", port=1234, hashes=[hash1, hash2, hash3])
  86. res = peer.request("announce", {
  87. "onions": [onion1, onion1, onion2],
  88. "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"]
  89. })
  90. assert len(res["peers"][0]["ip4"]) == 1
  91. # Onion address not added yet
  92. site_peers = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1)
  93. assert len(site_peers["onion"]) == 0
  94. assert "onion_sign_this" in res
  95. # Sign the nonces
  96. sign1 = CryptRsa.sign(res["onion_sign_this"], tor_manager.getPrivatekey(onion1))
  97. sign2 = CryptRsa.sign(res["onion_sign_this"], tor_manager.getPrivatekey(onion2))
  98. # Bad sign (different address)
  99. res = peer.request("announce", {
  100. "onions": [onion1], "onion_sign_this": res["onion_sign_this"],
  101. "onion_signs": {tor_manager.getPublickey(onion2): sign2},
  102. "hashes": [hash1], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"]
  103. })
  104. assert "onion_sign_this" in res
  105. site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1)
  106. assert len(site_peers1["onion"]) == 0 # Not added
  107. # Bad sign (missing one)
  108. res = peer.request("announce", {
  109. "onions": [onion1, onion1, onion2], "onion_sign_this": res["onion_sign_this"],
  110. "onion_signs": {tor_manager.getPublickey(onion1): sign1},
  111. "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"]
  112. })
  113. assert "onion_sign_this" in res
  114. site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1)
  115. assert len(site_peers1["onion"]) == 0 # Not added
  116. # Good sign
  117. res = peer.request("announce", {
  118. "onions": [onion1, onion1, onion2], "onion_sign_this": res["onion_sign_this"],
  119. "onion_signs": {tor_manager.getPublickey(onion1): sign1, tor_manager.getPublickey(onion2): sign2},
  120. "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ip4", "onion"], "need_num": 10, "add": ["onion"]
  121. })
  122. assert "onion_sign_this" not in res
  123. # Onion addresses added
  124. site_peers1 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash1)
  125. assert len(site_peers1["onion"]) == 1
  126. site_peers2 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash2)
  127. assert len(site_peers2["onion"]) == 1
  128. site_peers3 = bootstrapper_db.peerList(ip4="1.2.3.4", port=1234, hash=hash3)
  129. assert len(site_peers3["onion"]) == 1
  130. assert site_peers1["onion"][0] == site_peers2["onion"][0]
  131. assert site_peers2["onion"][0] != site_peers3["onion"][0]
  132. assert helper.unpackOnionAddress(site_peers1["onion"][0])[0] == onion1+".onion"
  133. assert helper.unpackOnionAddress(site_peers2["onion"][0])[0] == onion1+".onion"
  134. assert helper.unpackOnionAddress(site_peers3["onion"][0])[0] == onion2+".onion"
  135. tor_manager.delOnion(onion1)
  136. tor_manager.delOnion(onion2)
  137. def testRequestPeers(self, file_server, site, bootstrapper_db, tor_manager):
  138. site.connection_server = file_server
  139. site.connection_server.tor_manager = tor_manager
  140. hash = hashlib.sha256(site.address).digest()
  141. # Request peers from tracker
  142. assert len(site.peers) == 0
  143. bootstrapper_db.peerAnnounce(ip4="1.2.3.4", port=1234, hashes=[hash])
  144. site.announceTracker("zero", "127.0.0.1:1544")
  145. assert len(site.peers) == 1
  146. # Test onion address store
  147. bootstrapper_db.peerAnnounce(onion="bka4ht2bzxchy44r", port=1234, hashes=[hash], onion_signed=True)
  148. site.announceTracker("zero", "127.0.0.1:1544")
  149. assert len(site.peers) == 2
  150. assert "bka4ht2bzxchy44r.onion:1234" in site.peers