예제 #1
0
    def call(self):
        '''
        Call the function, passing self.arguments.
        Use self.cookie for auth if provided.
        '''
        password = self.client.password

        txid = random_string()

        pass_hash = hashlib.sha256(password + self.cookie).hexdigest()

        req = {
            'q': 'auth',
            'aq': self.function_name,
            'hash': pass_hash,
            'cookie': self.cookie,
            'args': self.call_args,
            'txid': txid
        }
        first_time_benc_req = bencoder.encode(req)
        req['hash'] = hashlib.sha256(first_time_benc_req).hexdigest()
        second_time_benc_req = bencoder.encode(req)

        if SUPER_VERBOSE:
            print "Calling function: %s" % req

        self.send(second_time_benc_req)

        return txid
예제 #2
0
    def call(self):
        """
        Call the function, passing self.arguments.
        Use self.cookie for auth if provided.
        """
        password = self.client.password

        txid = random_string()

        pass_hash = hashlib.sha256(password + self.cookie).hexdigest()

        req = {
            "q": "auth",
            "aq": self.function_name,
            "hash": pass_hash,
            "cookie": self.cookie,
            "args": self.call_args,
            "txid": txid,
        }
        first_time_benc_req = bencoder.encode(req)
        req["hash"] = hashlib.sha256(first_time_benc_req).hexdigest()
        second_time_benc_req = bencoder.encode(req)

        if SUPER_VERBOSE:
            print "Calling function: %s" % req

        self.send(second_time_benc_req)

        return txid
예제 #3
0
def gen_hash():
    '''
    Generated SHA1 hash based on the 'info' section of the magnet link data.
    '''
    info = magnet.info
    encoded_info = bencoder.encode(info)
    return hashlib.sha1(encoded_info)
예제 #4
0
 def get_peer_id(self):
     info = encode(self.torrent_file_dict[b'info'])
     peer_id = 'SA' + ''.join(
         random.choice(string.ascii_lowercase + string.digits)
         for i in range(18)
     )
     return peer_id
예제 #5
0
def gen_hash(torrent_dat):
    '''
    Generated SHA1 hash based on the 'info' section of the magnet link data.
    '''
    info = torrent_dat['info']
    encoded_info = bencoder.encode(info)
    return hashlib.sha1(encoded_info)
예제 #6
0
def add_trcackers(filename):
    f = open('torrent/' + filename, "rb")  # 读入文件

    d = bencoder.decode(f.read())
    #print(d[b'announce-list'])
    trackers = 'track.txt'  # 保存trackers的文本文档,可编辑,可自行添加trackers
    track_list = []

    with open(trackers) as f:
        for line in f:
            if len(line) > 1:
                l = line.rstrip()
                n = []
                n.append(l)

                track_list.append(n)
    #print(000, len(track_list))

    #print(len(track_list))
    a = track_list + d[b'announce-list']
    l2 = []
    for i in a:
        if i not in l2:
            l2.append(i)
    print(len(l2))
    d[b'announce-list'] = l2
    with open('torrent/' + filename, "wb") as n:
        n.write(bencoder.encode(d))  # 写入文件
    print('共', len(d[b'announce-list']), '个trackers.')
예제 #7
0
파일: cirque.py 프로젝트: SlashRoot/cirque
    def get_cookie(self, txid=None):
        if not txid:
            txid = random_string()

        request = {'q': 'cookie', 'txid': txid}
        self.transport.write(bencoder.encode(request), (self.host, self.port))
        return txid
예제 #8
0
 def ping(self):
     """
     Pings the CJDNS Admin API for this node, ensuring it is up.
     If no pong is received within 1 second, try again.
     """
     ping = bencoder.encode(self.actions["ping"])
     reactor.callLater(1, self.check_ponged)
     self.transport.write(ping, (self.host, self.port))
예제 #9
0
 def ping(self):
     '''
     Pings the CJDNS Admin API for this node, ensuring it is up.
     If no pong is received within 1 second, try again.
     '''
     ping = bencoder.encode(self.actions['ping'])
     reactor.callLater(1, self.check_ponged)
     self.transport.write(ping, (self.host, self.port))
예제 #10
0
    def ask_for_functions(self, page):
        availableFunctions = {}

        request_dict = {
            'q': 'Admin_availableFunctions',
            'args': {
                'page': page
            }
        }
        self.transport.write(bencoder.encode(request_dict),
                             (self.host, self.port))
예제 #11
0
 def _send_error(self, code, msg, ip, port):
     transaction_id = self._generate_transaction_id()
     if isinstance(msg, str):
         msg = msg.encode('utf-8')
     payload = {
         b't': b'E' + transaction_id,
         b'y': b'e',
         b'e': [code, msg],
     }
     self.transport.sendto(bencoder.encode(payload), (ip, port))
     return transaction_id
예제 #12
0
    def request_cookie(self):
        """
        Obtain a cookie
        """
        txid = random_string()
        request = {"q": "cookie", "txid": txid}
        self.send(bencoder.encode(request))

        if SUPER_VERBOSE:
            print "requested cookie for to run %s as %s" % (self.function_name, txid)

        return txid
예제 #13
0
    def send_krpc(self, msg, address):
        """
        发送 krpc 协议

        :param msg: 发送 UDP 报文信息
        :param address: 发送地址,(ip, port) 元组
        """
        try:
            # msg 要经过 bencode 编码
            self.udp.sendto(bencoder.encode(msg), address)
        except:
            pass
예제 #14
0
 def _send_ping(self, ip, port):
     transaction_id = self._generate_transaction_id()
     payload = {
         b't': transaction_id,
         b'y': b'q',
         b'q': b'ping',
         b'a': {
             b'id': self.packed_id
         },
     }
     self.transport.sendto(bencoder.encode(payload), (ip, port))
     return transaction_id
예제 #15
0
    def feed_datagram(self, data, addr):
        """called when received a UDP datagram"""
        ip, port = addr

        try:
            msg = bencoder.decode(data)
        except:
            raise BadDHTMessageError('not properly bencoded')

        try:
            transaction_id = msg[b't']
            message_type = msg[b'y']
        except KeyError:
            raise BadDHTMessageError('bad dict')

        if message_type == b'q':  # received a query
            query_type = msg.get(b'q')
            arg = msg.get(b'a')
            if not query_type or not arg:
                raise BadDHTMessageError('bad query')
            method = self._query_handler_method_map.get(query_type)
            if not method:
                raise BadDHTMessageError('unknown query type')
            response = method(arg, ip, port)
            if not response:
                return
            payload = {
                b't': transaction_id,
                b'y': b'r',
                b'r': response,
            }
            self.transport.sendto(bencoder.encode(payload), addr)

            remote_id = arg.get(b'id')
            if remote_id is not None:
                self._update_kbucket(decode_id(remote_id), ip, port)
        elif message_type == b'r':  # received a response
            arg = msg.get(b'r')
            if not arg:
                raise BadDHTMessageError('bad response')
            future_key = (ip, port, transaction_id)
            future = self._query_future_map.get(future_key)
            if not future:
                raise BadDHTMessageError('response without query')
            del self._query_future_map[future_key]
            future.set_result(arg)

            remote_id = arg.get(b'id')
            if remote_id is not None:
                self._update_kbucket(decode_id(remote_id), ip, port)
        else:
            raise BadDHTMessageError('unknown message type')
예제 #16
0
    def request_cookie(self):
        '''
        Obtain a cookie
        '''
        txid = random_string()
        request = {'q': 'cookie', 'txid': txid}
        self.send(bencoder.encode(request))

        if SUPER_VERBOSE:
            print "requested cookie for to run %s as %s" % (self.function_name,
                                                            txid)

        return txid
예제 #17
0
 def _send_get_peers(self, info_hash, ip, port):
     transaction_id = self._generate_transaction_id()
     payload = {
         b't': transaction_id,
         b'y': b'q',
         b'q': b'get_peers',
         b'a': {
             b'id': self.packed_id,
             b'info_hash': encode_id(info_hash),
         },
     }
     self.transport.sendto(bencoder.encode(payload), (ip, port))
     return transaction_id
예제 #18
0
 def _send_find_node(self, id, ip, port):
     transaction_id = self._generate_transaction_id()
     payload = {
         b't': transaction_id,
         b'y': b'q',
         b'q': b'find_node',
         b'a': {
             b'id': self.packed_id,
             b'target': encode_id(id),
         },
     }
     self.transport.sendto(bencoder.encode(payload), (ip, port))
     return transaction_id
예제 #19
0
    async def _add_torrent_url(self, url, options):
        async with self.core.session.get(url) as response:
            body = await response.read()

        parsed_body = bencoder.decode(body)
        info_hash = hashlib.sha1(bencoder.encode(
            parsed_body[b'info'])).hexdigest()

        await self._client.call_remote(
            'core.add_torrent_file',
            parsed_body[b'info'][b'name'] + b'.torrent',
            base64.b64encode(body),
            options,
        )
        return info_hash
예제 #20
0
파일: cirque.py 프로젝트: SlashRoot/cirque
    def call_function(self, cookie, function_name, call_args, txid=None, password=None):
        if not password:
            password=self.password

        if not txid:
            txid = random_string()

        pass_hash = hashlib.sha256(password + cookie).hexdigest()

        req = {
            'q': 'auth',
            'aq': function_name,
            'hash': pass_hash,
            'cookie': cookie,
            'args': call_args,
            'txid': txid
        }
        first_time_benc_req = bencoder.encode(req)
        req['hash'] = hashlib.sha256(first_time_benc_req).hexdigest()
        second_time_benc_req = bencoder.encode(req)

        if SUPER_VERBOSE:
            print "Calling function: %s" % req
        self.transport.write(second_time_benc_req, (self.host, self.port))
예제 #21
0
def parse_torrent_input(torrent, walk=True, recursive=False):
    # torrent is literal infohash
    if re.match(r'^[\da-fA-F]{40}$', torrent):
        return {'hash': torrent}
    # torrent is literal id
    if re.match(r'^\d+$', torrent):
        return {'id': torrent}
    # torrent is valid path
    if os.path.exists(torrent):
        if walk and os.path.isdir(torrent):
            for path in map(lambda x: os.path.join(torrent, x),
                            os.listdir(torrent)):
                handle_input_torrent(path, recursive, recursive)
            return 'walked'
        # If file/dir name is info hash use that
        filename = os.path.split(torrent)[-1].split('.')[0]
        if re.match(r'^[\da-fA-F]{40}$', filename):
            return {'hash': filename}
        # If torrent file compute the info hash
        if not args.no_hash and os.path.isfile(torrent) and os.path.split(
                torrent)[-1].endswith('.torrent'):
            global encode, decode
            if 'encode' not in globals() or 'decode' not in globals():
                try:
                    from bencoder import encode, decode
                except:
                    print(
                        'Found torrent file ' + torrent +
                        ' but unable to load bencoder module to compute hash')
                    print(
                        'Install bencoder (pip install bencoder) then try again or pass --no-hash to not compute the hash'
                    )
                    if args.ignore_invalid:
                        return None
                    else:
                        sys.exit(EXIT_CODES['input-error'])
            with open(torrent, 'rb') as torrent:
                try:
                    decoded = decode(torrent.read())
                    info_hash = sha1(encode(decoded[b'info'])).hexdigest()
                except:
                    return None
                return {'hash': info_hash}
    # torrent is a URL
    url_match = re.match(r'.*torrentid=(\d+).*', torrent)
    if not url_match or url_match.lastindex < 1:
        return None
    return {'id': url_match[1]}
예제 #22
0
 def _send_announce_peer(self, info_hash, token, ip, port, downloader_port):
     transaction_id = self._generate_transaction_id()
     payload = {
         b't': transaction_id,
         b'y': b'q',
         b'q': b'announce_peer',
         b'a': {
             b'id': self.packed_id,
             b'info_hash': encode_id(info_hash),
             b'token': token,
             b'port': downloader_port,
             b'implied_port': ANNOUNCE_IMPLIED_PORT,
         },
     }
     self.transport.sendto(bencoder.encode(payload), (ip, port))
     return transaction_id
예제 #23
0
    def __init__(self, file_name):

        self.file_name = file_name
        self.peerID = self.construct_peer_id()
        self.downloaded = 0
        self.uploaded = 0
        self.compact = 1
        # TODO: proper handling of port. From 6881-6889 check every port if it is open and pick the first one
        self.port = 6882
        # self.event = 'started'

        if file_name.endswith('torrent'):
            file = open(file_name, 'rb')
            self.torrent_data = bencoder.decode(file.read())
            self.info = self.torrent_data[b'info']
            self.hash_info = hashlib.sha1(bencoder.encode(self.info)).digest()

            self.creation_date = self.torrent_data[b'creation date']
            self.announce_list = list()

            if b'announce_list' in self.torrent_data.keys():
                self.announce_list = self.torrent_data[b'announce-list']
            elif b'httpseeds' in self.torrent_data.keys():
                self.announce_list = self.torrent_data[b'httpseeds']

            self.announce_list.append(self.torrent_data[b'announce'])

            if b'files' in self.info.keys():
                self.files = self.info[b'files']
            else:
                # In case we have only one file we change it to a similar format as multi file torrent
                self.files = list()
                file_data = dict()
                file_data[b'length'] = self.info[b'length']
                file_data[b'path'] = list()
                file_data[b'path'].append(self.info[b'name'])
                self.files.append(file_data)

            self.total_length = self.get_total_length()

        elif file_name.startswith('magnet'):
            self.torrent_data = self.magnet_to_torrent(file_name)
            self.hash_info = self.torrent_data[b'info'][b'hash_info']
            self.announce_list = self.torrent_data[b'announce-list']
            self.announce_list.append(self.torrent_data[b'announce'])
예제 #24
0
 def __init__(self, path_to_torrent, peer_id):
     # Set id
     self.peer_id = peer_id
     
     # Read torrent file
     with open(path_to_torrent, 'rb') as torrent_file:
         torrent_contents = torrent_file.read()
     
     # Decode torrent file
     self.metainfo = decode(torrent_contents)
     
     # Get info dictionary
     self.info_dict = self.metainfo[b'info']
     
     # Create SHA1 hash of info dictionary
     hash_sha1 = hashlib.sha1()
     hash_sha1.update(encode(self.info_dict))
     self.info_hash = hash_sha1.digest()
     
     # Get announce url
     self.announce_url = self.metainfo[b'announce']
     
     # Get pieces and pieces length 
     self.piece_length = self.info_dict[b'piece length']
     self.pieces = self.info_dict[b'pieces']
     
     # Get name of the torrent
     self.torrent_name = self.info_dict[b'name']
     
     # Get the length of the torrent and determine if it's a multi file torrent
     if b"files" in self.info_dict.keys():
         total_length = 0
         for i in self.info_dict[b'files']:
             total_length += i[b'length']
         self.torrent_length = total_length
         self.is_multi_files = True
     else:
         self.torrent_length = self.info_dict[b'length']
         self.is_multi_files = False
         
     # get paths for each file if its a multi file torrent
     if self.is_multi_files:
         self.file_paths = []
         for i in self.info_dict[b'files']:
             self.file_paths.append([i[b'path'], i[b'length']])
예제 #25
0
 def __init__(self, file_name):
     # Text
     self._bencoded_text = read_binary_file(file_name)
     self._parsed_text = bencoder.decode(self._bencoded_text)[0]
     self._parsed_info_hash = self._parsed_text['info']
     self.bencoded_info_hash = bencoder.encode(self._parsed_info_hash) # turn into readonly property
     
     # File information
     self.file_info_dict = self._get_file_info_dict()
     self.base_file_name = self._parsed_info_hash['name']
     self.type = "single" if len(self.file_info_dict.keys()) == 1 else "multiple"
     
     # Length and piece information
     self.total_length = self._get_total_length()
     self.piece_length = self._parsed_info_hash['piece length']
     self.num_pieces = int(len(self._parsed_info_hash['pieces']) / 20)
     self.request_blocks_per_piece = int(math.ceil( float(self.piece_length) / 2**14))
     self.pieces_hash = self._parsed_info_hash['pieces']
예제 #26
0
    def get_download_info(cls, dictionary):
        info_hash = hashlib.sha1(bencoder.encode(dictionary)).digest()

        if len(dictionary[b'pieces']) % SHA1_DIGEST_LEN != 0:
            raise ValueError('Invalid length of "pieces" string')
        piece_hashes = grouper(dictionary[b'pieces'], SHA1_DIGEST_LEN)

        if b'files' in dictionary:
            files = list(map(FileInfo.get_info, dictionary[b'files']))
        else:
            files = [FileInfo.get_info(dictionary)]

        return cls(info_hash,
                   dictionary[b'piece length'],
                   piece_hashes,
                   dictionary[b'name'].decode(),
                   files,
                   private=dictionary.get('private', False))
예제 #27
0
    def getinfo(self, filename):
        fp = open(filename, "rb")
        data = fp.read()  #it is string
        #print data
        decode_data = bencoder.decode(data)  #get a dictionary
        #print(decode_data)
        if 'announce' in decode_data and 'info' in decode_data:
            self.tracker = decode_data.get('announce')
            self.tracker_list = decode_data.get('announce-list')
            self.create = decode_data.get('created by')
            self.date = decode_data.get('creation date')
            self.source = decode_data.get('comment')
            info = decode_data.get('info')
            self.piece_size = info.get('piece length')
            self.pieces = info.get('pieces')
        else:
            #print("Invalid torrent file")
            pass
        if 'length' in info:
            self.directory = ''
            self.files = [(info.get('name'), info.get('length'))]
            self.size = info.get('length')
            self.name = info.get('name')
        else:
            files = []
            self.directory = info.get('name')
            for d in decode_data['info']['files']:
                files.append((d['path'], d['length']))
                self.size += d['length']

        if self.size % self.piece_size != 0:
            extra = 1
#			print 'extra 1'
        else:
            extra = 0


#			print 'extra 2'

        self.no_of_pieces = self.size / self.piece_size + extra
        #		print self.no_of_pieces
        sha1 = hashlib.sha1()
        sha1.update(bencoder.encode(info))
        self.hash_info = sha1.digest()
예제 #28
0
    def __init__(self, file_name):
        # Text
        self._bencoded_text = message.read_binary_file(file_name)
        self._parsed_text = bencoder.decode(self._bencoded_text)[0]
        self._parsed_info_hash = self._parsed_text['info']
        self.bencoded_info_hash = bencoder.encode(
            self._parsed_info_hash)  # turn into readonly property

        # File information
        self.file_info_dict = self._get_file_info_dict()
        self.base_file_name = self._parsed_info_hash['name']
        self.type = "single" if len(
            self.file_info_dict.keys()) == 1 else "multiple"

        # Length and piece information
        self.total_length = self._get_total_length()
        self.piece_length = self._parsed_info_hash['piece length']
        self.num_pieces = int(len(self._parsed_info_hash['pieces']) / 20)
        self.request_blocks_per_piece = int(
            math.ceil(float(self.piece_length) / POLITE_REQUEST_SIZE))
        self.pieces_hash = self._parsed_info_hash['pieces']
 def test_it_encodes_dicts_w_nums_and_lists(self):
     encoded_dict = bencoder.encode(OrderedDict([('length', 291), ('path', ['Distributed by Mininova.txt'])]))
     self.assertEqual(encoded_dict, self.dict_w_nums_and_lists)
예제 #30
0
 def test_it_encodes_nested_lists(self):
     encoded_list = bencoder.encode([['spam', 'eggs'], ['spam', 'eggs']])
     self.assertEqual(encoded_list, self.b_nested_list)
예제 #31
0
 def test_it_encodes_single_item_lists(self):
     encoded_list = bencoder.encode(['Distributed by Mininova.txt'])
     self.assertEqual(encoded_list, self.b_single_word_list)
예제 #32
0
 def test_reversing_walden(self):
     t = metainfo.MetainfoFile(self.walden)
     encoded_torrent = bencoder.encode(t._parsed_text)
     self.assertEqual(t.bencoded_text, encoded_torrent)
 def test_reversing_comic(self):
     t = metainfo.MetainfoFile(self.comics)
     encoded_torrent = bencoder.encode(t._parsed_text)
     self.assertEqual(t._bencoded_text, encoded_torrent)
예제 #34
0
    def ask_for_functions(self, page):
        availableFunctions = {}

        request_dict = {"q": "Admin_availableFunctions", "args": {"page": page}}
        self.transport.write(bencoder.encode(request_dict), (self.host, self.port))
예제 #35
0
파일: cirque.py 프로젝트: SlashRoot/cirque
    def ask_for_functions(self, page):
        availableFunctions = {}

        request_dict = {'q': 'Admin_availableFunctions', 'args': {'page': page}}
        self.transport.write(bencoder.encode(request_dict), (self.host, self.port))
예제 #36
0
 def test_it_encodes_a_dict_with_list_values(self):
     encoded_dict = bencoder.encode(OrderedDict([('spam', ['a', 'b']), ('eggs', ['a', 'b'])]))
     self.assertEqual(encoded_dict, self.dict_w_lists)
예제 #37
0
 def test_it_encodes_a_bigger_dict(self):
     encoded_dict = bencoder.encode(OrderedDict([('publisher', 'bob'), ('publisher-webpage', 'www.example.com'), ('publisher.location', 'home')]))
     self.assertEqual(encoded_dict, self.bigger_b_dict)
예제 #38
0
 def test_it_decodes_a_dict_of_strings(self):
     encoded_dict = bencoder.encode(OrderedDict([('cow', 'moo'), ('spam', 'eggs')]))
     self.assertEqual(encoded_dict, self.little_b_dict)
예제 #39
0
def _infohash(metadata):
    sha1 = hashlib.sha1()
    info = bencoder.encode(metadata[b'info'])
    sha1.update(info)
    return sha1.hexdigest()
 def test_it_encodes_nested_lists(self):
     encoded_list = bencoder.encode([['spam', 'eggs'], ['spam', 'eggs']])
     self.assertEqual(encoded_list, self.b_nested_list)
 def test_it_encodes_single_item_lists(self):
     encoded_list = bencoder.encode(['Distributed by Mininova.txt'])
     self.assertEqual(encoded_list, self.b_single_word_list)
 def test_reversing_walden(self):
     t = metainfo.MetainfoFile(self.walden)
     encoded_torrent = bencoder.encode(t._parsed_text)
     self.assertEqual(t._bencoded_text, encoded_torrent)
예제 #43
0
 def test_encoding_dictionary(self):
     expected = b'd2:doli1e1:ce3:how2:do3:youi42ee'
     result = encode({b'how': b'do', b'you': 42, b'do': [1, b'c']})
     self.assertEqual(expected, result)
예제 #44
0
파일: cirque.py 프로젝트: SlashRoot/cirque
 def ping(self):
     print "Pinging."
     ping = bencoder.encode(self.actions['ping'])
     reactor.callLater(1, self.check_ponged)
     self.transport.write(ping, (self.host, self.port))
예제 #45
0
 def test_it_encodes_dicts_w_some_numbers(self):
     encoded_dict = bencoder.encode(OrderedDict([('bar', 'spam'), ('foo', 42)]))
     self.assertEqual(encoded_dict, self.dict_w_nums)
예제 #46
0
 def get_info_hash(self):
     info = encode(self.torrent_file_dict[b'info'])
     return hashlib.sha1(info).digest()
예제 #47
0
 def test_it_encodes_dicts_w_nums_and_lists(self):
     encoded_dict = bencoder.encode(OrderedDict([('length', 291), ('path', ['Distributed by Mininova.txt'])]))
     self.assertEqual(encoded_dict, self.dict_w_nums_and_lists)
예제 #48
0
 def test_it_encodes_actual_bittorrent_files(self):
     decoded_dict = bencoder.decode(self.metainfo_file)[0]
     encoded_file = bencoder.encode(decoded_dict)
     self.assertEqual(self.metainfo_file, encoded_file)
 def test_it_encodes_actual_bittorrent_files(self):
     decoded_dict = bencoder.decode(self.metainfo_file)[0]
     encoded_file = bencoder.encode(decoded_dict)
     self.assertEqual(self.metainfo_file, encoded_file)
예제 #50
0
 def test_encoding_list(self):
     expected = b'li1eli2eli3eeee'
     result = encode([1, [2, [3]]])
     self.assertEqual(expected, result)
 def test_it_encodes_dicts_w_some_numbers(self):
     encoded_dict = bencoder.encode(OrderedDict([('bar', 'spam'), ('foo', 42)]))
     self.assertEqual(encoded_dict, self.dict_w_nums)