def recv_query_reply(self, permid, message, selversion): if selversion < OLPROTO_VER_SIXTH: return False try: d = bdecode(message[1:]) except: if DEBUG: print >> sys.stderr, 'rquery: Cannot bdecode QUERY_REPLY message', selversion return False if not isValidQueryReply(d, selversion): if DEBUG: print >> sys.stderr, 'rquery: not valid QUERY_REPLY message', selversion return False queryrec = self.is_registered_query_id(d['id']) if not queryrec: if DEBUG: print >> sys.stderr, 'rquery: QUERY_REPLY has unknown query ID', selversion return False if selversion >= OLPROTO_VER_TWELFTH: if queryrec['query'].startswith('SIMPLE+METADATA'): for infohash, torrentrec in d['a'].iteritems(): if 'metatype' not in torrentrec: if DEBUG: print >> sys.stderr, 'rquery: QUERY_REPLY has no metatype field', selversion return False if 'metadata' not in torrentrec: if DEBUG: print >> sys.stderr, 'rquery: QUERY_REPLY has no metadata field', selversion return False if torrentrec['torrent_size'] != len( torrentrec['metadata']): if DEBUG: print >> sys.stderr, 'rquery: QUERY_REPLY torrent_size != len metadata', selversion return False try: if torrentrec['metatype'] == URL_MIME_TYPE: tdef = TorrentDef.load_from_url( torrentrec['metadata']) else: metainfo = bdecode(torrentrec['metadata']) tdef = TorrentDef.load_from_dict(metainfo) except: if DEBUG: print_exc() return False self.process_query_reply(permid, queryrec['query'], queryrec['usercallback'], d) return True
def got_ask_for_help(self, permid, message, selversion): try: infohash = message[1:21] challenge = bdecode(message[21:]) except: if DEBUG: print >> sys.stderr, 'helper: got_ask_for_help: bad data in ask_for_help' return False if len(infohash) != 20: if DEBUG: print >> sys.stderr, 'helper: got_ask_for_help: bad infohash in ask_for_help' return False if DEBUG: print >> sys.stderr, 'helper: got_ask_for_help: received a help request from', show_permid_short(permid), 'with challenge', challenge self.received_challenges[permid] = challenge helper_obj = self.session.lm.get_coopdl_role_object(infohash, COOPDL_ROLE_HELPER) if helper_obj is None: if DEBUG: print >> sys.stderr, 'helper: got_ask_for_help: There is no current download for this infohash. A new download must be started.' self.start_helper_download(permid, infohash, selversion) return network_got_ask_for_help_lambda = lambda : self.network_got_ask_for_help(permid, infohash) self.session.lm.rawserver.add_task(network_got_ask_for_help_lambda, 0) return True
def getStatus(url, info_hash): try: resp = timeouturlopen.urlOpenTimeout(url, timeout=HTTP_TIMEOUT) response = resp.read() except IOError: return (-1, -1) except AttributeError: return (-2, -2) try: response_dict = bdecode(response) except: return (-2, -2) try: status = response_dict['files'][info_hash] seeder = status['complete'] if seeder < 0: seeder = 0 leecher = status['incomplete'] if leecher < 0: leecher = 0 except KeyError: try: if response_dict.has_key('flags'): if response_dict['flags'].has_key('min_request_interval'): return (-3, -3) except: pass return (-2, -2) return (seeder, leecher)
def got_ask_for_help(self, permid, message, selversion): try: infohash = message[1:21] challenge = bdecode(message[21:]) except: if DEBUG: print >> sys.stderr, 'helper: got_ask_for_help: bad data in ask_for_help' return False if len(infohash) != 20: if DEBUG: print >> sys.stderr, 'helper: got_ask_for_help: bad infohash in ask_for_help' return False if DEBUG: print >> sys.stderr, 'helper: got_ask_for_help: received a help request from', show_permid_short( permid), 'with challenge', challenge self.received_challenges[permid] = challenge helper_obj = self.session.lm.get_coopdl_role_object( infohash, COOPDL_ROLE_HELPER) if helper_obj is None: if DEBUG: print >> sys.stderr, 'helper: got_ask_for_help: There is no current download for this infohash. A new download must be started.' self.start_helper_download(permid, infohash, selversion) return network_got_ask_for_help_lambda = lambda: self.network_got_ask_for_help( permid, infohash) self.session.lm.rawserver.add_task(network_got_ask_for_help_lambda, 0) return True
def gotUdpConnectRequest(self, permid, selversion, channel_id, mh_msg, reply_callback): if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: gotUdpConnectRequest from', show_permid_short(permid) try: mh_data = bdecode(mh_msg) except: print_exc() print >> sys.stderr, 'NatCheckMsgHandler: bad encoded data:', mh_msg return False if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: gotUdpConnectRequest is', mh_data try: request_id, host, port = mh_data.split(':') except: print_exc() print >> sys.stderr, 'NatCheckMsgHandler: error in received data:', mh_data return False coordinator = (host, int(port)) if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: coordinator address is', coordinator mhr_data = request_id + ':' + tryConnect(coordinator) try: mhr_msg = bencode(mhr_data) except: print_exc() print >> sys.stderr, 'NatCheckMsgHandler: error in encoding data:', mhr_data return False reply_callback(mhr_msg, callback=self.udpConnectReplySendCallback)
def _decodeGETSUBSMessage(self, message): try: values = bdecode(message[1:]) except: if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + 'Error bdecoding message' return None if len(values) != 3: if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + 'Invalid number of fields in GET_SUBS' return None channel_id, infohash, bitmask = values[0], values[1], values[2] if not validPermid(channel_id): if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + 'Invalid channel_id in GET_SUBS' return None if not validInfohash(infohash): if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + 'Invalid infohash in GET_SUBS' return None if not isinstance(bitmask, str) or not len(bitmask) == 4: if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + 'Invalid bitmask in GET_SUBS' return None try: bitmask, = unpack('!L', bitmask) languages = self._languagesUtility.maskToLangCodes(bitmask) except: if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + 'Invalid bitmask in GET_SUBS' return None return (channel_id, infohash, languages)
def add_metadata_piece(self, piece, data): 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 for requested, piece, data in self._metadata_blocks: if data is None: break else: 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!' 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: 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 _read(stream): bdata = stream.read() stream.close() protected = False # Path anonym 04.11.2013 if bdata[:8] == chr(1) + chr(2) + chr(3) + chr(4) + chr(17) + chr(2) + chr(101) + chr(46): bdata = bdata[8:] bdata = m2_AES_decrypt(bdata, '%E0(tK8r]8KKU=crz!Vuex0b#I)H+!0n}%f0]L_x0ch++?-<#YHwXkvM6UL') protected = True elif bdata[:4] == chr(1) + chr(2) + chr(3) + chr(4): bdata = bdata[4:] # end Path anonym 04.11.2013 bdata = m2_AES_decrypt(bdata, 'tslive_key') protected = True elif bdata[:4] == chr(17) + chr(2) + chr(101) + chr(46): bdata = bdata[4:] bdata = m2_AES_decrypt(bdata, '=Atl6GD#Vb+#QwW9zJy34lBOcM-7R7G)') protected = True data = bdecode(bdata, params={'use_ordered_dict': True}) if not data.has_key('info') and data.has_key('qualities'): return MultiTorrent._create(data, protected) else: return TorrentDef._create(data, protected)
def run(self): announce = self._tracker + '?' + urlencode({'info_hash': self._swarm.get_info_hash(), 'peer_id': self._swarm.get_peer_id(), 'port': '12345', 'compact': '1', 'uploaded': '0', 'downloaded': '0', 'left': '-1', 'event': 'started'}) handle = urlopen(announce) if handle: body = handle.read() if body: try: body = bdecode(body) except: pass else: peers = [] peer_data = body['peers'] for x in range(0, len(peer_data), 6): key = peer_data[x:x + 6] ip = '.'.join([ str(ord(i)) for i in peer_data[x:x + 4] ]) port = ord(peer_data[x + 4]) << 8 | ord(peer_data[x + 5]) peers.append((ip, port)) if DEBUG: print >> sys.stderr, 'MiniTracker.run() received', len(peers), 'peer addresses from tracker' self._swarm.add_potential_peers(peers)
def gotUdpConnectRequest(self, permid, selversion, channel_id, mh_msg, reply_callback): if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: gotUdpConnectRequest from', show_permid_short( permid) try: mh_data = bdecode(mh_msg) except: print_exc() print >> sys.stderr, 'NatCheckMsgHandler: bad encoded data:', mh_msg return False if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: gotUdpConnectRequest is', mh_data try: request_id, host, port = mh_data.split(':') except: print_exc() print >> sys.stderr, 'NatCheckMsgHandler: error in received data:', mh_data return False coordinator = (host, int(port)) if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: coordinator address is', coordinator mhr_data = request_id + ':' + tryConnect(coordinator) try: mhr_msg = bencode(mhr_data) except: print_exc() print >> sys.stderr, 'NatCheckMsgHandler: error in encoding data:', mhr_data return False reply_callback(mhr_msg, callback=self.udpConnectReplySendCallback)
def recv_query_reply(self, permid, message, selversion): if selversion < OLPROTO_VER_SIXTH: return False try: d = bdecode(message[1:]) except: if DEBUG: print >> sys.stderr, 'rquery: Cannot bdecode QUERY_REPLY message', selversion return False if not isValidQueryReply(d, selversion): if DEBUG: print >> sys.stderr, 'rquery: not valid QUERY_REPLY message', selversion return False queryrec = self.is_registered_query_id(d['id']) if not queryrec: if DEBUG: print >> sys.stderr, 'rquery: QUERY_REPLY has unknown query ID', selversion return False if selversion >= OLPROTO_VER_TWELFTH: if queryrec['query'].startswith('SIMPLE+METADATA'): for infohash, torrentrec in d['a'].iteritems(): if 'metatype' not in torrentrec: if DEBUG: print >> sys.stderr, 'rquery: QUERY_REPLY has no metatype field', selversion return False if 'metadata' not in torrentrec: if DEBUG: print >> sys.stderr, 'rquery: QUERY_REPLY has no metadata field', selversion return False if torrentrec['torrent_size'] != len(torrentrec['metadata']): if DEBUG: print >> sys.stderr, 'rquery: QUERY_REPLY torrent_size != len metadata', selversion return False try: if torrentrec['metatype'] == URL_MIME_TYPE: tdef = TorrentDef.load_from_url(torrentrec['metadata']) else: metainfo = bdecode(torrentrec['metadata']) tdef = TorrentDef.load_from_dict(metainfo) except: if DEBUG: print_exc() return False self.process_query_reply(permid, queryrec['query'], queryrec['usercallback'], d) return True
def deserialize(encoded): if not encoded: raise InvalidPOAException('Cannot deserialize nothing') try: lst = bdecode(encoded) if len(lst) < 5: raise InvalidPOAException('Too few entries (got %d, expected 5)' % len(lst)) return POA(lst[0], lst[1], lst[2], expire_time=lst[3], signature=lst[4]) except Exception as e: raise InvalidPOAException('De-serialization failed (%s)' % e)
def check_challenge(cdata): try: randomB = bdecode(cdata) except: return None if len(randomB) != num_random_bits / 8: return None else: return randomB
def got_request_pieces(self, permid, message, selversion): try: infohash = message[1:21] pieces = bdecode(message[21:]) except: print >> sys.stderr, 'helper: got_request_pieces: bad data in REQUEST_PIECES' return False network_got_request_pieces_lambda = lambda : self.network_got_request_pieces(permid, message, selversion, infohash, pieces) self.session.lm.rawserver.add_task(network_got_request_pieces_lambda, 0) return True
def handleMessage(self, permid, selversion, message): if selversion < OLPROTO_VER_SEVENTH: if DEBUG: print >> sys.stderr, 'friendship: Got FRIENDSHIP msg from peer with old protocol', show_permid_short(permid) return False try: d = bdecode(message[1:]) except: print_exc() return False return self.process_message(permid, selversion, d)
def valid_metadata(self, infohash, metadata): try: metainfo = bdecode(metadata) tdef = TorrentDef.load_from_dict(metainfo) got_infohash = tdef.get_infohash() if infohash != got_infohash: print >> sys.stderr, "metadata: infohash doesn't match the torrent " + 'hash. Required: ' + ` infohash ` + ', but got: ' + ` got_infohash ` return False return True except: print_exc() return False
def valid_metadata(self, infohash, metadata): try: metainfo = bdecode(metadata) tdef = TorrentDef.load_from_dict(metainfo) got_infohash = tdef.get_infohash() if infohash != got_infohash: print >> sys.stderr, "metadata: infohash doesn't match the torrent " + 'hash. Required: ' + `infohash` + ', but got: ' + `got_infohash` return False return True except: print_exc() return False
def readTorrent(self, torrent): try: torrent_path = torrent['torrent_path'] f = open(torrent_path, 'rb') _data = f.read() f.close() data = bdecode(_data) del data['info'] torrent['info'] = data return torrent except Exception: return torrent
def recv_overlap(self, permid, message, selversion): try: oldict = bdecode(message[1:]) except: print_exc() if DEBUG: print >> sys.stderr, 'socnet: SOCIAL_OVERLAP: error becoding' return False if not isValidDict(oldict, permid): return False self.process_overlap(permid, oldict) return True
def got_request_pieces(self, permid, message, selversion): try: infohash = message[1:21] pieces = bdecode(message[21:]) except: print >> sys.stderr, 'helper: got_request_pieces: bad data in REQUEST_PIECES' return False network_got_request_pieces_lambda = lambda: self.network_got_request_pieces( permid, message, selversion, infohash, pieces) self.session.lm.rawserver.add_task(network_got_request_pieces_lambda, 0) return True
def got_proxy_have(self, permid, message, selversion): if DEBUG: print >> sys.stderr, 'coordinator: network_got_proxy_have: got_proxy_have' try: infohash = message[1:21] aggregated_string = bdecode(message[21:]) except: print >> sys.stderr, 'coordinator: network_got_proxy_have: warning - bad data in PROXY_HAVE' return False network_got_proxy_have_lambda = lambda : self.network_got_proxy_have(permid, infohash, selversion, aggregated_string) self.launchmany.rawserver.add_task(network_got_proxy_have_lambda, 0) return True
def got_dropped_piece(self, permid, message, selversion): if DEBUG: print >> sys.stderr, 'coordinator: got_dropped_piece' try: infohash = message[1:21] piece = bdecode(message[22:]) except: print >> sys.stderr, 'coordinator warning: bad data in DROPPED_PIECE' return False network_got_dropped_piece_lambda = lambda : self.network_got_dropped_piece(permid, infohash, peice, selversion) self.launchmany.rawserver.add_task(network_got_dropped_piece_lambda, 0) return True
def handleMessage(self, permid, selversion, message): if selversion < OLPROTO_VER_SEVENTH: if DEBUG: print >> sys.stderr, 'friendship: Got FRIENDSHIP msg from peer with old protocol', show_permid_short( permid) return False try: d = bdecode(message[1:]) except: print_exc() return False return self.process_message(permid, selversion, d)
def read_and_send_metadata(self, permid, infohash, torrent_path, selversion): torrent_data = self.read_torrent(torrent_path) if torrent_data: try: metainfo = bdecode(torrent_data) if 'info' in metainfo and 'private' in metainfo[ 'info'] and metainfo['info']['private']: if DEBUG: print >> sys.stderr, 'metadata: Not sending torrent', ` torrent_path `, 'because it is private' return 0 except: print_exc() return 0 if DEBUG: print >> sys.stderr, 'metadata: sending torrent', ` torrent_path `, len( torrent_data) torrent = {} torrent['torrent_hash'] = infohash tdef = TorrentDef.load_from_dict(metainfo) if selversion >= OLPROTO_VER_ELEVENTH and tdef.get_url_compat(): torrent['metatype'] = URL_MIME_TYPE torrent['metadata'] = tdef.get_url() else: torrent['metatype'] = TSTREAM_MIME_TYPE torrent['metadata'] = torrent_data if selversion >= OLPROTO_VER_FOURTH: data = self.torrent_db.getTorrent(infohash) if data is None: return 0 nleechers = data.get('leecher', -1) nseeders = data.get('seeder', -1) last_check_ago = int(time()) - data.get('last_check_time', 0) if last_check_ago < 0: last_check_ago = 0 status = data.get('status', 'unknown') torrent.update({ 'leecher': nleechers, 'seeder': nseeders, 'last_check_time': last_check_ago, 'status': status }) return self.do_send_metadata(permid, torrent, selversion) else: self.torrent_db.deleteTorrent(infohash, delete_file=True, commit=True) if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: no torrent data to send' return 0
def gotNatCheckReplyMessage(self, permid, selversion, channel_id, channel_data, error, payload, request_callback): if error: if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: gotNatCheckReplyMessage' print >> sys.stderr, 'NatCheckMsgHandler: error', error self._file.write('; '.join((strftime('%Y/%m/%d %H:%M:%S'), ' REPLY', show_permid(permid), str(self._secure_overlay.get_dns_from_peerdb(permid)), 'ERROR(%d)' % error, payload, '\n'))) self._file.flush() else: try: recv_data = bdecode(payload) except: print_exc() print >> sys.stderr, 'bad encoded data:', payload return False try: self.validNatCheckReplyMsg(recv_data) except RuntimeError as e: print >> sys.stderr, e return False if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: received NAT_CHECK_REPLY message: ', recv_data self._file.write('; '.join((strftime('%Y/%m/%d %H:%M:%S'), ' REPLY', show_permid(permid), str(self._secure_overlay.get_dns_from_peerdb(permid)), ':'.join([ str(x) for x in recv_data ]), '\n'))) self._file.flush() if selversion < OLPROTO_VER_NINETH: if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: freestream version too old for NATTRAVERSAL: do nothing' return True if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: do NATTRAVERSAL' if len(self.peerlist) == PEERLIST_LEN: del self.peerlist[0] self.peerlist.append([permid, recv_data[1], recv_data[2]]) if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: peerlist length is: ', len(self.peerlist) if len(self.peerlist) >= 2: self.tryHolePunching() return True
def got_dropped_piece(self, permid, message, selversion): if DEBUG: print >> sys.stderr, 'coordinator: got_dropped_piece' try: infohash = message[1:21] piece = bdecode(message[22:]) except: print >> sys.stderr, 'coordinator warning: bad data in DROPPED_PIECE' return False network_got_dropped_piece_lambda = lambda: self.network_got_dropped_piece( permid, infohash, peice, selversion) self.launchmany.rawserver.add_task(network_got_dropped_piece_lambda, 0) return True
def got_proxy_have(self, permid, message, selversion): if DEBUG: print >> sys.stderr, 'coordinator: network_got_proxy_have: got_proxy_have' try: infohash = message[1:21] aggregated_string = bdecode(message[21:]) except: print >> sys.stderr, 'coordinator: network_got_proxy_have: warning - bad data in PROXY_HAVE' return False network_got_proxy_have_lambda = lambda: self.network_got_proxy_have( permid, infohash, selversion, aggregated_string) self.launchmany.rawserver.add_task(network_got_proxy_have_lambda, 0) return True
def isValidRemoteVal(d, selversion): if not isinstance(d, dict): if DEBUG: print >> sys.stderr, 'rqmh: reply: a: value not dict' return False if selversion >= OLPROTO_VER_TWELFTH: if not ('content_name' in d and 'length' in d and 'leecher' in d and 'seeder' in d and 'category' in d and 'torrent_size' in d and 'channel_permid' in d and 'channel_name' in d): if DEBUG: print >> sys.stderr, 'rqmh: reply: torrentrec12: key missing, got', d.keys( ) return False if 'metatype' in d and 'metadata' in d: try: metatype = d['metatype'] metadata = d['metadata'] if metatype == URL_MIME_TYPE: tdef = TorrentDef.load_from_url(metadata) else: metainfo = bdecode(metadata) tdef = TorrentDef.load_from_dict(metainfo) except: if DEBUG: print >> sys.stderr, 'rqmh: reply: torrentrec12: metadata invalid' print_exc() return False elif selversion >= OLPROTO_VER_ELEVENTH: if not ('content_name' in d and 'length' in d and 'leecher' in d and 'seeder' in d and 'category' in d and 'torrent_size' in d and 'channel_permid' in d and 'channel_name' in d): if DEBUG: print >> sys.stderr, 'rqmh: reply: torrentrec11: key missing, got', d.keys( ) return False elif selversion >= OLPROTO_VER_NINETH: if not ('content_name' in d and 'length' in d and 'leecher' in d and 'seeder' in d and 'category' in d and 'torrent_size' in d): if DEBUG: print >> sys.stderr, 'rqmh: reply: torrentrec9: key missing, got', d.keys( ) return False elif not ('content_name' in d and 'length' in d and 'leecher' in d and 'seeder' in d and 'category' in d): if DEBUG: print >> sys.stderr, 'rqmh: reply: torrentrec6: key missing, got', d.keys( ) return False return True
def check_response2(rdata2, randomA, peeridA, randomB, peeridB): try: response2 = bdecode(rdata2) except: return None if response2['A'] != peeridA: return None pubB_der = response2['certB'] pubB = EC.pub_key_from_der(pubB_der) sigB = response2['SB'] if verify_response(randomB, randomA, peeridA, pubB, sigB): return pubB else: return None
def handle_crawler_request(self, permid, selversion, channel_id, message, reply_callback): if DEBUG: print >> sys.stderr, 'FriendshipCrawler: handle_friendship_crawler_database_query_request', message try: d = bdecode(message) stats = self.getStaticsFromFriendshipStatisticsTable(self.session.get_permid(), d['current time']) msg_dict = {'current time': d['current time'], 'stats': stats} msg = bencode(msg_dict) reply_callback(msg) except Exception as e: print_exc() reply_callback(str(e), 1) return True
def deserialize(encoded): if not encoded: raise InvalidPOAException('Cannot deserialize nothing') try: lst = bdecode(encoded) if len(lst) < 5: raise InvalidPOAException( 'Too few entries (got %d, expected 5)' % len(lst)) return POA(lst[0], lst[1], lst[2], expire_time=lst[3], signature=lst[4]) except Exception as e: raise InvalidPOAException('De-serialization failed (%s)' % e)
def gotNatCheckReplyMessage(self, permid, selversion, channel_id, channel_data, error, payload, request_callback): if error: if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: gotNatCheckReplyMessage' print >> sys.stderr, 'NatCheckMsgHandler: error', error self._file.write('; '.join( (strftime('%Y/%m/%d %H:%M:%S'), ' REPLY', show_permid(permid), str(self._secure_overlay.get_dns_from_peerdb(permid)), 'ERROR(%d)' % error, payload, '\n'))) self._file.flush() else: try: recv_data = bdecode(payload) except: print_exc() print >> sys.stderr, 'bad encoded data:', payload return False try: self.validNatCheckReplyMsg(recv_data) except RuntimeError as e: print >> sys.stderr, e return False if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: received NAT_CHECK_REPLY message: ', recv_data self._file.write('; '.join( (strftime('%Y/%m/%d %H:%M:%S'), ' REPLY', show_permid(permid), str(self._secure_overlay.get_dns_from_peerdb(permid)), ':'.join([str(x) for x in recv_data]), '\n'))) self._file.flush() if selversion < OLPROTO_VER_NINETH: if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: freestream version too old for NATTRAVERSAL: do nothing' return True if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: do NATTRAVERSAL' if len(self.peerlist) == PEERLIST_LEN: del self.peerlist[0] self.peerlist.append([permid, recv_data[1], recv_data[2]]) if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: peerlist length is: ', len( self.peerlist) if len(self.peerlist) >= 2: self.tryHolePunching() return True
def recv_query(self, permid, message, selversion): if selversion < OLPROTO_VER_SIXTH: return False try: d = bdecode(message[1:]) except: if DEBUG: print >> sys.stderr, 'rquery: Cannot bdecode QUERY message' return False if not isValidQuery(d, selversion): if DEBUG: print >> sys.stderr, 'rquery: QUERY invalid', ` d ` return False self.process_query(permid, d, selversion) return True
def check_response1(rdata1, randomB, peeridB): try: response1 = bdecode(rdata1) except: return [None, None] if response1['B'] != peeridB: return [None, None] pubA_der = response1['certA'] pubA = EC.pub_key_from_der(pubA_der) sigA = response1['SA'] randomA = response1['rA'] if verify_response(randomA, randomB, peeridB, pubA, sigA): return [randomA, pubA] else: return [None, None]
def recv_query(self, permid, message, selversion): if selversion < OLPROTO_VER_SIXTH: return False try: d = bdecode(message[1:]) except: if DEBUG: print >> sys.stderr, 'rquery: Cannot bdecode QUERY message' return False if not isValidQuery(d, selversion): if DEBUG: print >> sys.stderr, 'rquery: QUERY invalid', `d` return False self.process_query(permid, d, selversion) return True
def handle_crawler_reply(self, permid, selversion, channel_id, channel_data, error, message, request_callback): if error: if DEBUG: print >> sys.stderr, 'friendshipcrawler: handle_crawler_reply' print >> sys.stderr, 'friendshipcrawler: error', error, message else: try: d = bdecode(message) except Exception: print_exc() else: if DEBUG: print >> sys.stderr, 'friendshipcrawler: handle_crawler_reply' print >> sys.stderr, 'friendshipcrawler: friendship: Got', `d` self.saveFriendshipStatistics(permid, d['current time'], d['stats']) return True
def gotBarterCastMessage(self, recv_msg, sender_permid, selversion): if DEBUG: print >> sys.stderr, 'bartercast: %s Received a BarterCast msg from %s' % ( ctime(now()), self.bartercastdb.getName(sender_permid)) if not sender_permid or sender_permid == self.bartercastdb.my_permid: print >> sys.stderr, 'bartercast: error - got BarterCastMsg from a None peer', sender_permid, recv_msg return False if MAX_BARTERCAST_LENGTH > 0 and len(recv_msg) > MAX_BARTERCAST_LENGTH: print >> sys.stderr, 'bartercast: warning - got large BarterCastMsg', len( recv_msg) return False bartercast_data = {} try: bartercast_data = bdecode(recv_msg) except: print >> sys.stderr, 'bartercast: warning, invalid bencoded data' return False try: self.validBarterCastMsg(bartercast_data) except RuntimeError as msg: print >> sys.stderr, msg return False if LOG: self.logMsg(bartercast_data, sender_permid, 'in', logfile=self.logfile) data = bartercast_data['data'] if 'totals' in bartercast_data: totals = bartercast_data['totals'] else: totals = None if DEBUG: st = time() self.handleBarterCastMsg(sender_permid, data) et = time() diff = et - st print >> sys.stderr, 'bartercast: HANDLE took %.4f' % diff else: self.handleBarterCastMsg(sender_permid, data, totals) if not self.isBlocked(sender_permid, self.send_block_list): self.replyBarterCast(sender_permid, selversion) return True
def gotChannelCastMessage(self, recv_msg, sender_permid, selversion): if selversion < OLPROTO_VER_THIRTEENTH: if DEBUG: print >> sys.stderr, 'channelcast: Do not receive from lower version peer:', selversion return True if DEBUG: print >> sys.stderr, 'channelcast: Received a msg from ', show_permid_short( sender_permid) print >> sys.stderr, 'channelcast: my_permid=', show_permid_short( self.my_permid) if not sender_permid or sender_permid == self.my_permid: if DEBUG: print >> sys.stderr, 'channelcast: warning - got channelcastMsg from a None/Self peer', show_permid_short( sender_permid), recv_msg return False channelcast_data = {} try: channelcast_data = bdecode(recv_msg) except: print >> sys.stderr, 'channelcast: warning, invalid bencoded data' return False if not validChannelCastMsg(channelcast_data): print >> sys.stderr, 'channelcast: invalid channelcast_message' return False for ch in channelcast_data.values(): if isinstance(ch['publisher_name'], str): ch['publisher_name'] = str2unicode(ch['publisher_name']) if isinstance(ch['torrentname'], str): ch['torrentname'] = str2unicode(ch['torrentname']) self.handleChannelCastMsg(sender_permid, channelcast_data) if self.log: dns = self.dnsindb(sender_permid) if dns: ip, port = dns MSG_ID = 'CHANNELCAST' msg = repr(channelcast_data) self.overlay_log('RECV_MSG', ip, port, show_permid(sender_permid), selversion, MSG_ID, msg) if self.TESTASSERVER: self.createAndSendChannelCastMessage(sender_permid, selversion) return True
def read_and_send_metadata(self, permid, infohash, torrent_path, selversion): torrent_data = self.read_torrent(torrent_path) if torrent_data: try: metainfo = bdecode(torrent_data) if 'info' in metainfo and 'private' in metainfo['info'] and metainfo['info']['private']: if DEBUG: print >> sys.stderr, 'metadata: Not sending torrent', `torrent_path`, 'because it is private' return 0 except: print_exc() return 0 if DEBUG: print >> sys.stderr, 'metadata: sending torrent', `torrent_path`, len(torrent_data) torrent = {} torrent['torrent_hash'] = infohash tdef = TorrentDef.load_from_dict(metainfo) if selversion >= OLPROTO_VER_ELEVENTH and tdef.get_url_compat(): torrent['metatype'] = URL_MIME_TYPE torrent['metadata'] = tdef.get_url() else: torrent['metatype'] = TSTREAM_MIME_TYPE torrent['metadata'] = torrent_data if selversion >= OLPROTO_VER_FOURTH: data = self.torrent_db.getTorrent(infohash) if data is None: return 0 nleechers = data.get('leecher', -1) nseeders = data.get('seeder', -1) last_check_ago = int(time()) - data.get('last_check_time', 0) if last_check_ago < 0: last_check_ago = 0 status = data.get('status', 'unknown') torrent.update({'leecher': nleechers, 'seeder': nseeders, 'last_check_time': last_check_ago, 'status': status}) return self.do_send_metadata(permid, torrent, selversion) else: self.torrent_db.deleteTorrent(infohash, delete_file=True, commit=True) if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: no torrent data to send' return 0
def gotUdpConnectReply(self, permid, selversion, channel_id, channel_data, error, mhr_msg, request_callback): if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: gotMakeHoleReplyMessage' try: mhr_data = bdecode(mhr_msg) except: print_exc() print >> sys.stderr, 'NatCheckMsgHandler: bad encoded data:', mhr_msg return False if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: message is', mhr_data try: request_id, reply = mhr_data.split(':') except: print_exc() print >> sys.stderr, 'NatCheckMsgHandler: error in received data:', mhr_data return False if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: request_id is', request_id if request_id in self.trav: if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: request_id is in the list' peer, value = self.trav[request_id] if peer == None: if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: first peer reply' self.trav[request_id] = ((permid, self._secure_overlay.get_dns_from_peerdb(permid)), reply) elif type(peer) == TupleType: if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: second peer reply' self._file2.write('; '.join((strftime('%Y/%m/%d %H:%M:%S'), ' REPLY', request_id, show_permid(peer[0]), str(peer[1]), value, show_permid(permid), str(self._secure_overlay.get_dns_from_peerdb(permid)), reply, '\n'))) del self.trav[request_id] self._file2.flush()
def gotUdpConnectReply(self, permid, selversion, channel_id, channel_data, error, mhr_msg, request_callback): if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: gotMakeHoleReplyMessage' try: mhr_data = bdecode(mhr_msg) except: print_exc() print >> sys.stderr, 'NatCheckMsgHandler: bad encoded data:', mhr_msg return False if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: message is', mhr_data try: request_id, reply = mhr_data.split(':') except: print_exc() print >> sys.stderr, 'NatCheckMsgHandler: error in received data:', mhr_data return False if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: request_id is', request_id if request_id in self.trav: if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: request_id is in the list' peer, value = self.trav[request_id] if peer == None: if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: first peer reply' self.trav[request_id] = (( permid, self._secure_overlay.get_dns_from_peerdb(permid)), reply) elif type(peer) == TupleType: if DEBUG: print >> sys.stderr, 'NatCheckMsgHandler: second peer reply' self._file2.write('; '.join( (strftime('%Y/%m/%d %H:%M:%S'), ' REPLY', request_id, show_permid(peer[0]), str(peer[1]), value, show_permid(permid), str(self._secure_overlay.get_dns_from_peerdb(permid)), reply, '\n'))) del self.trav[request_id] self._file2.flush()
def send_metadata(self, permid, message, selversion): try: infohash = bdecode(message[1:]) except: print_exc() if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: error becoding' return False if not isValidInfohash(infohash): if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: invalid hash' return False res = self.torrent_db.getOne(('torrent_file_name', 'status_id'), infohash=bin2str(infohash)) if not res: if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: not in database', infohash return True torrent_file_name, status_id = res if status_id == self.torrent_db._getStatusID('dead'): if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: Torrent was dead' return True if not torrent_file_name: if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: no torrent file name' return True torrent_path = os.path.join(self.torrent_dir, torrent_file_name) if not os.path.isfile(torrent_path): if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: not existing', res, torrent_path return True task = { 'permid': permid, 'infohash': infohash, 'torrent_path': torrent_path, 'selversion': selversion } self.upload_queue.append(task) if int(time()) >= self.next_upload_time: self.checking_upload_queue() return True
def send_metadata(self, permid, message, selversion): try: infohash = bdecode(message[1:]) except: print_exc() if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: error becoding' return False if not isValidInfohash(infohash): if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: invalid hash' return False res = self.torrent_db.getOne(('torrent_file_name', 'status_id'), infohash=bin2str(infohash)) if not res: if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: not in database', infohash return True torrent_file_name, status_id = res if status_id == self.torrent_db._getStatusID('dead'): if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: Torrent was dead' return True if not torrent_file_name: if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: no torrent file name' return True torrent_path = os.path.join(self.torrent_dir, torrent_file_name) if not os.path.isfile(torrent_path): if DEBUG: print >> sys.stderr, 'metadata: GET_METADATA: not existing', res, torrent_path return True task = {'permid': permid, 'infohash': infohash, 'torrent_path': torrent_path, 'selversion': selversion} self.upload_queue.append(task) if int(time()) >= self.next_upload_time: self.checking_upload_queue() return True
def gotBarterCastMessage(self, recv_msg, sender_permid, selversion): if DEBUG: print >> sys.stderr, 'bartercast: %s Received a BarterCast msg from %s' % (ctime(now()), self.bartercastdb.getName(sender_permid)) if not sender_permid or sender_permid == self.bartercastdb.my_permid: print >> sys.stderr, 'bartercast: error - got BarterCastMsg from a None peer', sender_permid, recv_msg return False if MAX_BARTERCAST_LENGTH > 0 and len(recv_msg) > MAX_BARTERCAST_LENGTH: print >> sys.stderr, 'bartercast: warning - got large BarterCastMsg', len(recv_msg) return False bartercast_data = {} try: bartercast_data = bdecode(recv_msg) except: print >> sys.stderr, 'bartercast: warning, invalid bencoded data' return False try: self.validBarterCastMsg(bartercast_data) except RuntimeError as msg: print >> sys.stderr, msg return False if LOG: self.logMsg(bartercast_data, sender_permid, 'in', logfile=self.logfile) data = bartercast_data['data'] if 'totals' in bartercast_data: totals = bartercast_data['totals'] else: totals = None if DEBUG: st = time() self.handleBarterCastMsg(sender_permid, data) et = time() diff = et - st print >> sys.stderr, 'bartercast: HANDLE took %.4f' % diff else: self.handleBarterCastMsg(sender_permid, data, totals) if not self.isBlocked(sender_permid, self.send_block_list): self.replyBarterCast(sender_permid, selversion) return True
def isValidRemoteVal(d, selversion): if not isinstance(d, dict): if DEBUG: print >> sys.stderr, 'rqmh: reply: a: value not dict' return False if selversion >= OLPROTO_VER_TWELFTH: if not ('content_name' in d and 'length' in d and 'leecher' in d and 'seeder' in d and 'category' in d and 'torrent_size' in d and 'channel_permid' in d and 'channel_name' in d): if DEBUG: print >> sys.stderr, 'rqmh: reply: torrentrec12: key missing, got', d.keys() return False if 'metatype' in d and 'metadata' in d: try: metatype = d['metatype'] metadata = d['metadata'] if metatype == URL_MIME_TYPE: tdef = TorrentDef.load_from_url(metadata) else: metainfo = bdecode(metadata) tdef = TorrentDef.load_from_dict(metainfo) except: if DEBUG: print >> sys.stderr, 'rqmh: reply: torrentrec12: metadata invalid' print_exc() return False elif selversion >= OLPROTO_VER_ELEVENTH: if not ('content_name' in d and 'length' in d and 'leecher' in d and 'seeder' in d and 'category' in d and 'torrent_size' in d and 'channel_permid' in d and 'channel_name' in d): if DEBUG: print >> sys.stderr, 'rqmh: reply: torrentrec11: key missing, got', d.keys() return False elif selversion >= OLPROTO_VER_NINETH: if not ('content_name' in d and 'length' in d and 'leecher' in d and 'seeder' in d and 'category' in d and 'torrent_size' in d): if DEBUG: print >> sys.stderr, 'rqmh: reply: torrentrec9: key missing, got', d.keys() return False elif not ('content_name' in d and 'length' in d and 'leecher' in d and 'seeder' in d and 'category' in d): if DEBUG: print >> sys.stderr, 'rqmh: reply: torrentrec6: key missing, got', d.keys() return False return True
def gotChannelCastMessage(self, recv_msg, sender_permid, selversion): if selversion < OLPROTO_VER_THIRTEENTH: if DEBUG: print >> sys.stderr, 'channelcast: Do not receive from lower version peer:', selversion return True if DEBUG: print >> sys.stderr, 'channelcast: Received a msg from ', show_permid_short(sender_permid) print >> sys.stderr, 'channelcast: my_permid=', show_permid_short(self.my_permid) if not sender_permid or sender_permid == self.my_permid: if DEBUG: print >> sys.stderr, 'channelcast: warning - got channelcastMsg from a None/Self peer', show_permid_short(sender_permid), recv_msg return False channelcast_data = {} try: channelcast_data = bdecode(recv_msg) except: print >> sys.stderr, 'channelcast: warning, invalid bencoded data' return False if not validChannelCastMsg(channelcast_data): print >> sys.stderr, 'channelcast: invalid channelcast_message' return False for ch in channelcast_data.values(): if isinstance(ch['publisher_name'], str): ch['publisher_name'] = str2unicode(ch['publisher_name']) if isinstance(ch['torrentname'], str): ch['torrentname'] = str2unicode(ch['torrentname']) self.handleChannelCastMsg(sender_permid, channelcast_data) if self.log: dns = self.dnsindb(sender_permid) if dns: ip, port = dns MSG_ID = 'CHANNELCAST' msg = repr(channelcast_data) self.overlay_log('RECV_MSG', ip, port, show_permid(sender_permid), selversion, MSG_ID, msg) if self.TESTASSERVER: self.createAndSendChannelCastMessage(sender_permid, selversion) return True
def olthread_process_dialback_reply(self, dns, message): self.dbreach = True permid = self.olthread_permid_of_asked_peer(dns) if permid is None: if DEBUG: print >> sys.stderr, "dialback: DIALBACK_REPLY: Got reply from peer I didn't ask", dns return False del self.peers_asked[permid] try: myip = bdecode(message[1:]) except: print_exc() if DEBUG: print >> sys.stderr, 'dialback: DIALBACK_REPLY: error becoding' return False if not isValidIP(myip): if DEBUG: print >> sys.stderr, 'dialback: DIALBACK_REPLY: invalid IP' return False if self.trust_superpeers: superpeers = self.superpeer_db.getSuperPeers() if permid in superpeers: if DEBUG: print >> sys.stderr, 'dialback: DIALBACK_REPLY: superpeer said my IP address is', myip, 'setting it to that' self.consensusip = myip self.fromsuperpeer = True else: self.myips, consensusip = tally_opinion(myip, self.myips, PEERS_TO_AGREE) if self.consensusip is None: self.consensusip = consensusip if self.consensusip is not None: self.launchmany.dialback_got_ext_ip_callback(self.consensusip) if DEBUG: print >> sys.stderr, 'dialback: DIALBACK_REPLY: I think my IP address is', self.old_ext_ip, 'others say', self.consensusip, ', setting it to latter' self.launchmany.dialback_reachable_callback() return True
def StringToValue(self, value, type): 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': value = None elif type.startswith('bencode'): value = bdecode(value) except: value = None if value is None: value = self.defaultvalues[type] return value