Beispiel #1
0
    def _decode_introduction_request(self, placeholder, offset, data):
        offset, payload = BinaryConversion._decode_introduction_request(
            self, placeholder, offset, data)

        #if there's still bytes in this request, treat them as taste_bloom_filter
        has_taste = len(data) > offset
        if has_taste:
            if len(data) < offset + 8:
                raise DropPacket("Insufficient packet size")

            num_preferences, functions, size = unpack_from(
                '!IBH', data, offset)
            offset += 7

            prefix = data[offset]
            offset += 1

            if not 0 < num_preferences:
                raise DropPacket("Invalid num_preferences value")
            if not 0 < functions:
                raise DropPacket("Invalid functions value")
            if not 0 < size:
                raise DropPacket("Invalid size value")
            if not size % 8 == 0:
                raise DropPacket(
                    "Invalid size value, must be a multiple of eight")

            length = int(ceil(size / 8))
            if not length == len(data) - offset:
                raise DropPacket(
                    "Invalid number of bytes available (irq) %d, %d, %d" %
                    (length, len(data) - offset, size))

            taste_bloom_filter = BloomFilter(data[offset:offset + length],
                                             functions,
                                             prefix=prefix)
            offset += length

            payload.set_num_preferences(num_preferences)
            payload.set_taste_bloom_filter(taste_bloom_filter)

        return offset, payload
Beispiel #2
0
    def _decode_search_response(self, placeholder, offset, data):
        try:
            offset, payload = decode(data, offset)
        except (ValueError, KeyError):
            raise DropPacket("Unable to decode the search-reponse-payload")

        if len(payload) < 2:
            raise DropPacket("Invalid payload length")

        identifier, results = payload[:2]

        if len(identifier) != 2:
            raise DropPacket(
                "Unable to decode the search-response-payload, got %d bytes expected 2"
                % (len(identifier)))
        identifier, = unpack_from('!H', identifier)

        if not isinstance(results, list):
            raise DropPacket("Invalid 'results' type")

        for result in results:
            if not isinstance(result, tuple):
                raise DropPacket("Invalid result type")

            if len(result) < 9:
                raise DropPacket("Invalid result length")

            infohash, swarmname, length, nrfiles, category_list, creation_date, seeders, leechers, cid = result[:
                                                                                                                9]

            if not isinstance(infohash, str):
                raise DropPacket("Invalid infohash type")
            if len(infohash) != 20:
                raise DropPacket("Invalid infohash length")

            if not isinstance(swarmname, unicode):
                raise DropPacket("Invalid swarmname type")

            if not isinstance(length, long):
                raise DropPacket("Invalid length type '%s'" % type(length))

            if not isinstance(nrfiles, int):
                raise DropPacket("Invalid nrfiles type")

            if not isinstance(category_list, list) or not all(
                    isinstance(key, unicode) for key in category_list):
                raise DropPacket("Invalid category_list type")

            if not isinstance(creation_date, long):
                raise DropPacket("Invalid creation_date type")

            if not isinstance(seeders, int):
                raise DropPacket("Invalid seeders type '%s'" % type(seeders))

            if not isinstance(leechers, int):
                raise DropPacket("Invalid leechers type '%s'" % type(leechers))

            if cid:
                if not isinstance(cid, str):
                    raise DropPacket("Invalid cid type")

                if len(cid) != 20:
                    raise DropPacket("Invalid cid length")

        return offset, placeholder.meta.payload.implement(identifier, results)
Beispiel #3
0
    def _decode_search_request(self, placeholder, offset, data):
        try:
            offset, payload = decode(data, offset)
        except ValueError:
            raise DropPacket("Unable to decodr 21, 2012 e the search-payload")

        if len(payload) < 2:
            raise DropPacket("Invalid payload length")

        identifier, keywords = payload[:2]

        if len(identifier) != 2:
            raise DropPacket(
                "Unable to decode the search-payload, got %d bytes expected 2"
                % (len(identifier)))
        identifier, = unpack_from('!H', identifier)

        if not isinstance(keywords, list):
            raise DropPacket("Invalid 'keywords' type")
        for keyword in keywords:
            if not isinstance(keyword, unicode):
                raise DropPacket("Invalid 'keyword' type")

        if len(payload) > 5:
            functions, prefix, bytes_ = payload[2:6]

            if not isinstance(functions, int):
                raise DropPacket("Invalid functions type")
            if not 0 < functions:
                raise DropPacket("Invalid functions value")

            size = len(bytes_)
            if not 0 < size:
                raise DropPacket("Invalid size of bloomfilter")
            if not size % 8 == 0:
                raise DropPacket(
                    "Invalid size of bloomfilter, must be a multiple of eight")

            if not isinstance(prefix, str):
                raise DropPacket("Invalid prefix type")
            if not 0 <= len(prefix) < 256:
                raise DropPacket("Invalid prefix length")

            bloom_filter = BloomFilter(bytes_, functions, prefix=prefix)
        else:
            bloom_filter = None

        return offset, placeholder.meta.payload.implement(
            identifier, keywords, bloom_filter)
Beispiel #4
0
    def _decode_modification(self, placeholder, offset, data):
        try:
            offset, dic = decode(data, offset)
        except ValueError:
            raise DropPacket("Unable to decode the payload")

        if not "modification-type" in dic:
            raise DropPacket("Missing 'modification-type'")
        modification_type = dic["modification-type"]
        if not isinstance(modification_type, unicode):
            raise DropPacket("Invalid 'modification_type' type")

        if not "modification-value" in dic:
            raise DropPacket("Missing 'modification-value'")
        modification_value = dic["modification-value"]
        if not (isinstance(modification_value, unicode)
                and len(modification_value) < 1024):
            raise DropPacket("Invalid 'modification_value' type or value")

        if not "timestamp" in dic:
            raise DropPacket("Missing 'timestamp'")
        timestamp = dic["timestamp"]
        if not isinstance(timestamp, (int, long)):
            raise DropPacket("Invalid 'timestamp' type or value")

        if not "modification-on-mid" in dic:
            raise DropPacket("Missing 'modification-on-mid'")
        modification_on_mid = dic["modification-on-mid"]
        if not (isinstance(modification_on_mid, str)
                and len(modification_on_mid) == 20):
            raise DropPacket("Invalid 'modification-on-mid' type or value")

        if not "modification-on-global-time" in dic:
            raise DropPacket("Missing 'modification-on-global-time'")
        modification_on_global_time = dic["modification-on-global-time"]
        if not isinstance(modification_on_global_time, (int, long)):
            raise DropPacket("Invalid 'modification-on-global-time' type")

        try:
            packet_id, packet, message_name = self._get_message(
                modification_on_global_time, modification_on_mid)
            modification_on = Packet(
                self._community.get_meta_message(message_name), packet,
                packet_id)
        except DropPacket:
            member = self._community.get_member(mid=modification_on_mid)
            if not member:
                raise DelayPacketByMissingMember(self._community,
                                                 modification_on_mid)
            raise DelayPacketByMissingMessage(self._community, member,
                                              modification_on_global_time)

        prev_modification_mid = dic.get("prev-modification-mid", None)
        if prev_modification_mid and not (
                isinstance(prev_modification_mid, str)
                and len(prev_modification_mid) == 20):
            raise DropPacket("Invalid 'prev-modification-mid' type or value")

        prev_modification_global_time = dic.get(
            "prev-modification-global-time", None)
        if prev_modification_global_time and not isinstance(
                prev_modification_global_time, (int, long)):
            raise DropPacket("Invalid 'prev-modification-global-time' type")

        try:
            packet_id, packet, message_name = self._get_message(
                prev_modification_global_time, prev_modification_mid)
            prev_modification_packet = Packet(
                self._community.get_meta_message(message_name), packet,
                packet_id)
        except:
            prev_modification_packet = None

        return offset, placeholder.meta.payload.implement(
            modification_type, modification_value, timestamp, modification_on,
            prev_modification_packet, prev_modification_mid,
            prev_modification_global_time)
Beispiel #5
0
    def _decode_comment(self, placeholder, offset, data):
        try:
            offset, dic = decode(data, offset)
        except ValueError:
            raise DropPacket("Unable to decode the payload")

        if not "text" in dic:
            raise DropPacket("Missing 'text'")
        text = dic["text"]
        if not (isinstance(text, unicode) and len(text) < 1024):
            raise DropPacket("Invalid 'text' type or value")

        if not "timestamp" in dic:
            raise DropPacket("Missing 'timestamp'")
        timestamp = dic["timestamp"]
        if not isinstance(timestamp, (int, long)):
            raise DropPacket("Invalid 'timestamp' type or value")

        reply_to_mid = dic.get("reply-to-mid", None)
        if reply_to_mid and not (isinstance(reply_to_mid, str)
                                 and len(reply_to_mid) == 20):
            raise DropPacket("Invalid 'reply-to-mid' type or value")

        reply_to_global_time = dic.get("reply-to-global-time", None)
        if reply_to_global_time and not isinstance(reply_to_global_time,
                                                   (int, long)):
            raise DropPacket("Invalid 'reply-to-global-time' type")

        reply_after_mid = dic.get("reply-after-mid", None)
        if reply_after_mid and not (isinstance(reply_after_mid, str)
                                    and len(reply_after_mid) == 20):
            raise DropPacket("Invalid 'reply-after-mid' type or value")

        reply_after_global_time = dic.get("reply-after-global-time", None)
        if reply_after_global_time and not isinstance(reply_after_global_time,
                                                      (int, long)):
            raise DropPacket("Invalid 'reply-after-global-time' type")

        playlist_mid = dic.get("playlist-mid", None)
        if playlist_mid and not (isinstance(playlist_mid, str)
                                 and len(playlist_mid) == 20):
            raise DropPacket("Invalid 'playlist-mid' type or value")

        playlist_global_time = dic.get("playlist-global-time", None)
        if playlist_global_time and not isinstance(playlist_global_time,
                                                   (int, long)):
            raise DropPacket("Invalid 'playlist-global-time' type")

        if playlist_mid and playlist_global_time:
            try:
                packet_id, packet, message_name = self._get_message(
                    playlist_global_time, playlist_mid)
                playlist = Packet(
                    self._community.get_meta_message(message_name), packet,
                    packet_id)
            except DropPacket:
                member = self._community.get_member(mid=playlist_mid)
                if not member:
                    raise DelayPacketByMissingMember(self._community,
                                                     playlist_mid)
                raise DelayPacketByMissingMessage(self._community, member,
                                                  playlist_global_time)
        else:
            playlist = None

        infohash = dic.get("infohash", None)
        if infohash and not (isinstance(infohash, str)
                             and len(infohash) == 20):
            raise DropPacket("Invalid 'infohash' type or value")
        return offset, placeholder.meta.payload.implement(
            text, timestamp, reply_to_mid, reply_to_global_time,
            reply_after_mid, reply_after_global_time, playlist, infohash)
Beispiel #6
0
    def _decode_torrent(self, placeholder, offset, data):
        try:
            uncompressed_data = zlib.decompress(data[offset:])
        except zlib.error:
            raise DropPacket("Invalid zlib data")
        offset = len(data)

        try:
            _, values = decode(uncompressed_data)
        except ValueError:
            raise DropPacket("Unable to decode the torrent-payload")

        infohash_time, name, files, trackers = values
        if len(infohash_time) != 28:
            raise DropPacket(
                "Unable to decode the torrent-payload, got %d bytes expected 28"
                % (len(infohash_time)))
        infohash, timestamp = unpack_from('!20sQ', infohash_time)

        if not isinstance(name, unicode):
            raise DropPacket("Invalid 'name' type")

        if not isinstance(files, tuple):
            raise DropPacket("Invalid 'files' type")

        if len(files) == 0:
            raise DropPacket("Should have at least one file")

        for file in files:
            if len(file) != 2:
                raise DropPacket("Invalid 'file_len' type")

            path, length = file
            if not isinstance(path, unicode):
                raise DropPacket("Invalid 'files_path' type is %s" %
                                 type(path))
            if not isinstance(length, (int, long)):
                raise DropPacket("Invalid 'files_length' type is %s" %
                                 type(length))

        if not isinstance(trackers, tuple):
            raise DropPacket("Invalid 'trackers' type")
        for tracker in trackers:
            if not isinstance(tracker, str):
                raise DropPacket("Invalid 'tracker' type")

        return offset, placeholder.meta.payload.implement(
            infohash, timestamp, name, files, trackers)