Forking what is left of ZeroNet and hopefully adding an AT Proto Frontend/Proxy
at main 246 lines 11 kB view raw
1import hashlib 2import os 3 4import pytest 5 6from Bootstrapper import BootstrapperPlugin 7from Bootstrapper.BootstrapperDb import BootstrapperDb 8from Peer import Peer 9from Crypt import CryptRsa 10from util import helper 11 12 13@pytest.fixture() 14def bootstrapper_db(request): 15 BootstrapperPlugin.db.close() 16 BootstrapperPlugin.db = BootstrapperDb() 17 BootstrapperPlugin.db.createTables() # Reset db 18 BootstrapperPlugin.db.cur.logging = True 19 20 def cleanup(): 21 BootstrapperPlugin.db.close() 22 os.unlink(BootstrapperPlugin.db.db_path) 23 24 request.addfinalizer(cleanup) 25 return BootstrapperPlugin.db 26 27 28@pytest.mark.usefixtures("resetSettings") 29class TestBootstrapper: 30 def testHashCache(self, file_server, bootstrapper_db): 31 ip_type = helper.getIpType(file_server.ip) 32 peer = Peer(file_server.ip, 1544, connection_server=file_server) 33 hash1 = hashlib.sha256(b"site1").digest() 34 hash2 = hashlib.sha256(b"site2").digest() 35 hash3 = hashlib.sha256(b"site3").digest() 36 37 # Verify empty result 38 res = peer.request("announce", { 39 "hashes": [hash1, hash2], 40 "port": 15441, "need_types": [ip_type], "need_num": 10, "add": [ip_type] 41 }) 42 43 assert len(res["peers"][0][ip_type]) == 0 # Empty result 44 45 hash_ids_before = bootstrapper_db.hash_ids.copy() 46 47 bootstrapper_db.updateHashCache() 48 49 assert hash_ids_before == bootstrapper_db.hash_ids 50 51 52 def testBootstrapperDb(self, file_server, bootstrapper_db): 53 ip_type = helper.getIpType(file_server.ip) 54 peer = Peer(file_server.ip, 1544, connection_server=file_server) 55 hash1 = hashlib.sha256(b"site1").digest() 56 hash2 = hashlib.sha256(b"site2").digest() 57 hash3 = hashlib.sha256(b"site3").digest() 58 59 # Verify empty result 60 res = peer.request("announce", { 61 "hashes": [hash1, hash2], 62 "port": 15441, "need_types": [ip_type], "need_num": 10, "add": [ip_type] 63 }) 64 65 assert len(res["peers"][0][ip_type]) == 0 # Empty result 66 67 # Verify added peer on previous request 68 bootstrapper_db.peerAnnounce(ip_type, file_server.ip_external, port=15441, hashes=[hash1, hash2], delete_missing_hashes=True) 69 70 res = peer.request("announce", { 71 "hashes": [hash1, hash2], 72 "port": 15441, "need_types": [ip_type], "need_num": 10, "add": [ip_type] 73 }) 74 assert len(res["peers"][0][ip_type]) == 1 75 assert len(res["peers"][1][ip_type]) == 1 76 77 # hash2 deleted from 1.2.3.4 78 bootstrapper_db.peerAnnounce(ip_type, file_server.ip_external, port=15441, hashes=[hash1], delete_missing_hashes=True) 79 res = peer.request("announce", { 80 "hashes": [hash1, hash2], 81 "port": 15441, "need_types": [ip_type], "need_num": 10, "add": [ip_type] 82 }) 83 assert len(res["peers"][0][ip_type]) == 1 84 assert len(res["peers"][1][ip_type]) == 0 85 86 # Announce 3 hash again 87 bootstrapper_db.peerAnnounce(ip_type, file_server.ip_external, port=15441, hashes=[hash1, hash2, hash3], delete_missing_hashes=True) 88 res = peer.request("announce", { 89 "hashes": [hash1, hash2, hash3], 90 "port": 15441, "need_types": [ip_type], "need_num": 10, "add": [ip_type] 91 }) 92 assert len(res["peers"][0][ip_type]) == 1 93 assert len(res["peers"][1][ip_type]) == 1 94 assert len(res["peers"][2][ip_type]) == 1 95 96 # Single hash announce 97 res = peer.request("announce", { 98 "hashes": [hash1], "port": 15441, "need_types": [ip_type], "need_num": 10, "add": [ip_type] 99 }) 100 assert len(res["peers"][0][ip_type]) == 1 101 102 # Test DB cleanup 103 assert [row[0] for row in bootstrapper_db.execute("SELECT address FROM peer").fetchall()] == [file_server.ip_external] # 127.0.0.1 never get added to db 104 105 # Delete peers 106 bootstrapper_db.execute("DELETE FROM peer WHERE address = ?", [file_server.ip_external]) 107 assert bootstrapper_db.execute("SELECT COUNT(*) AS num FROM peer_to_hash").fetchone()["num"] == 0 108 109 assert bootstrapper_db.execute("SELECT COUNT(*) AS num FROM hash").fetchone()["num"] == 3 # 3 sites 110 assert bootstrapper_db.execute("SELECT COUNT(*) AS num FROM peer").fetchone()["num"] == 0 # 0 peer 111 112 def testPassive(self, file_server, bootstrapper_db): 113 peer = Peer(file_server.ip, 1544, connection_server=file_server) 114 ip_type = helper.getIpType(file_server.ip) 115 hash1 = hashlib.sha256(b"hash1").digest() 116 117 bootstrapper_db.peerAnnounce(ip_type, address=None, port=15441, hashes=[hash1]) 118 res = peer.request("announce", { 119 "hashes": [hash1], "port": 15441, "need_types": [ip_type], "need_num": 10, "add": [] 120 }) 121 122 assert len(res["peers"][0]["ipv4"]) == 0 # Empty result 123 124 def testAddOnion(self, file_server, site, bootstrapper_db, tor_manager): 125 onion1 = tor_manager.addOnion() 126 onion2 = tor_manager.addOnion() 127 peer = Peer(file_server.ip, 1544, connection_server=file_server) 128 hash1 = hashlib.sha256(b"site1").digest() 129 hash2 = hashlib.sha256(b"site2").digest() 130 hash3 = hashlib.sha256(b"site3").digest() 131 132 bootstrapper_db.peerAnnounce(ip_type="ipv4", address="1.2.3.4", port=1234, hashes=[hash1, hash2, hash3]) 133 res = peer.request("announce", { 134 "onions": [onion1, onion1, onion2], 135 "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ipv4", "onion"], "need_num": 10, "add": ["onion"] 136 }) 137 assert len(res["peers"][0]["ipv4"]) == 1 138 139 # Onion address not added yet 140 site_peers = bootstrapper_db.peerList(address="1.2.3.4", port=1234, hash=hash1) 141 assert len(site_peers["onion"]) == 0 142 assert "onion_sign_this" in res 143 144 # Sign the nonces 145 sign1 = CryptRsa.sign(res["onion_sign_this"].encode(), tor_manager.getPrivatekey(onion1)) 146 sign2 = CryptRsa.sign(res["onion_sign_this"].encode(), tor_manager.getPrivatekey(onion2)) 147 148 # Bad sign (different address) 149 res = peer.request("announce", { 150 "onions": [onion1], "onion_sign_this": res["onion_sign_this"], 151 "onion_signs": {tor_manager.getPublickey(onion2): sign2}, 152 "hashes": [hash1], "port": 15441, "need_types": ["ipv4", "onion"], "need_num": 10, "add": ["onion"] 153 }) 154 assert "onion_sign_this" in res 155 site_peers1 = bootstrapper_db.peerList(address="1.2.3.4", port=1234, hash=hash1) 156 assert len(site_peers1["onion"]) == 0 # Not added 157 158 # Bad sign (missing one) 159 res = peer.request("announce", { 160 "onions": [onion1, onion1, onion2], "onion_sign_this": res["onion_sign_this"], 161 "onion_signs": {tor_manager.getPublickey(onion1): sign1}, 162 "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ipv4", "onion"], "need_num": 10, "add": ["onion"] 163 }) 164 assert "onion_sign_this" in res 165 site_peers1 = bootstrapper_db.peerList(address="1.2.3.4", port=1234, hash=hash1) 166 assert len(site_peers1["onion"]) == 0 # Not added 167 168 # Good sign 169 res = peer.request("announce", { 170 "onions": [onion1, onion1, onion2], "onion_sign_this": res["onion_sign_this"], 171 "onion_signs": {tor_manager.getPublickey(onion1): sign1, tor_manager.getPublickey(onion2): sign2}, 172 "hashes": [hash1, hash2, hash3], "port": 15441, "need_types": ["ipv4", "onion"], "need_num": 10, "add": ["onion"] 173 }) 174 assert "onion_sign_this" not in res 175 176 # Onion addresses added 177 site_peers1 = bootstrapper_db.peerList(address="1.2.3.4", port=1234, hash=hash1) 178 assert len(site_peers1["onion"]) == 1 179 site_peers2 = bootstrapper_db.peerList(address="1.2.3.4", port=1234, hash=hash2) 180 assert len(site_peers2["onion"]) == 1 181 site_peers3 = bootstrapper_db.peerList(address="1.2.3.4", port=1234, hash=hash3) 182 assert len(site_peers3["onion"]) == 1 183 184 assert site_peers1["onion"][0] == site_peers2["onion"][0] 185 assert site_peers2["onion"][0] != site_peers3["onion"][0] 186 assert helper.unpackOnionAddress(site_peers1["onion"][0])[0] == onion1 + ".onion" 187 assert helper.unpackOnionAddress(site_peers2["onion"][0])[0] == onion1 + ".onion" 188 assert helper.unpackOnionAddress(site_peers3["onion"][0])[0] == onion2 + ".onion" 189 190 tor_manager.delOnion(onion1) 191 tor_manager.delOnion(onion2) 192 193 def testRequestPeers(self, file_server, site, bootstrapper_db, tor_manager): 194 site.connection_server = file_server 195 file_server.tor_manager = tor_manager 196 hash = hashlib.sha256(site.address.encode()).digest() 197 198 # Request peers from tracker 199 assert len(site.peers) == 0 200 bootstrapper_db.peerAnnounce(ip_type="ipv4", address="1.2.3.4", port=1234, hashes=[hash]) 201 site.announcer.announceTracker("zero://%s:%s" % (file_server.ip, file_server.port)) 202 assert len(site.peers) == 1 203 204 # Test onion address store 205 bootstrapper_db.peerAnnounce(ip_type="onion", address="bka4ht2bzxchy44r", port=1234, hashes=[hash], onion_signed=True) 206 site.announcer.announceTracker("zero://%s:%s" % (file_server.ip, file_server.port)) 207 assert len(site.peers) == 2 208 assert "bka4ht2bzxchy44r.onion:1234" in site.peers 209 210 @pytest.mark.slow 211 def testAnnounce(self, file_server, tor_manager): 212 file_server.tor_manager = tor_manager 213 hash1 = hashlib.sha256(b"1Nekos4fiBqfcazyG1bAxdBT5oBvA76Z").digest() 214 hash2 = hashlib.sha256(b"1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr").digest() 215 peer = Peer("zero.booth.moe", 443, connection_server=file_server) 216 assert peer.request("ping") 217 peer = Peer("boot3rdez4rzn36x.onion", 15441, connection_server=file_server) 218 assert peer.request("ping") 219 res = peer.request("announce", { 220 "hashes": [hash1, hash2], 221 "port": 15441, "need_types": ["ip4", "onion"], "need_num": 100, "add": [""] 222 }) 223 224 assert res 225 226 def testBackwardCompatibility(self, file_server, bootstrapper_db): 227 peer = Peer(file_server.ip, 1544, connection_server=file_server) 228 hash1 = hashlib.sha256(b"site1").digest() 229 230 bootstrapper_db.peerAnnounce("ipv4", file_server.ip_external, port=15441, hashes=[hash1], delete_missing_hashes=True) 231 232 # Test with ipv4 need type 233 res = peer.request("announce", { 234 "hashes": [hash1], 235 "port": 15441, "need_types": ["ipv4"], "need_num": 10, "add": [] 236 }) 237 238 assert len(res["peers"][0]["ipv4"]) == 1 239 240 # Test with ip4 need type 241 res = peer.request("announce", { 242 "hashes": [hash1], 243 "port": 15441, "need_types": ["ip4"], "need_num": 10, "add": [] 244 }) 245 246 assert len(res["peers"][0]["ip4"]) == 1