Example #1
0
 def __init__(self):
     self.protocol_header = b'\x00'
     self.message_format = Struct(
         "fields" / RawCopy(
             Struct("NetworkID" / Bytes(32), "DeviceID" / Int8sb,
                    "Sequence" / Int16ub, "Payload_length" / Byte,
                    "Payload" / Bytes(this.Payload_length))),
         "checksum" /
         Checksum(Bytes(4), lambda data: hashlib.sha256(data).digest()[0:4],
                  this.fields.data),
     )
Example #2
0
            decrypted = decrypted.rstrip(b"\x00")
        except Exception as ex:
            _LOGGER.debug("Unable to decrypt, returning raw bytes.")
            return obj

        try:
            jsoned = json.loads(decrypted.decode('utf-8'))
        except:
            _LOGGER.error("unable to parse json, was: %s", decrypted)
            jsoned = b'{}'
            raise

        return jsoned


Message = Struct(
    # for building we need data before anything else.
    "data" / Pointer(32, RawCopy(EncryptionAdapter(GreedyBytes))),
    "header" / RawCopy(
        Struct(
            Const(Int16ub,
                  0x2131), "length" / Rebuild(Int16ub, Utils.get_length),
            "unknown" / Default(Int32ub, 0x00000000), "devtype" /
            Enum(Default(Int16ub, 0x02c1), default=Pass, **xiaomi_devices),
            "serial" / Default(Int16ub, 0xa40d),
            "ts" / TimeAdapter(Default(Int32ub, datetime.datetime.utcnow())))),
    "checksum" /
    IfThenElse(Utils.is_hello, Bytes(16),
               Checksum(Bytes(16), Utils.md5, Utils.checksum_field_bytes)),
)
Example #3
0
RequestedEvent = Struct(
    "fields" / RawCopy(
        Struct(
            "po" / BitStruct(
                "command" / Const(0xE, Nibble), "status" /
                Struct("reserved" / Flag, "alarm_reporting_pending" / Flag,
                       "Winload_connected" / Flag, "NeWare_connected" / Flag)),
            "length" / PacketLength(Int8ub),
            "_not_used0" / Bytes(1),
            "requested_event_nr" / Const(0x00, Int8ub),
            "event_nr" / Int16ub,
            # "data" / Bytes(lambda this: this.length - 7)
            "data" / Array(lambda x: int(
                (x.length - 7) / 12), CompressedEvent))),
    "checksum" / Checksum(Bytes(1), lambda data: calculate_checksum(data),
                          this.fields.data))

CloseConnection = Struct(
    "fields" / RawCopy(
        Struct(
            "po" / Struct("command" / Const(0x70, Int8ub)),
            "length" / PacketLength(Int8ub),
            "message" / Default(
                Enum(Int8ub,
                     requested_command_failed=0x00,
                     invalid_user_code=0x01,
                     partition_in_code_lockout=0x02,
                     panel_will_disconnect=0x05,
                     panel_not_connected=0x10,
                     panel_already_connected=0x11,
                     invalid_pc_password=0x12,
Example #4
0
        hashlib.sha256).digest()


# -------------------- Payload Decryption/Decompression --------------------
# encrypted payload is split into multiple data blocks with hashes
EncryptedPayloadBlock = Struct(
    "hmac_hash_offset" / Tell,
    Padding(32),
    "block_data" / Prefixed(Int32ul, GreedyBytes),
    # hmac_hash has to be at the end with a pointer because it needs to
    # come after other fields
    "hmac_hash" / Pointer(
        this.hmac_hash_offset,
        Checksum(
            Bytes(32),
            compute_payload_block_hash,
            this,
            # exception=PayloadChecksumError
        )))

EncryptedPayload = Concatenated(
    RepeatUntil(lambda item, a, b: len(item.block_data) == 0,
                EncryptedPayloadBlock))

DecryptedPayload = Switch(
    this._.header.value.dynamic_header.cipher_id.data, {
        'aes256': AES256Payload(EncryptedPayload),
        'chacha20': ChaCha20Payload(EncryptedPayload),
        'twofish': TwoFishPayload(EncryptedPayload)
    })

InnerHeaderItem = Struct(
Example #5
0
            'compression_flags': CompressionFlags,
            'cipher_id': CipherId,
            'transform_rounds': Int32ul,
            'protected_stream_id': ProtectedStreamId
        },
               default=GreedyBytes)),
)

DynamicHeader = DynamicDict(
    'id', RepeatUntil(lambda item, a, b: item.id == 'end', DynamicHeaderItem))

# -------------------- Payload Verification --------------------

# encrypted payload is split into multiple data blocks with hashes
PayloadBlock = Struct(
    "block_index" / Checksum(Int32ul, lambda this: this._index, this),
    "block_hash_offset" / Tell,
    Padding(32),
    "block_data" / Prefixed(Int32ul, GreedyBytes),
    # block_hash has to be at the end with a pointer because it needs to
    # come after other fields
    "block_hash" / Pointer(
        this.block_hash_offset,
        IfThenElse(
            len_(this.block_data) == 0,
            Checksum(Bytes(32), lambda _: b'\x00' * 32, this),
            Checksum(
                Bytes(32),
                lambda block_data: hashlib.sha256(block_data).digest(),
                this.block_data,
                # exception=PayloadChecksumError
Example #6
0
    "random_state" /
    Pointer(this.dir.dir_size + this.dir.offset[2],
            FixedSized(this.dir.uncompr_size[2], GreedyBytes)),

    # 2004
    "bmap_size" / Pointer(
        this.dir.dir_size + this.dir.offset[3],
        Struct(
            "uncompr_size" / Int32ul, "uncompr_size" /
            Computed(this._.dir.uncompr_size[3]), "compr_size" / Int32ul,
            "compr_size" / Computed(this._.dir.compr_size[3] - 12),
            "crc32_offset" / Tell, "crc32" / Int32ul, "data" / FixedSized(
                this.compr_size, Compressed(Bytes(this.uncompr_size),
                                            "blast")), "crc32" /
            Pointer(this.crc32_offset,
                    Checksum(Int32ul, lambda l: crc32(l), this.data)))),

    # 2005
    "bmap_tile" / Pointer(
        this.dir.dir_size + this.dir.offset[4],
        Struct(
            "uncompr_size" / Int32ul, "uncompr_size" /
            Computed(this._.dir.uncompr_size[4]), "compr_size" / Int32ul,
            "compr_size" / Computed(this._.dir.compr_size[4] - 12),
            "crc32_offset" / Tell, "crc32" / Int32ul, "data" / FixedSized(
                this.compr_size, Compressed(GreedyBytes, "blast")), "crc32" /
            Pointer(this.crc32_offset,
                    Checksum(Int32ul, lambda l: crc32(l), this.data)))),

    # 2013
    "tmap" / Pointer(
Example #7
0
    'width' / Int16ul,
    'height' / Int16ul,
    'format' / Const(0x02, Int8ul),
    'palette_entries' / PaletteCountAdapter(Int8ul),
    'palette' / Array(this.palette_entries, struct_blit_pixel),
    'bit_length' / Computed(compute_bit_length),
    'data_length' / Computed(compute_data_length),
    'data' / Array(this.data_length, Int8ul)
)

struct_blit_meta = Struct(
    'header' / Const(b'BLITMETA'),
    'data' / Prefixed(Int16ul, Struct(
        'checksum' / Checksum(
            Int32ul,
            lambda data: binascii.crc32(data),
            this._._.bin.data
        ),
        'date' / PaddedString(16, 'ascii'),
        'title' / PaddedString(25, 'ascii'),
        'description' / PaddedString(129, 'ascii'),
        'version' / PaddedString(17, 'ascii'),
        'author' / PaddedString(17, 'ascii'),
        Const(b'BLITTYPE'),
        'category' / PaddedString(17, 'ascii'),
        'url' / PaddedString(129, 'ascii'),
        'filetypes' / PrefixedArray(Int8ul, PaddedString(5, 'ascii')),
        'icon' / struct_blit_image,
        'splash' / struct_blit_image
    ))
)
Example #8
0
def PacketChecksum(subcons):
    return Checksum(subcons, lambda data: calculate_checksum(data), this.fields.data)
WriteCommand = Struct("address" / Int16ul, "value" / Int16ul)

WriteMessageRequest = Struct(
    "fields" / RawCopy(
        Struct(
            "length" / Rebuild(
                Int16ul,
                len_(this.items) * WriteCommand.sizeof() // Int16ul.sizeof() +
                2,
            ),
            "command" /
            Const(vlxDevConstants.WS_WEB_UI_COMMAND_WRITE_DATA, Int16ul),
            "items" / WriteCommand[len_(this.items)],
        )),
    "checksum" /
    Checksum(Int16ul, lambda data: checksum_16(data), this.fields.data),
)

ReadTableResponse = GreedyRange(Int16ub)

ReadTableRequest = Struct(
    "fields" / RawCopy(
        Struct(
            "length" / Const(3, Int16ul),
            "command" /
            Const(vlxDevConstants.WS_WEB_UI_COMMAND_READ_TABLES, Int16ul),
            "items" / Const(0, Int16ul),
        )),
    "checksum" /
    Checksum(Int16ul, lambda data: checksum_16(data), this.fields.data),
)
Example #10
0
TIME_FORMAT = '%Y-%m-%d;%H:%M'

crc16 = lambda val: '{:04x}'.format(CRCCCITT().calculate(val)).upper()

TabTerminated = CString(terminators=b'\x09', encoding='cp1250')

PosnetParameter = Struct(
    'name' / Select(Const('@'), Const('?'), String(length=2)),
    'value' / TabTerminated)

PosnetFrame = Struct(
    Const(b'\x02'), 'summed' / RawCopy(
        Struct('instruction' / TabTerminated,
               'parameters' / GreedyRange(PosnetParameter))), Const('#'),
    'crc' / Checksum(Bytes(4), crc16, 'summed'), Const('\x03'),
    'instruction' / Computed(this.summed.value.instruction),
    'parameters' / Computed(this.summed.value.parameters))


def build_frame(instruction, *params):
    '''
    Helper for building Posnet protocol frames out of instructions and
    params passed as (name, value) tuples. Can't use **kwargs: Posnet protocol
    uses reserved chars (such as @ and ?)
    '''
    data = Container(summed=Container(
        value=Container(instruction=instruction,
                        parameters=[
                            Container(name=name, value=value)
                            for name, value in params