Example #1
0
def bep44_insert(index_key, desc_link, desc_inline, priv_key):
    """Return a signed BEP44 mutable data item (as bytes)."""

    # It is not safe to assume that storing more than 1000 bytes will succeed,
    # according to <http://bittorrent.org/beps/bep_0044.html#messages>.
    v = desc_inline
    if len(bencoder.bencode(desc_inline)) > 1000:
        v = desc_link

    salt = hashlib.sha1(index_key.encode()).digest()  # SHA1 hash of the index key
    seq = int(time.time())  # integer Unix time stamp

    # Low-level signature buffer computation is mandated by
    # <http://bittorrent.org/beps/bep_0044.html#signature-verification>.
    sigbuf = b''
    sigbuf += b'4:salt%d:%s' % (len(salt), salt)
    sigbuf += b'3:seqi%de' % seq
    sigbuf += b'1:v%d:%s' % (len(v), v)

    # Sign, build exported message fields and encode the result.
    # We follow the names used in the BEP44 document.
    sig = priv_key.sign(sigbuf).signature
    return bencoder.bencode(dict(
        # cas is not compulsory
        # id depends on the publishing node
        k=priv_key.verify_key.encode(),
        salt=salt,
        seq=seq,
        # token depends on the insertion
        sig=sig,
        v=v
    ))
Example #2
0
def test_encode_large_int(benchmark):
    assert bencode(1455189890) == b'i1455189890e'
    assert bencode(25735241490) == b'i25735241490e'
    MAX_SIZE = sys.maxsize + 1
    BENCODED_MAXSIZE = ('i%de' % MAX_SIZE).encode()

    assert benchmark(bencode, MAX_SIZE) == BENCODED_MAXSIZE
Example #3
0
def test_encode_large_int(benchmark):
    assert bencode(1455189890) == b'i1455189890e'
    assert bencode(25735241490) == b'i25735241490e'
    MAX_SIZE = sys.maxsize + 1
    BENCODED_MAXSIZE = ('i%de' % MAX_SIZE).encode()

    assert benchmark(bencode, MAX_SIZE) == BENCODED_MAXSIZE
Example #4
0
	def sendHello(self):
		# global REG_IPV4, REG_PORT
		helloTime = time.time()
					
		firstHello = True
		while True:
			if (time.time() - helloTime) > 10 or firstHello:
				# Create a UDP socket
				sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

				# print(REG_IPV4, REG_PORT)

				server_address = (REG_IPV4, int(REG_PORT))      
				firstHello = False
				data = self.prepareData()
				bencoded = bencode(data)
				try:
					# Send data
					# print('sending {!r}'.format(bencoded))
					# print("to")
					# print(server_address)
					# print(bencoded)
					sent = sock.sendto(bencoded, server_address)
					# Receive response
					# print('waiting to receive')
					# data, server = sock.recvfrom(4096)
					# print('received {!r}'.format(data))

				finally:
					# print('closing socket')
					sock.close()
				helloTime = time.time() 
Example #5
0
	def __init__(self, sock):
		print("Peer started ...")
		# Start RPC daemon for listening to his messages
		RPCThread = threading.Thread(target=self.RPCHandler, args=())
		RPCThread.daemon = True
		RPCThread.start()

		helloThread = threading.Thread(target=self.sendHello, args=())
		helloThread.daemon = True
		helloThread.start()        

		# Get some time variable out of while loop
		helloTime = time.time()

		while True:       
			# print('\nwaiting to receive message')
			data, address = sock.recvfrom(4096)

			# print('received {} bytes from {}'.format(
				# len(data), address))
			data = data.decode("utf-8") 
			dataDecoded = bdecode(data)
			message = self.parseMessage(dataDecoded)
			for line in message:
				if line == 'type':
					if message[line] == 'message':
						print("[SERVER] I got message from someone")
						print(message)
						bencoded = bencode(b'ACK')
						sent = sock.sendto(bencoded, address)
Example #6
0
 def send_krpc(self, data, address):
     """发送 krpc 信息"""
     self.logger.debug("I'm sending to {}".format(address))
     try:
         self.udp_socket.sendto(bencode(data), address)
     except Exception:
         self.logger.exception(Exception)
Example #7
0
 def send_message(self, data, addr):
     data.setdefault("t", b"tt")
     try:
         print(addr, data['q'])
     except Exception:
         print(addr)
     self.transport.sendto(bencoder.bencode(data), addr)
Example #8
0
	def sendGetList(self):
		# Create a UDP socket
		sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

		server_address = (REG_IPV4, int(REG_PORT))

		data = {
			"type":"getlist", 
			"txid": TXID
		}
				 
		while True:
			bencoded = bencode(data)
			try:
				# Send data
				# print('sending {!r}'.format(bencoded))
				sent = sock.sendto(bencoded, server_address)

				# Receive response
				# print('waiting to receive')
				data, server = sock.recvfrom(4096)
				decodedData = bdecode(data)
				# print('received {!r}'.format(decodedData))
				self.sendACK()
			finally:
				# print('closing socket')
				sock.close()
			return decodedData
Example #9
0
File: my.py Project: Zsfzy/dht-
 def send_krpc(self, msg, address):
     # print(address, msg['q'])
     # print(msg)
     # print(bencode(msg))
     try:
         self.transport.sendto(bencode(msg), address)
     except Exception as e:
         print(address, e)
Example #10
0
def test_encode_complex():
    od = dict()
    od['KeyA'] = ['listitemA', {'k': 'v'}, 3]
    od['KeyB'] = {'k': 'v'}
    od['KeyC'] = 3
    od['KeyD'] = 'AString'
    expected_result = b'd4:KeyAl9:listitemAd1:k1:vei3ee4:KeyBd1:k1:ve4:KeyCi3e4:KeyD7:AStringe'
    assert bencode(od) == expected_result
Example #11
0
 def save_dtorrent(self, files, comment=None):
     dtor = files.dtors[0].as_dict
     if comment:
         dtor[b'comment'] = comment.encode()
     file_path = os.path.join(self.dtor_save_dir,
                              self.tor_info.folder_name) + ".torrent"
     with open(file_path, "wb") as f:
         f.write(bencode(dtor))
Example #12
0
def test_validate_missing_info():
    data = OrderedDict([
        (b'foo', b'bar'),
    ])
    fo = io.BytesIO(bencode(data))
    with pytest.raises(torf.MetainfoError) as excinfo:
        torf.Torrent.read_stream(fo, validate=True)
    assert excinfo.match("^Invalid metainfo: Missing 'info'$")
Example #13
0
def test_single_tracker(valid_singlefile_metainfo):
    valid_singlefile_metainfo[b'announce'] = b'http://lonelyhost/announce'
    valid_singlefile_metainfo.pop(b'announce-list', None)
    fo = io.BytesIO(bencode(valid_singlefile_metainfo))
    t = torf.Torrent.read_stream(fo)
    assert t.trackers == [[
        str(valid_singlefile_metainfo[b'announce'], encoding='utf-8')
    ]]
Example #14
0
def test_encode_dict_subclass():
    class AAA(dict):
        pass

    od = AAA()
    od['ka'] = 'va'
    od['kb'] = 2
    assert bencode(od) == b'd2:ka2:va2:kbi2ee'
Example #15
0
def test_read_from_unreadable_file(valid_singlefile_metainfo, tmpdir):
    f = tmpdir.join('a.torrent')
    f.write_binary(bencode(valid_singlefile_metainfo))
    f.chmod(mode=0o222)

    with pytest.raises(torf.ReadError) as excinfo:
        torf.Torrent.read(str(f))
    assert excinfo.match(f'^{str(f)}: Permission denied$')
Example #16
0
def send_krpc(message, node, sock):
    '''
    sends bencoded krpc to node ip address and node port
    '''
    try:
        sock.sendto(bencode(message), (node[1], node[2]))
    except (IndexError, TypeError):
        pass
Example #17
0
def test_encode_complex():
    od = dict()
    od['KeyA'] = ['listitemA', {'k': 'v'}, 3]
    od['KeyB'] = {'k': 'v'}
    od['KeyC'] = 3
    od['KeyD'] = 'AString'
    expected_result = b'd4:KeyAl9:listitemAd1:k1:vei3ee4:KeyBd1:k1:ve4:KeyCi3e4:KeyD7:AStringe'
    assert bencode(od) == expected_result
Example #18
0
def infohash_alt(filename, source=None):
    '''Calculate infohash for the same torrent with different source tag'''
    torrent, info = _parse_torrent(filename)
    if source is None:  # delete source tag
        if SOURCE in info:
            del info[SOURCE]
    else:
        info[SOURCE] = source
    return sha1(bencode(info)).hexdigest()
Example #19
0
def test_multiple_trackers(valid_singlefile_metainfo, tmpdir):
    valid_singlefile_metainfo[b'announce-list'] = [[
        b'http://localhost', b'http://foohost'
    ], [b'http://bazhost']]
    valid_singlefile_metainfo.pop(b'announce', None)
    fo = io.BytesIO(bencode(valid_singlefile_metainfo))
    t = torf.Torrent.read_stream(fo)
    assert t.trackers == [[
        str(url, encoding='utf-8') for url in tier
    ] for tier in valid_singlefile_metainfo[b'announce-list']]
Example #20
0
def test_successful_read(valid_singlefile_metainfo):
    fo = io.BytesIO(bencode(valid_singlefile_metainfo))
    t = torf.Torrent.read_stream(fo)
    assert t.path is None
    assert tuple(t.files) == (str(valid_singlefile_metainfo[b'info'][b'name'],
                                  encoding='utf-8'), )
    assert tuple(t.filepaths) == ()
    assert t.name == str(valid_singlefile_metainfo[b'info'][b'name'],
                         encoding='utf-8')
    assert t.size == valid_singlefile_metainfo[b'info'][b'length']
    assert t.infohash == sha1(bencode(
        valid_singlefile_metainfo[b'info'])).hexdigest()
    assert t.comment == str(valid_singlefile_metainfo[b'comment'],
                            encoding='utf-8')
    assert t.creation_date == datetime.fromtimestamp(
        valid_singlefile_metainfo[b'creation date'])
    assert t.created_by == str(valid_singlefile_metainfo[b'created by'],
                               encoding='utf-8')
    assert t.private is bool(valid_singlefile_metainfo[b'info'][b'private'])
    assert t.piece_size == valid_singlefile_metainfo[b'info'][b'piece length']
Example #21
0
    def info_hash(self):
        """
        :return: The SHA-1 info hash of the torrent. Useful for generating
            magnet links.

        .. note:: ``generate()`` must be called first.
        """
        if getattr(self, '_data', None):
            return sha1(bencode(self._data['info'])).hexdigest()
        else:
            raise exceptions.TorrentNotGeneratedException
Example #22
0
    def dump(self):
        """
        :return: The bencoded torrent data as a byte string.

        .. note:: ``generate()`` must be called first.
        """
        if getattr(self, '_data', None):

            return bencode(self._data)
        else:
            raise exceptions.TorrentNotGeneratedException
Example #23
0
    def info_hash_base32(self):
        """
        Returns the base32 info hash of the torrent. Useful for generating
        magnet links.

        .. note:: ``generate()`` must be called first.
        """
        if getattr(self, '_data', None):
            return b32encode(sha1(bencode(self._data['info'])).digest())
        else:
            raise exceptions.TorrentNotGeneratedException
Example #24
0
def test_read_from_proper_torrent_file(valid_multifile_metainfo, tmpdir):
    f = tmpdir.join('a.torrent')
    f.write_binary(bencode(valid_multifile_metainfo))
    t = torf.Torrent.read(str(f))
    exp_info = valid_multifile_metainfo[b'info']
    assert t.path is None
    assert tuple(t.files) == tuple(
        str(b'/'.join([exp_info[b'name']] + f[b'path']), encoding='utf-8')
        for f in exp_info[b'files'])
    assert tuple(t.filepaths) == ()
    assert t.name == str(exp_info[b'name'], encoding='utf-8')
    assert t.size == sum(f[b'length'] for f in exp_info[b'files'])
    assert t.infohash == sha1(bencode(exp_info)).hexdigest()
    assert t.comment == str(valid_multifile_metainfo[b'comment'],
                            encoding='utf-8')
    assert t.creation_date == datetime.fromtimestamp(
        valid_multifile_metainfo[b'creation date'])
    assert t.created_by == str(valid_multifile_metainfo[b'created by'],
                               encoding='utf-8')
    assert t.private is bool(exp_info[b'private'])
    assert t.piece_size == exp_info[b'piece length']
Example #25
0
    def send_krpc(self, msg, address):
        """
        发送 krpc 协议

        :param msg: 发送 UDP 报文信息
        :param address: 发送地址,(ip, port) 元组
        """
        try:
            # msg 要经过 bencode 编码
            self.udp.sendto(bencoder.bencode(msg), address)
        except:
            pass
Example #26
0
def test_read_nonstandard_data_without_validation():
    data = OrderedDict([(b'foo', b'bar'), (b'number', 17),
                        (b'list', [1, b'two']),
                        (b'dict', OrderedDict([
                            (b'yes', 1),
                            (b'no', 0),
                        ]))])
    fo = io.BytesIO(bencode(data))
    t = torf.Torrent.read_stream(fo, validate=False)
    assert t.metainfo['foo'] == 'bar'
    assert t.metainfo['number'] == 17
    assert t.metainfo['list'] == [1, 'two']
    assert t.metainfo['dict'] == {'yes': 1, 'no': 0}
Example #27
0
    def parse_dtorrent(self, path):
        with open(path, "rb") as f:
            torbytes = f.read()
        self.dtor_dict = bdecode(torbytes)
        announce = self.dtor_dict[b'announce'].decode()

        tr_domain = re.search(r"https?://(.+?)/.+", announce).group(1)
        for t, data in tr_data.items():
            if tr_domain in data['tracker']:
                self.src_tr = t
                break

        info = self.dtor_dict[b'info']
        self.info_hash = sha1(bencode(info)).hexdigest()
Example #28
0
 async def get_metainfo(self, infohash, addr):
     fail = False
     async with self.fetch_metainfo_semaphore:
         filename = '{}{}{}.torrent'.format(cfg.get('torrent', 'save_path'), os.sep, infohash.lower())
         if len(glob.glob(filename)) == 0:
             try:
                 metainfo = await asyncio.wait_for(
                     get_metadata(
                         infohash, addr[0], addr[1], loop=self.loop
                     ),
                     timeout=self.interval * 20)
             except:
                 fail = True
             if fail or (isinstance(metainfo, bool) and metainfo is False):
                 async with self.database_semaphore:
                     async with self.connection_pool.acquire() as connect:
                         cursor = await connect.cursor()
                         await cursor.execute(base_sql.remove_from_announce_queue.format(info_hash=infohash))
                         await connect.commit()
                         await cursor.close()
                         return
             if metainfo is not None:
                 # hash error
                 if infohash != get_meta_hash(metainfo):
                     return
                 name = get_filename(metainfo)
                 size = get_file_size(metainfo)
                 logging.info(
                     'Hash: {}. Name: {}. Size: {}'.format(
                         infohash, name, size
                     )
                 )
                 file_content = bencoder.bencode({b'info': metainfo})
                 async with aiofiles.open(filename, mode='wb') as f:
                     await f.write(file_content)
                 async with self.database_semaphore:
                     async with self.connection_pool.acquire() as connect:
                         cursor = await connect.cursor()
                         try:
                             await cursor.execute(base_sql.insert_into_torrent.format(
                                 name=aiomysql.escape_string(name),
                                 info_hash=infohash,
                                 size=size))
                         except pymysql.err.IntegrityError:
                             await cursor.rollback()
                         finally:
                             await cursor.execute(base_sql.remove_from_announce_queue.format(info_hash=infohash))
                             await connect.commit()
                         await cursor.close()
Example #29
0
	def sendMessage(self, data):
		print("[INFO] Send message")
		data2 = data.decode("utf-8")
		data2 = data2.replace("'", '"')
		data3 = json.loads(data2)
		to = data3['to']
		message = data3['message']
		users = self.sendGetList()
		for item in users:
			if item == "peers":
				for entry in users[item]:
					user = (users['peers'][str(entry)])
					if user['username'].decode("utf-8") == to:
						("here2")
						ip = (user['ipv4']).decode("utf-8")
						port = (user['port']) 
		
		# Create a UDP socket
		sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

		server_address = (ip, int(port))
		next_id()
		data = {
			"type":"message",
			"txid": TXID,
			"from": str(USERNAME),
			"to": str(to),
			"message":str(message)
		}
				 
		while True:
			bencoded = bencode(data)
			try:
				# Send data
				# print('sending {!r}'.format(bencoded))
				sent = sock.sendto(bencoded, server_address)

				# Receive response
				# print('waiting to receive')
				data, server = sock.recvfrom(4096)
				print('received {!r}'.format(data))

			finally:
				# print('closing socket')
				sock.close()
				return
Example #30
0
    def create(self, target_path=None):
        self.validate()
        if not target_path:
            target_path = os.getcwd()
        torrent_info = {
            "announce": self.announce,
            "creation date": self.creation_date,
            "encoding": self.encoding,
            "info": self.info
        }
        if self.announce_list:
            torrent_info['announce-list'] = self.announce_list
        if self.created_by:
            torrent_info['created by'] = self.created_by

        encode_info = bencoder.bencode(torrent_info)
        file_name = os.path.join(target_path, self.info['name'] + ".torrent")
        with open(file_name, "wb") as f:
            f.write(encode_info)
Example #31
0
	def sendACK(self):
		# Create a UDP socket
		sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

		server_address = (REG_IPV4, int(REG_PORT))
		next_id()
		data = {
			"type":"ack", 
			"txid": TXID
		}
				 
		while True:
			bencoded = bencode(data)
			try:
				# Send data
				# print('sending {!r}'.format(bencoded))
				sent = sock.sendto(bencoded, server_address)
			finally:
				# print('closing socket')
				sock.close()
			return
Example #32
0
    def __init__(self):
        print("[INFO] init")
        print("Server is starting ...")
        # Start RPC daemon for listening to his messages
        RPCThread = threading.Thread(target=self.RPCHandler, args=())
        RPCThread.daemon = True
        RPCThread.start()

        # Create a UDP socket
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        # Bind the socket to the port
        server_address = (REG_IPV4, int(REG_PORT))
        print('Serverstarting up socket on {} port {}'.format(*server_address))
        sock.bind(server_address)

        while True:
            # print('\nwaiting to receive message')
            data, address = sock.recvfrom(4096)

            # print('received {} bytes from {}'.format(
            # len(data), address))
            data = data.decode("utf-8")
            dataDecoded = bdecode(data)
            message = self.parseMessage(dataDecoded)
            # print(message)
            for line in message:
                self.checkPeerHelloInterval()
                if line == 'type':
                    if message[line] == 'getlist':
                        print("[SERVER] I got GETLIST")
                        data = self.preparePeersData()
                        bencoded = bencode(data)
                        sent = sock.sendto(bencoded, address)
                    elif message[line] == 'hello':
                        print("[SERVER] I got HELO")
                        self.checkPeer(message)
                    elif message[line] == 'ack':
                        print("ACK")
Example #33
0
 def send_message(self, data, addr):
     data.setdefault("t", b"tt")
     self.transport.sendto(bencoder.bencode(data), addr)
Example #34
0
def test_infohash():
    import hashlib
    with open(TORRENT_PATH, "rb") as f:
        torrent = bdecode(f.read())
    infohash = hashlib.sha1(bencode(torrent[b'info'])).hexdigest()
    assert infohash == "4194e473d6c49630e1c6247d6716076809bb96ae"
Example #35
0
def test_encode_false(benchmark):
    assert benchmark(bencode, False) == bencode(0)
Example #36
0
def test_encode_true(benchmark):
    assert benchmark(bencode, True) == bencode(1)