def getMetainfo(src, openoptions='rb', style="file"): if src is None: return None metainfo = None try: metainfo_file = None # We're getting a url if style == "rawdata": return bdecode(src) # We're getting a file that exists elif os.access(src, os.R_OK): metainfo_file = open(src, openoptions) if metainfo_file is not None: metainfo = bdecode(metainfo_file.read()) metainfo_file.close() except: print_exc() if metainfo_file is not None: try: metainfo_file.close() except: pass metainfo = None return metainfo
def __init__(self,my_keypair,hostname,port,opensock=None,mylistenport=481,myoversion=None): """ If opensock is not None, we assume this is a connection we accepted, and he initiates the Challenge/Response """ self.my_keypair = my_keypair self.b = BTConnection(hostname,port,opensock,mylistenport=mylistenport,myoversion=myoversion) if opensock: self.b.read_handshake_medium_rare() # Read challenge msg = self.b.recv() assert(msg[0] == CHALLENGE) randomB = bdecode(msg[1:]) [randomA,resp1_data] = self.create_good_response1(randomB,self.b.get_his_id()) self.b.send(resp1_data) # Read response2 msg = self.b.recv() assert(msg[0] == RESPONSE2) else: self.b.read_handshake() [rB,chal_data] = self.create_good_challenge() self.b.send(chal_data) resp1_data = self.b.recv() if DEBUG: print >>sys.stderr,"olconn: recv",len(resp1_data),"bytes" resp1_dict = bdecode(resp1_data[1:]) resp2_data = self.create_good_response2(rB,resp1_dict,self.b.get_his_id()) self.b.send(resp2_data) if DEBUG: print >>sys.stderr,"olconn: sent",len(resp2_data),"bytes"
def subtest_channelcast(self): print >> sys.stderr, "test: channelcast----------------------" s = OLConnection(self.my_keypair, 'localhost', self.hisport) chcast = ChannelCastCore(None, s, self.session, None, log='', dnsindb=None) #Send Empty ChannelCast message chdata = {} print >> sys.stderr, "Test Good ChannelCast", ` chdata ` msg = CHANNELCAST + bencode(chdata) s.send(msg) resp = s.recv() if len(resp) > 0: print >> sys.stderr, "test: channelcast: got", getMessageName( resp[0]) self.assert_(resp[0] == CHANNELCAST) print >> sys.stderr, "test: channelcast: got msg", ` bdecode( resp[1:]) ` chdata_rcvd = bdecode(resp[1:]) self.assert_(validChannelCastMsg(chdata_rcvd) == True) s.close() #Now, send a bad ChannelCast message. # The other side should close the connection # Create bad message by manipulating a good one #bad infohash chdata = deepcopy(chdata_rcvd) for k, v in chdata.items(): v['infohash'] = 234 self.subtest_bad_channelcast(chdata) #bad torrentname chdata = deepcopy(chdata_rcvd) for k, v in chdata.items(): v['torrentname'] = 1231 self.subtest_bad_channelcast(chdata) #bad signature.. temporarily disabled. # Got to enable when signature validation in validChannelCastMsg are enabled # chdata = deepcopy(chdata_rcvd) # value_list = chdata.values() # if len(value_list)>0: # chdata['sdfg234sadf'] = value_list[0] # self.subtest_bad_channelcast(chdata) #Bad message format chdata = {'2343ww34': ''} self.subtest_bad_channelcast(chdata) #Bad print >> sys.stderr, "End of channelcast test---------------------------"
def subtest_channelcast(self): print >> sys.stderr, "test: channelcast----------------------" s = OLConnection(self.my_keypair, "localhost", self.hisport) chcast = ChannelCastCore(None, s, self.session, None, log="", dnsindb=None) # Send Empty ChannelCast message chdata = {} print >> sys.stderr, "Test Good ChannelCast", ` chdata ` msg = CHANNELCAST + bencode(chdata) s.send(msg) resp = s.recv() if len(resp) > 0: print >> sys.stderr, "test: channelcast: got", getMessageName(resp[0]) self.assert_(resp[0] == CHANNELCAST) print >> sys.stderr, "test: channelcast: got msg", ` bdecode(resp[1:]) ` chdata_rcvd = bdecode(resp[1:]) self.assert_(validChannelCastMsg(chdata_rcvd) == True) s.close() # Now, send a bad ChannelCast message. # The other side should close the connection # Create bad message by manipulating a good one # bad infohash chdata = deepcopy(chdata_rcvd) for k, v in chdata.items(): v["infohash"] = 234 self.subtest_bad_channelcast(chdata) # bad torrentname chdata = deepcopy(chdata_rcvd) for k, v in chdata.items(): v["torrentname"] = 1231 self.subtest_bad_channelcast(chdata) # bad signature.. temporarily disabled. # Got to enable when signature validation in validChannelCastMsg are enabled # chdata = deepcopy(chdata_rcvd) # value_list = chdata.values() # if len(value_list)>0: # chdata['sdfg234sadf'] = value_list[0] # self.subtest_bad_channelcast(chdata) # Bad message format chdata = {"2343ww34": ""} self.subtest_bad_channelcast(chdata) # Bad print >> sys.stderr, "End of channelcast test---------------------------"
def getStatus(announce, url, info_hash, info_hashes): returndict = {info_hash: (0, 0)} try: resp = timeouturlopen.urlOpenTimeout(url, timeout=HTTP_TIMEOUT) response = resp.read() response_dict = bdecode(response) for cur_infohash, status in response_dict["files"].iteritems(): seeder = max(0, status["complete"]) leecher = max(0, status["incomplete"]) returndict[cur_infohash] = (seeder, leecher) registerSuccess(announce) return returndict except IOError: registerIOError(announce) return {info_hash: (-1, -1)} except KeyError: try: if "flags" in response_dict: # may be interval problem if "min_request_interval" in response_dict["flags"]: return {info_hash: (-3, -3)} except: pass except: pass return None
def check_get_metadata(self, data): infohash = bdecode(data) self.check_infohash(infohash) # Extra check: he can only ask us for metadata for an infohash we # gave him. self.assert_(infohash in self.myprefs)
def test_createSingleResponseMessage(self): langUtil = LanguagesProvider.getLanguagesInstance() data = { 'permid' : testDestPermId, 'channel_id' : testChannelId, 'infohash' : testInfohash, 'subtitles' : {"eng" : "This is content 1", "nld": "This is content 2", "ita" : "This is content 3"}, 'selversion' : OLPROTO_VER_FOURTEENTH } langs = data['subtitles'].keys() bitmask = langUtil.langCodesToMask(langs) binaryBitmask = pack("!L", bitmask) expextedMessage = SUBS + \ bencode(( data['channel_id'], data['infohash'], binaryBitmask, [data['subtitles']['eng'], data['subtitles']['ita'], data['subtitles']['nld']] )) msg = self.underTest._createSingleResponseMessage(data) decoded = bdecode(msg[1:]) self.assertEquals(expextedMessage, msg)
def check_rquery_reply(self,querytype,data,goodtorrents): d = bdecode(data) print >>sys.stderr,"test: Got reply",`d` self.assert_(type(d) == DictType) self.assert_(d.has_key('a')) self.check_adict(d['a']) self.assert_(d.has_key('id')) id = d['id'] self.assert_(type(id) == StringType) k = d['a'].keys() self.assert_(len(k) == 2) var1 = k[0] == goodtorrents.keys()[0] and k[1] == goodtorrents.keys()[1] var2 = k[0] == goodtorrents.keys()[1] and k[1] == goodtorrents.keys()[0] self.assert_(var1 or var2) # OLPROTO_VER_NINETH must contain torrent_size for infohash, torrent in d['a'].iteritems(): self.assert_(torrent['torrent_size'], goodtorrents[infohash]) if querytype.startswith("SIMPLE+METADATA"): for infohash, torrent in d['a'].iteritems(): self.assert_('metadata' in torrent) bmetainfo = torrent['metadata'] self.assert_(bmetainfo == goodtorrents[infohash])
def subtest_valid_nat_check(self): """ Send a CRAWLER_NATCHECK message to the Tribler instance. A reply containing a nat type should be returned. """ print >>sys.stderr, "-"*80, "\ntest: subtest_valid_nat_check" # make sure that the OLConnection IS in the crawler_db crawler_db = CrawlerDBHandler.getInstance() crawler_db.temporarilyAddCrawler(self.my_permid) s = OLConnection(self.my_keypair, "localhost", self.hisport, mylistenport=self.listen_port) self.send_crawler_request(s, CRAWLER_NATCHECK, 42, 0, "") s.close() if DEBUG: print >>sys.stderr, "test_natcheck: the nat-check code allows for a 10 minute delay in reporting the nat stats" self.listen_socket.settimeout(11 * 60) # wait for reply try: conn, addr = self.listen_socket.accept() except socket.timeout: if DEBUG: print >> sys.stderr,"test_natcheck: timeout, bad, peer didn't connect to send the crawler reply" assert False, "test_natcheck: timeout, bad, peer didn't connect to send the crawler reply" s = OLConnection(self.my_keypair, "", 0, conn, mylistenport=self.listen_port) # read reply error, payload = self.receive_crawler_reply(s, CRAWLER_NATCHECK, 42) assert error == 0 if DEBUG: print >>sys.stderr, "test_natcheck:", bdecode(payload) time.sleep(1)
def readTorrent(self, torrent): try: torrent_path = torrent['torrent_path'] if not path.isfile(torrent_path): # torrent not found, try filename + current torrent collection directory _, torrent_filename = path.split(torrent_path) torrent_path = path.join(self.torrent_collection_dir, torrent_filename) if path.isfile(torrent_path): f = open(torrent_path, 'rb') _data = f.read() f.close() data = bdecode(_data) assert 'info' in data del data['info'] torrent['info'] = data except Exception: # print_exc() pass return torrent
def _test_response1(self, ss, gen_resp1, good): print >> sys.stderr, "test: myserver running:", gen_resp1 conn, addr = ss.accept() s = BTConnection('', 0, conn) s.read_handshake_medium_rare() # Read challenge msg = s.recv() self.testcase.assert_(msg[0] == CHALLENGE) randomB = bdecode(msg[1:]) self.testcase.assert_(type(randomB) == StringType) self.testcase.assert_(len(randomB) == random_size) [randomA, resp1_data] = gen_resp1(randomB, s.get_his_id()) s.send(resp1_data) if good: # Read response2 msg = s.recv() self.testcase.assert_(msg[0] == RESPONSE2) self.check_response2(msg[1:], randomA, randomB, s.get_my_id()) # the connection should be intact, so this should not throw an # exception: time.sleep(5) s.send('bla') s.close() else: time.sleep(5) # the other side should not our bad RESPONSE1 this and close the # connection msg = s.recv() self.testcase.assert_(len(msg) == 0) s.close()
def _test_response1(self,ss,gen_resp1,good): print >>sys.stderr,"test: myserver running:",gen_resp1 conn, addr = ss.accept() s = BTConnection('',0,conn) s.read_handshake_medium_rare() # Read challenge msg = s.recv() self.testcase.assert_(msg[0] == CHALLENGE) randomB = bdecode(msg[1:]) self.testcase.assert_(type(randomB) == StringType) self.testcase.assert_(len(randomB) == random_size) [randomA,resp1_data] = gen_resp1(randomB,s.get_his_id()) s.send(resp1_data) if good: # Read response2 msg = s.recv() self.testcase.assert_(msg[0] == RESPONSE2) self.check_response2(msg[1:],randomA,randomB,s.get_my_id()) # the connection should be intact, so this should not throw an # exception: time.sleep(5) s.send('bla') s.close() else: time.sleep(5) # the other side should not our bad RESPONSE1 this and close the # connection msg = s.recv() self.testcase.assert_(len(msg)==0) s.close()
def subtest_good_friendship_stats(self): """ Send a valid message-id from a registered crawler peer """ print >>sys.stderr, "-"*80, "\ntest: good friendship stats" s = OLConnection(self.my_keypair, "localhost", self.hisport) t = time.time() - 100.0 msg_dict = {'current time':int(t)} payload = bencode(msg_dict) self.send_crawler_request(s, CRAWLER_FRIENDSHIP_STATS, 0, 0, payload) error, payload = self.receive_crawler_reply(s, CRAWLER_FRIENDSHIP_STATS, 0) assert error == 0 d = bdecode(payload) if DEBUG: print >>sys.stderr, "test: Got FRIENDSHIPSTATISTICS",`d` stats = d['stats'] self.assert_(len(stats) == 1) record = d['stats'][0] self.assert_(record[0] == bin2str(self.his_permid)) # source_permid self.assert_(record[1] == bin2str(self.some_permid)) # target_permid self.assert_(record[2] == 0) # isForwarder time.sleep(1) s.close()
def setUpPostSession(self): """ override TestAsServer """ TestAsServer.setUpPostSession(self) self.mypermid = str(self.my_keypair.pub().get_der()) self.hispermid = str(self.his_keypair.pub().get_der()) # Calculating the infohash for proxyservice.test.torrent self.torrentfile = os.path.join('extend_hs_dir','proxyservice.test.torrent') # Read torrentfile to calculate the infohash torrentfile_content = open(self.torrentfile, "rb") # Decode all the file metainfo = bdecode(torrentfile_content.read()) # Re-encode only the info section self.infohash = hashlib.sha1(bencode(metainfo['info'])).digest() # Close the torrentfile torrentfile_content.close() # Add us as friend, so he will accept the ASK_FOR_HELP if False: # TEMP friendsdb = FriendDBHandler.getInstance() friendsdb.addFriend(self.mypermid) else: self.session.set_overlay_request_policy(AllowAllRequestPolicy()) self.session.set_download_states_callback(self.states_callback)
def check_friendship(self, data, mtype, fwd, resp, dobdecode=True, source=None, dest=None): if dobdecode: d = bdecode(data) else: d = data print >> sys.stderr, "test: Got FRIENDSHIP", ` d `, type(d) self.assert_(type(d) == DictType) self.assert_('msg type' in d) self.assert_(type(d['msg type']) == StringType) self.assert_(d['msg type'] == mtype) if mtype == RESP: self.assert_('response' in d) self.assert_(type(d['response']) == IntType) print >> sys.stderr, "test: COMPARE", ` d['response'] `, ` resp ` self.assert_(d['response'] == resp) elif mtype == FWD: self.assert_('source' in d) self.check_peer(d['source'], permid=source) self.assert_('dest' in d) self.check_peer(d['dest'], permid=dest) self.assert_('msg' in d) self.check_friendship(d['msg'], fwd, None, resp, dobdecode=False)
def subtest_good_friendship_req_fromhim(self, mtype, fwd=None, mresp=None): print >> sys.stderr, "test: good FRIENDSHIP req from him", mtype, fwd # He should try to forward the request to us, his friend try: self.destss.settimeout(330.0) conn, addr = self.destss.accept() s = OLConnection(self.dest_keypair, '', 0, conn, self.destport) while True: resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: good FRIENDSHIP fwd: Dest got reply", getMessageName( resp[0]) if resp[0] == FRIENDSHIP: break elif resp[0] == SOCIAL_OVERLAP: d = bdecode(resp[1:]) print >> sys.stderr, "test: SOCIAL OVERLAP", ` d ` pass else: self.assert_(False) except socket.timeout: print >> sys.stderr, "test: Timeout, bad, peer didn't connect to FWD dest" self.assert_(False) self.check_friendship(resp[1:], mtype, fwd, mresp, source=self.hispermid, dest=self.mypermid)
def get_thumbstreaminfo(self, infohash, hit): if DEBUG: print >> sys.stderr, "hitmap: get_thumbstreaminfo", infohash2urlpath( infohash) torrent_db = self.session.open_dbhandler(NTFY_TORRENTS) try: if hit['hittype'] == "localdb": dbhit = torrent_db.getTorrent(infohash, include_mypref=False) colltorrdir = self.session.get_torrent_collecting_dir() filepath = os.path.join(colltorrdir, dbhit['torrent_file_name']) tdef = TorrentDef.load(filepath) (thumbtype, thumbdata) = tdef.get_thumbnail() return self.create_thumbstreaminfo(thumbtype, thumbdata) else: if hit['metatype'] == URL_MIME_TYPE: # Shouldn't happen, not thumb in P2PURL return streaminfo404() else: if DEBUG: print >> sys.stderr, "hitmap: get_thumbstreaminfo: looking for thumb in remote hit" metainfo = bdecode(hit['metadata']) tdef = TorrentDef.load_from_dict(metainfo) (thumbtype, thumbdata) = tdef.get_thumbnail() return self.create_thumbstreaminfo(thumbtype, thumbdata) finally: self.session.close_dbhandler(torrent_db)
def StringToValue(self, value, type): # Assume that the value is already in the proper form # if it's not a string # (the case for some defaults) if value is not None: if not isinstance(value, unicode) and not isinstance(value, str): return value try: if type == "boolean": if value == "1": value = True else: value = False elif type == "int": value = int(value) elif type == "float": value = float(value) elif type == "color": red = int(value[0:3]) green = int(value[3:6]) blue = int(value[6:9]) value = wx.Colour(red, green, blue) elif type.startswith("bencode"): value = bdecode(value) except: value = None if value is None: value = self.defaultvalues[type] return value
def setUpPostSession(self): """ override TestAsServer """ TestAsServer.setUpPostSession(self) self.mypermid = str(self.my_keypair.pub().get_der()) self.hispermid = str(self.his_keypair.pub().get_der()) # Calculating the infohash for proxyservice.test.torrent self.torrentfile = os.path.join('extend_hs_dir', 'proxyservice.test.torrent') # Read torrentfile to calculate the infohash torrentfile_content = open(self.torrentfile, "rb") # Decode all the file metainfo = bdecode(torrentfile_content.read()) # Re-encode only the info section self.infohash = hashlib.sha1(bencode(metainfo['info'])).digest() # Close the torrentfile torrentfile_content.close() # Add us as friend, so he will accept the ASK_FOR_HELP if False: # TEMP friendsdb = FriendDBHandler.getInstance() friendsdb.addFriend(self.mypermid) else: self.session.set_overlay_request_policy(AllowAllRequestPolicy()) self.session.set_download_states_callback(self.states_callback)
def getStatus(announce, url, info_hash, info_hashes): returndict = {} try: resp = timeouturlopen.urlOpenTimeout(url, timeout=HTTP_TIMEOUT) response = resp.read() response_dict = bdecode(response) for cur_infohash, status in response_dict["files"].iteritems(): seeder = max(0, status["complete"]) leecher = max(0, status["incomplete"]) returndict[cur_infohash] = (seeder, leecher) registerSuccess(announce) return returndict except IOError: registerIOError(announce) return {info_hash: (-1, -1)} except KeyError: try: if response_dict.has_key("flags"): # may be interval problem if response_dict["flags"].has_key("min_request_interval"): return {info_hash: (-3, -3)} except: pass except: pass return None
def check_buddycast(self, data, oversion): d = bdecode(data) print >> sys.stderr, "test: Got BUDDYCAST", d.keys() #print >>sys.stderr,"test: Got CONTENT",`d` self.assert_(type(d) == DictType) self.assert_('ip' in d) self.assert_(type(d['ip']) == StringType) self.assert_('port' in d) self.assert_(type(d['port']) == IntType) self.assert_('name' in d) self.assert_(type(d['name']) == StringType) self.assert_('preferences' in d) self.check_preferences(d['preferences'], oversion) self.assert_('taste buddies' in d) self.check_taste_buddies(d['taste buddies'], oversion) self.assert_('random peers' in d) self.check_random_peers(d['random peers'], oversion) if oversion >= 3: self.assert_('connectable' in d) #print >>sys.stderr,"CONNECTABLE TYPE",type(d['connectable']) self.assert_(type(d['connectable']) == IntType) if oversion >= 4: self.assert_('collected torrents' in d) self.check_collected_torrents(d['collected torrents'], oversion) if oversion >= 6: self.assert_('npeers' in d) self.assert_(type(d['npeers']) == IntType) self.assert_('nfiles' in d) self.assert_(type(d['nfiles']) == IntType) self.assert_('ndls' in d) self.assert_(type(d['ndls']) == IntType)
def check_response1(self,resp1_data,rB,myid): resp1 = bdecode(resp1_data) self.assert_(type(resp1) == DictType) self.assert_(resp1.has_key('certA')) self.assert_(resp1.has_key('rA')) self.assert_(resp1.has_key('B')) self.assert_(resp1.has_key('SA')) # show throw exception when key no good pubA = EC.pub_key_from_der(resp1['certA']) rA = resp1['rA'] self.assert_(type(rA) == StringType) self.assert_(len(rA) == random_size) B = resp1['B'] self.assert_(type(B) == StringType) self.assert_(B,myid) SA = resp1['SA'] self.assert_(type(SA) == StringType) # verify signature sig_list = [rA,rB,myid] sig_data = bencode(sig_list) sig_hash = sha(sig_data).digest() self.assert_(pubA.verify_dsa_asn1(sig_hash,SA)) # Cannot resign the data with his keypair to double check. Signing # appears to yield different, supposedly valid sigs each time. return resp1
def get_thumbstreaminfo(self,infohash,hit): if DEBUG: print >>sys.stderr,"hitmap: get_thumbstreaminfo",infohash2urlpath(infohash) torrent_db = self.session.open_dbhandler(NTFY_TORRENTS) try: if hit['hittype'] == "localdb": dbhit = torrent_db.getTorrent(infohash,include_mypref=False) colltorrdir = self.session.get_torrent_collecting_dir() filepath = os.path.join(colltorrdir,dbhit['torrent_file_name']) tdef = TorrentDef.load(filepath) (thumbtype,thumbdata) = tdef.get_thumbnail() return self.create_thumbstreaminfo(thumbtype,thumbdata) else: if hit['metatype'] == URL_MIME_TYPE: # Shouldn't happen, not thumb in P2PURL return streaminfo404() else: if DEBUG: print >>sys.stderr,"hitmap: get_thumbstreaminfo: looking for thumb in remote hit" metainfo = bdecode(hit['metadata']) tdef = TorrentDef.load_from_dict(metainfo) (thumbtype,thumbdata) = tdef.get_thumbnail() return self.create_thumbstreaminfo(thumbtype,thumbdata) finally: self.session.close_dbhandler(torrent_db)
def subtest_good_friendship_req_fromhim(self,mtype,fwd=None,mresp=None): print >>sys.stderr,"test: good FRIENDSHIP req from him",mtype,fwd # He should try to forward the request to us, his friend try: self.destss.settimeout(330.0) conn, addr = self.destss.accept() s = OLConnection(self.dest_keypair,'',0,conn,self.destport) while True: resp = s.recv() self.assert_(len(resp) > 0) print >>sys.stderr,"test: good FRIENDSHIP fwd: Dest got reply",getMessageName(resp[0]) if resp[0] == FRIENDSHIP: break elif resp[0] == SOCIAL_OVERLAP: d = bdecode(resp[1:]) print >>sys.stderr,"test: SOCIAL OVERLAP",`d` pass else: self.assert_(False) except socket.timeout: print >> sys.stderr,"test: Timeout, bad, peer didn't connect to FWD dest" self.assert_(False) self.check_friendship(resp[1:],mtype,fwd,mresp,source=self.hispermid,dest=self.mypermid)
def check_friendship(self,data,mtype,fwd,resp,dobdecode=True,source=None,dest=None): if dobdecode: d = bdecode(data) else: d = data print >>sys.stderr,"test: Got FRIENDSHIP",`d`,type(d) self.assert_(type(d) == DictType) self.assert_('msg type' in d) self.assert_(type(d['msg type']) == StringType) self.assert_(d['msg type'] == mtype) if mtype == RESP: self.assert_('response' in d) self.assert_(type(d['response']) == IntType) print >>sys.stderr,"test: COMPARE",`d['response']`,`resp` self.assert_(d['response'] == resp) elif mtype == FWD: self.assert_('source' in d) self.check_peer(d['source'],permid=source) self.assert_('dest' in d) self.check_peer(d['dest'],permid=dest) self.assert_('msg' in d) self.check_friendship(d['msg'],fwd,None,resp,dobdecode=False)
def check_response1(self, resp1_data, rB, myid): resp1 = bdecode(resp1_data) self.assert_(type(resp1) == DictType) self.assert_(resp1.has_key('certA')) self.assert_(resp1.has_key('rA')) self.assert_(resp1.has_key('B')) self.assert_(resp1.has_key('SA')) # show throw exception when key no good pubA = EC.pub_key_from_der(resp1['certA']) rA = resp1['rA'] self.assert_(type(rA) == StringType) self.assert_(len(rA) == random_size) B = resp1['B'] self.assert_(type(B) == StringType) self.assert_(B, myid) SA = resp1['SA'] self.assert_(type(SA) == StringType) # verify signature sig_list = [rA, rB, myid] sig_data = bencode(sig_list) sig_hash = sha(sig_data).digest() self.assert_(pubA.verify_dsa_asn1(sig_hash, SA)) # Cannot resign the data with his keypair to double check. Signing # appears to yield different, supposedly valid sigs each time. return resp1
def check_get_metadata(self,data): infohash = bdecode(data) self.check_infohash(infohash) # Extra check: he can only ask us for metadata for an infohash we # gave him. self.assert_(infohash in self.myprefs)
def check_buddycast(self,data,oversion): d = bdecode(data) print >>sys.stderr,"test: Got BUDDYCAST",d.keys() #print >>sys.stderr,"test: Got CONTENT",`d` self.assert_(type(d) == DictType) self.assert_('ip' in d) self.assert_(type(d['ip']) == StringType) self.assert_('port' in d) self.assert_(type(d['port']) == IntType) self.assert_('name' in d) self.assert_(type(d['name']) == StringType) self.assert_('preferences' in d) self.check_preferences(d['preferences'],oversion) self.assert_('taste buddies' in d) self.check_taste_buddies(d['taste buddies'],oversion) self.assert_('random peers' in d) self.check_random_peers(d['random peers'],oversion ) if oversion >= 3: self.assert_('connectable' in d) #print >>sys.stderr,"CONNECTABLE TYPE",type(d['connectable']) self.assert_(type(d['connectable']) == IntType) if oversion >= 4: self.assert_('collected torrents' in d) self.check_collected_torrents(d['collected torrents'],oversion) if oversion >= 6: self.assert_('npeers' in d) self.assert_(type(d['npeers']) == IntType) self.assert_('nfiles' in d) self.assert_(type(d['nfiles']) == IntType) self.assert_('ndls' in d) self.assert_(type(d['ndls']) == IntType)
def subtest_channel_keyword_query(self, nickname): print >> sys.stderr, "test: chquery keyword-----------------------------" s = OLConnection(self.my_keypair, 'localhost', self.hisport) data = {} uq = u'CHANNEL k ' + nickname data['q'] = uq.encode("UTF-8") data['id'] = 'b' * 20 msg = QUERY + bencode(data) s.send(msg) resp = s.recv() #print >> sys.stderr, "printing resp", resp if len(resp) > 0: print >> sys.stderr, "test: chquery: got", getMessageName(resp[0]) self.assert_(resp[0] == QUERY_REPLY) self.check_chquery_reply(resp[1:], nickname) print >> sys.stderr, "test:", ` bdecode(resp[1:]) ` s.close()
def subtest_channel_keyword_query(self, nickname): print >> sys.stderr, "test: chquery keyword-----------------------------" s = OLConnection(self.my_keypair, "localhost", self.hisport) data = {} uq = u"CHANNEL k " + nickname data["q"] = uq.encode("UTF-8") data["id"] = "b" * 20 msg = QUERY + bencode(data) s.send(msg) resp = s.recv() # print >> sys.stderr, "printing resp", resp if len(resp) > 0: print >> sys.stderr, "test: chquery: got", getMessageName(resp[0]) self.assert_(resp[0] == QUERY_REPLY) self.check_chquery_reply(resp[1:], nickname) print >> sys.stderr, "test:", ` bdecode(resp[1:]) ` s.close()
def check_metadata(self,bdata,tdef): data = bdecode(bdata) # selversion >= OLPROTO_VER_ELEVENTH: for key in ['torrent_hash','metatype','metadata','last_check_time','status','leecher','seeder']: self.assert_(key in data) self.assertEqual(data['metatype'],URL_MIME_TYPE) self.assertEqual(data['torrent_hash'],tdef.get_infohash()) url = data['metadata'] cidx = url.find(':') self.assert_(cidx != -1) scheme = url[0:cidx] if url[cidx+1] == '/': # hierarchical URL qidx = url.find('?') self.assert_(qidx != -1) tracker = "http"+url[cidx:qidx] else: # Not yet supported by TorrentDef tracker = None qidx = cidx+1 query = url[qidx+1:] kvs = query.split('&') pt = {} for kv in kvs: if not '=' in kv: k = 'n' v = kv else: (k,v) = kv.split('=') if k == 'l': #length v = p2purl_decode_nnumber(v) elif k == 's': # piece size v = p2purl_decode_piecelength(v) elif k == 'r': # root hash v = p2purl_decode_base64url(v) elif k == 'k': # live key v = p2purl_decode_base64url(v) elif k == 'a': # live auth method pass elif k == 'b': # bitrate v = p2purl_decode_nnumber(v) pt[k] = v # Compare: self.assertEqual(P2PURL_SCHEME,scheme) self.assertEqual(tdef.get_tracker(),tracker) self.assertEqual(tdef.get_name(),pt['n']) self.assertEqual(tdef.get_length(),pt['l']) self.assertEqual(tdef.get_piece_length(),pt['s']) if 'r' in pt: self.assertEqual(tdef.get_infohash(),pt['r']) else: self.assertEqual(tdef.get_live_pubkey(),pt['k']) self.assertEqual(tdef.get_live_authmethod(),pt['a']) self.assertEqual(tdef.get_bitrate(),pt['b'])
def _refresh(self): channel_url = None try: self.key_url_lock.acquire() channel_url = deepcopy(self.key_url) finally: self.key_url_lock.release() if channel_url: for key, urls in channel_url.iteritems(): if key in self.key_callbacks: for url in urls: if DEBUG: print >> sys.stderr, "RssParser: getting rss", url, len(urls) historyfile = self.gethistfilename(url, key) urls_already_seen = URLHistory(historyfile) urls_already_seen.read() newItems = self.readUrl(url, urls_already_seen) for title, new_urls, description, thumbnail in newItems: for new_url in new_urls: urls_already_seen.add(new_url) urls_already_seen.write() try: if DEBUG: print >> sys.stderr, "RssParser: trying", new_url referer = urlparse(new_url) referer = referer.scheme + "://" + referer.netloc + "/" stream = urlOpenTimeout(new_url, referer=referer) bdata = stream.read() stream.close() bddata = bdecode(bdata, 1) torrent = TorrentDef._create(bddata) def processCallbacks(key): for callback in self.key_callbacks[key]: try: callback(key, torrent, extraInfo={'title': title, 'description': description, 'thumbnail': thumbnail}) except: print_exc() if self.remote_th.is_registered(): callback = lambda key = key: processCallbacks(key) self.remote_th.save_torrent(torrent, callback) else: processCallbacks(key) except: if DEBUG: print >> sys.stderr, "RssParser: could not download", new_url pass time.sleep(RSS_CHECK_FREQUENCY)
def check_bartercast(self, data): d = bdecode(data) print "Received data:" print d self.assert_(type(d) == DictType) self.assert_(d.has_key('data')) self.check_bartercast_data(d['data'])
def _read(stream): """ Internal class method that reads a torrent file from stream, checks it for correctness and sets self.input and self.metainfo accordingly. """ bdata = stream.read() stream.close() data = bdecode(bdata) #print >>sys.stderr,data return TorrentDef._create(data)
def check_challenge(cdata): try: randomB = bdecode(cdata) except: return None if len(randomB) != num_random_bits / 8: return None else: return randomB
def check_bartercast(self,data): d = bdecode(data) print "Received data:" print d self.assert_(type(d) == DictType) self.assert_(d.has_key('data')) self.check_bartercast_data(d['data'])
def check_challenge(cdata): try: randomB = bdecode(cdata) except: return None if len(randomB) != num_random_bits/8: return None else: return randomB
def __init__(self, my_keypair, hostname, port, opensock=None, mylistenport=481, myoversion=None): """ If opensock is not None, we assume this is a connection we accepted, and he initiates the Challenge/Response """ self.my_keypair = my_keypair self.b = BTConnection(hostname, port, opensock, mylistenport=mylistenport, myoversion=myoversion) if opensock: self.b.read_handshake_medium_rare() # Read challenge msg = self.b.recv() assert (msg[0] == CHALLENGE) randomB = bdecode(msg[1:]) [randomA, resp1_data] = self.create_good_response1(randomB, self.b.get_his_id()) self.b.send(resp1_data) # Read response2 msg = self.b.recv() assert (msg[0] == RESPONSE2) else: self.b.read_handshake() [rB, chal_data] = self.create_good_challenge() self.b.send(chal_data) resp1_data = self.b.recv() if DEBUG: print >> sys.stderr, "olconn: recv", len(resp1_data), "bytes" resp1_dict = bdecode(resp1_data[1:]) resp2_data = self.create_good_response2(rB, resp1_dict, self.b.get_his_id()) self.b.send(resp2_data) if DEBUG: print >> sys.stderr, "olconn: sent", len(resp2_data), "bytes"
def check_reserve_pieces(self, data): # torrent_hash + 1-byte all_or_nothing + bencode([piece num,...]) self.assert_(len(data) > 21) infohash = data[0:20] allflag = data[20] plist = bdecode(data[21:]) self.assert_(infohash == self.infohash) self.assert_(type(plist) == ListType) return plist
def check_reserve_pieces(self,data): # torrent_hash + 1-byte all_or_nothing + bencode([piece num,...]) self.assert_(len(data) > 21) infohash = data[0:20] allflag = data[20] plist = bdecode(data[21:]) self.assert_(infohash == self.infohash) self.assert_(type(plist) == ListType) return plist
def check_tribler_extend_hs(self, data): self.assert_(data[0] == chr(0)) d = bdecode(data[1:]) self.assert_(isinstance(d, DictType)) self.assert_('m' in d.keys()) m = d['m'] self.assert_(isinstance(m, DictType)) self.assert_('Tr_hashpiece' in m.keys()) val = m['Tr_hashpiece'] self.assert_(isinstance(val, IntType)) self.assert_(val == 250)
def check_tribler_extend_hs(self,data): self.assert_(data[0] == chr(0)) d = bdecode(data[1:]) self.assert_(type(d) == DictType) self.assert_('m' in d.keys()) m = d['m'] self.assert_(type(m) == DictType) self.assert_('Tr_OVERLAYSWARM' in m.keys()) val = m['Tr_OVERLAYSWARM'] self.assert_(type(val) == IntType) self.assert_(val == 253)
def check_tribler_extend_hs(self, data): self.assert_(data[0] == chr(0)) d = bdecode(data[1:]) self.assert_(isinstance(d, DictType)) self.assert_("m" in d.keys()) m = d["m"] self.assert_(isinstance(m, DictType)) self.assert_("Tr_hashpiece" in m.keys()) val = m["Tr_hashpiece"] self.assert_(isinstance(val, IntType)) self.assert_(val == 250)
def metadata_id_from_extend_handshake(self, data): assert data[0] == chr(0) d = bdecode(data[1:]) assert isinstance(d, dict) assert 'm' in d.keys() m = d['m'] assert isinstance(m, dict) assert "ut_metadata" in m.keys() val = m["ut_metadata"] assert isinstance(val, int) return val
def check_tribler_extend_hs(self, data): self.assert_(data[0] == chr(0)) d = bdecode(data[1:]) self.assert_(type(d) == DictType) self.assert_('m' in d.keys()) m = d['m'] self.assert_(type(m) == DictType) self.assert_('Tr_OVERLAYSWARM' in m.keys()) val = m['Tr_OVERLAYSWARM'] self.assert_(type(val) == IntType) self.assert_(val == 253)
def subtest_votecast(self): print >> sys.stderr, "test: votecast-----------------------------" s = OLConnection(self.my_keypair, 'localhost', self.hisport) vcast = VoteCastCore(None, s, self.session, None, log='', dnsindb=None) #Send Good VoteCast message vdata = {self.hispermid: {'vote': -1, 'time_stamp': 12345345}} print >> sys.stderr, "Test Good VoteCast", ` vdata ` msg = VOTECAST + bencode(vdata) s.send(msg) resp = s.recv() #print >> sys.stderr, "printing resp", resp if len(resp) > 0: print >> sys.stderr, "test: votecast: got", getMessageName(resp[0]) self.assert_(resp[0] == VOTECAST) print >> sys.stderr, "test: votecast: got msg", ` bdecode(resp[1:]) ` vdata_rcvd = bdecode(resp[1:]) self.assert_(validVoteCastMsg(vdata_rcvd) == True) s.close() #Now, send a bad ChannelCast messages # The other side should close the connection #Bad time_stamp: it can only int vdata = {bin2str(self.hispermid): {'vote': -1, 'time_stamp': 'halo'}} self.subtest_bad_votecast(vdata) #Bad Vote: Vote can only -1 or 2 vdata = { bin2str(self.hispermid): { 'vote': -15, 'time_stamp': 12345345 } } self.subtest_bad_votecast(vdata) # Bad Message format ... Correct format is 'time_stamp' vdata = {bin2str(self.hispermid): {'vote': -15, 'timestamp': 12345345}} self.subtest_bad_votecast(vdata) print >> sys.stderr, "End of votecast test"
def check_g2g_v2(self,data,g2g_id): self.assert_(data[0] == chr(g2g_id)) d = bdecode(data[1:]) print >>sys.stderr,"test: l is",`d` self.assert_(type(d) == DictType) for k,v in d.iteritems(): self.assert_(type(k) == StringType) self.assert_(type(v) == StringType) self.assert_(ord(k) > 0) self.assert_(ord(v) <= 100)
def check_chquery_reply(self, data, nickname): d = bdecode(data) self.assert_(type(d) == DictType) self.assert_(d.has_key('a')) self.assert_(d.has_key('id')) id = d['id'] self.assert_(type(id) == StringType) self.assert_(validChannelCastMsg(d['a']) == True) self.assert_(len(d['a']) > 0) for key, val in d['a'].iteritems(): self.assert_(val['publisher_name'] == nickname.encode("UTF-8")) self.assert_(val['publisher_id'] == self.hispermid)
def check_rquery(self,data): d = bdecode(data) self.assert_(type(d) == DictType) self.assert_(d.has_key('q')) q = d['q'] self.assert_(type(q) == StringType) self.assert_(d.has_key('id')) id = d['id'] self.assert_(type(id) == StringType) self.assert_(q == self.query.encode("UTF-8")) return d['id']
def check_g2g_v2(self, data, g2g_id): self.assert_(data[0] == chr(g2g_id)) d = bdecode(data[1:]) print >> sys.stderr, "test: l is", ` d ` self.assert_(type(d) == DictType) for k, v in d.iteritems(): self.assert_(type(k) == StringType) self.assert_(type(v) == StringType) self.assert_(ord(k) > 0) self.assert_(ord(v) <= 100)
def add_metadata_piece(self, piece, data): """ A metadata piece was received """ if not self._closed: for index, block_tuple in zip(xrange(len(self._metadata_blocks)), self._metadata_blocks): if block_tuple[1] == piece: block_tuple[0] = max(0, block_tuple[0] - 1) block_tuple[2] = data self._metadata_blocks.sort() break # def p(s): # if s is None: return 0 # return len(s) # if DEBUG: print >> sys.stderr, "Progress:", [p(t[2]) for t in self._metadata_blocks] progress = sum([1 if t[2] else 0 for t in self._metadata_blocks])/float(len(self._metadata_blocks)) self._notifier.notify(NTFY_TORRENTS, NTFY_MAGNET_PROGRESS, self._info_hash, progress) # see if we are done for requested, piece, data in self._metadata_blocks: if data is None: break else: # _metadata_blocks is sorted by requested count. we need to sort it by piece-id metadata_blocks = [(piece, data) for _, piece, data in self._metadata_blocks] metadata_blocks.sort() metadata = "".join([data for _, data in metadata_blocks]) info_hash = sha(metadata).digest() if info_hash == self._info_hash: if DEBUG: print >> sys.stderr, "MiniBitTorrent.add_metadata_piece() Done!" # get nice list with recent BitTorrent peers, sorted # by most recently connected peers = [(timestamp, address) for address, timestamp in self._good_peers.iteritems()] peers.sort(reverse=True) peers = [address for _, address in peers] self._callback(bdecode(metadata), peers) else: # for piece, data in metadata_blocks: # open("failed-hash-{0}.data".format(piece), "w+").write(data) # todo: hash failed... now what? # quick solution... remove everything and try again if DEBUG: print >> sys.stderr, "MiniBitTorrent.add_metadata_piece() Failed hashcheck! Restarting all over again :(" self._metadata_blocks = [[requested, piece, None] for requested, piece, data in self._metadata_blocks]
def subtest_receptionOfSUBSTwoRequestsOneAvailable(self): """ Asking for two subtitles while the recipent of the request has only one. The response should contain only the one available subtitle content, plus a bitmask that reflects the contents of the response. """ print >> sys.stderr, "test: test_subtitles_msgs_2_1 -----------------------" ol_conn = OLConnection(self.my_keypair, 'localhost', self.hisport) bitmask = LanguagesProvider.getLanguagesInstance().langCodesToMask( ['nld', 'eng']) binmask = utilities.uintToBinaryString(bitmask, length=4) request = GET_SUBS + \ bencode(( self.anotherpermid, self.testInfohash, binmask )) subshandler = SubtitlesHandler() subshandler.register(ol_conn, self.richMetadata_db, self.session) ol_conn.send(request) subs_data = ol_conn.recv() self.assertEquals(SUBS, subs_data[0]) data = bdecode(subs_data[1:]) print >> sys.stderr, "test: subtitles_messages : received SUBS repsonse: ", data #check on the format of the response self.assertTrue(isinstance(data, list)) self.assertEquals(4, len(data)) # for fields self.assertEquals(self.mdto.channel, data[0]) self.assertEquals(self.mdto.infohash, data[1]) #the receiver had only one of the two requested subtitles # so I expect a different bitmask bitmask = LanguagesProvider.getLanguagesInstance().langCodesToMask( ['nld']) expectedBinarymask = utilities.uintToBinaryString(bitmask, length=4) self.assertEquals(expectedBinarymask, data[2]) self.assertTrue(isinstance(data[3], list)) self.assertEquals(1, len(data[3])) with codecs.open(self.sub1, "rb", "utf-8") as sub: expectedContents = sub.read() self.assertEquals(expectedContents, data[3][0]) ol_conn.close() print >> sys.stderr, "test: subtitles_messages: received content is valid." print >> sys.stderr, "End of test_subtitles_msgs_2_1 test --------------------"