Exemplo n.º 1
0
def test_unpack_uid():
    assert unpack(b"\xDF\x30\x01\x30\x02\xC1\x01\x03") == ([1, 2, 2], b"")
    assert unpack(b"\xDF\x30\x01\x30\x02\xC2\x01\x00\x03") == ([1, 2, 2], b"")
    assert unpack(b"\xDF\x30\x01\x30\x02\xC3\x01\x00\x00\x03") == ([1, 2,
                                                                    2], b"")
    assert unpack(b"\xDF\x30\x01\x30\x02\xC4\x01\x00\x00\x00\x03") == ([
        1, 2, 2
    ], b"")
Exemplo n.º 2
0
def test_unpack_ptr():
    assert unpack(b"\xD2\x41\x61\xA0") == (["a", "a"], b"")
    assert unpack(b"\xD4\x43\x66\x6F\x6F\x43\x62\x61\x72\xA0\xA1") == (
        ["foo", "bar", "foo", "bar"],
        b"",
    )
    assert unpack(b"\xE3\x41\x61\x41\x62\x41\x63\xE1\x41\x64\xA0\xA3\x01") == (
        {
            "a": "b",
            "c": {
                "d": "a"
            },
            "d": True
        },
        b"",
    )
Exemplo n.º 3
0
    async def _process_buffer(self) -> None:
        _LOGGER.debug("Process buffer (size: %d)", len(self.buffer))

        payload_length = 4 + int.from_bytes(self.buffer[1:4], byteorder="big")
        if len(self.buffer) < payload_length:
            _LOGGER.debug(
                "Expected %d bytes, have %d (waiting for more)",
                payload_length,
                len(self.buffer),
            )
            self._receive_event.clear()
            return

        frame_type = FrameType(self.buffer[0])
        data = self.buffer[4:payload_length]
        self.buffer = self.buffer[payload_length:]

        if frame_type in COMPANION_AUTH_FRAMES:
            try:
                self.handle_auth_frame(frame_type, opack.unpack(data)[0])
            except Exception:
                _LOGGER.exception("failed to handle auth frame")
        else:
            try:
                resp = await self.send_to_atv(frame_type, data)
                self.send_to_client(frame_type, resp)
            except Exception:
                _LOGGER.exception("data exchange failed")

        self._receive_event.clear()
Exemplo n.º 4
0
def test_golden():
    data = {
        "_i": "_systemInfo",
        "_x": 1254122577,
        "_btHP": False,
        "_c": {
            "_pubID":
            "AA:BB:CC:DD:EE:FF",
            "_sv":
            "230.1",
            "_bf":
            0,
            "_siriInfo": {
                "collectorElectionVersion": 1.0,
                "deviceCapabilities": {
                    "seymourEnabled": 1,
                    "voiceTriggerEnabled": 2
                },
                "sharedDataProtoBuf": 512 * b"\x08",
            },
            "_stA": [
                "com.apple.LiveAudio",
                "com.apple.siri.wakeup",
                "com.apple.Seymour",
                "com.apple.announce",
                "com.apple.coreduet.sync",
                "com.apple.SeymourSession",
            ],
            "_i":
            "6c62fca18b11",
            "_clFl":
            128,
            "_idsID":
            "44E14ABC-DDDD-4188-B661-11BAAAF6ECDE",
            "_hkUID": [UUID("17ed160a-81f8-4488-962c-6b1a83eb0081")],
            "_dC":
            "1",
            "_sf":
            256,
            "model":
            "iPhone10,6",
            "name":
            "iPhone",
        },
        "_t": 2,
    }

    packed = pack(data)
    unpacked = unpack(packed)

    assert DeepDiff(unpacked, data, ignore_order=True)
Exemplo n.º 5
0
    async def send_to_atv(self, frame_type: FrameType, data: bytes):
        """Send data to remote device (ATV)."""
        log_binary(_LOGGER,
                   f">>(ENCRYPTED) FrameType={frame_type}",
                   Message=data)

        if self.chacha:
            header = bytes([frame_type.value]) + len(data).to_bytes(
                3, byteorder="big")
            data = self.chacha.decrypt(data, aad=header)
            log_binary(_LOGGER, "<<(DECRYPTED)", Message=data)

        unpacked = cast(Dict[Any, Any],
                        opack.unpack(data)[0])  # TODO: Bad cast
        if frame_type in COMPANION_AUTH_FRAMES:
            return await self.protocol.exchange_auth(frame_type, unpacked)
        return await self.protocol.exchange_opack(frame_type, unpacked)
Exemplo n.º 6
0
    def frame_received(self, frame_type: FrameType, data: bytes) -> None:
        """Frame was received from remote device."""
        _LOGGER.debug("Received frame %s: %s", frame_type, data)

        if frame_type in _OPACK_FRAMES or frame_type in _AUTH_FRAMES:
            try:
                opack_data, _ = opack.unpack(data)

                if not isinstance(opack_data, dict):
                    _LOGGER.debug("Unsupported OPACK base type: %s",
                                  type(opack_data))
                    return

                if frame_type in _AUTH_FRAMES:
                    self._handle_auth(frame_type, opack_data)
                else:
                    self._handle_opack(frame_type, opack_data)
            except Exception:
                _LOGGER.exception("failed to process frame")
        else:
            _LOGGER.debug("Received unsupported frame type: %s", frame_type)
Exemplo n.º 7
0
    def data_received(self, data):
        self.buffer += data

        while self.buffer:
            payload_length = 4 + int.from_bytes(self.buffer[1:4],
                                                byteorder="big")
            if len(self.buffer) < payload_length:
                _LOGGER.debug("Expect %d bytes, have %d bytes", payload_length,
                              len(self.buffer))
                break

            frame_type = FrameType(self.buffer[0])
            header = self.buffer[0:4]
            data = self.buffer[4:payload_length]
            self.buffer = self.buffer[payload_length:]

            if self.chacha:
                data = self.chacha.decrypt(data, aad=header)

            unpacked, _ = opack.unpack(data)

            try:
                if frame_type in COMPANION_AUTH_FRAMES:
                    self.handle_auth_frame(frame_type, unpacked)
                else:
                    if not self.chacha:
                        raise Exception("client has not authenticated")

                    _LOGGER.debug("Received OPACK: %s", unpacked)
                    handler_method_name = f"handle_{unpacked['_i'].lower()}"
                    if hasattr(self, handler_method_name):
                        getattr(self, handler_method_name)(unpacked)
                    else:
                        _LOGGER.warning("No handler for type %s",
                                        unpacked["_i"])

            except Exception:
                _LOGGER.exception("failed to handle incoming data")
Exemplo n.º 8
0
def test_unpack_none():
    assert unpack(b"\x04") == (None, b"")
Exemplo n.º 9
0
def test_unpack_boolean():
    assert unpack(b"\x01") == (True, b"")
    assert unpack(b"\x02") == (False, b"")
Exemplo n.º 10
0
def test_unpack_endless_dict():
    assert unpack(b"\xEF" + b"\x41" +
                  b"\x41".join(bytes([x])
                               for x in range(97, 127)) + b"\x03") == (dict(
                                   (chr(x), chr(x + 1))
                                   for x in range(97, 127, 2)), b"")
Exemplo n.º 11
0
def test_unpack_uuid():
    assert unpack(b"\x05\x124Vx\x124Vx\x124Vx\x124Vx") == (
        UUID("{12345678-1234-5678-1234-567812345678}"),
        b"",
    )
Exemplo n.º 12
0
def test_unpack_endless_array():
    list1 = b"\xDF\x41\x61" + 15 * b"\xa0" + b"\x03"
    list2 = b"\xDF\x41\x62" + 15 * b"\xa1" + b"\x03"
    assert unpack(list1) == (16 * ["a"], b"")
    assert unpack(b"\xD2" + list1 + list2) == ([16 * ["a"], 16 * ["b"]], b"")
Exemplo n.º 13
0
def test_unpack_dict():
    assert unpack(b"\xe0") == ({}, b"")
    assert unpack(b"\xe2\x41\x61\x14\x02\x04") == ({"a": 12, False: None}, b"")
    assert unpack(b"\xe1\x01\xe1\x41\x61\x0a") == ({True: {"a": 2}}, b"")
Exemplo n.º 14
0
def test_unpack_longer_raw_bytes():
    assert unpack(b"\x91\x21" + (33 * b"\x61")) == (33 * b"\x61", b"")
    assert unpack(b"\x92\x00\x01" + (256 * b"\x61")) == (256 * b"\x61", b"")
Exemplo n.º 15
0
def test_unpack_larger_integers():
    assert unpack(b"\x30\x28") == (0x28, b"")
    assert unpack(b"\x31\xFf\x01") == (0x1FF, b"")
    assert unpack(b"\x32\xFF\xFF\x01") == (0x1FFFF, b"")
    assert unpack(b"\x33\xFF\xFF\xFF\x01") == (0x1FFFFFF, b"")
Exemplo n.º 16
0
def test_unpack_absolute_time():
    # TODO: This is not implemented, it only parses the time stamp as an integer
    assert unpack(b"\x06\x01\x00\x00\x00\x00\x00\x00\x00") == (1, b"")
Exemplo n.º 17
0
def test_unpack_short_raw_bytes():
    assert unpack(b"\x71\xac") == (b"\xac", b"")
    assert unpack(b"\x73\x12\x34\x56") == (b"\x12\x34\x56", b"")
    assert unpack(b"\x90" + (0x20 * b"\xad")) == (0x20 * b"\xad", b"")
Exemplo n.º 18
0
def test_unpack_short_strings():
    assert unpack(b"\x41\x61") == ("a", b"")
    assert unpack(b"\x43\x61\x62\x63") == ("abc", b"")
    assert unpack(b"\x60" + (0x20 * b"\x61")) == (0x20 * "a", b"")
Exemplo n.º 19
0
def test_unpack_float64():
    assert unpack(b"\x36\x00\x00\x00\x00\x00\x00\xF0\x3F") == (1.0, b"")
Exemplo n.º 20
0
def test_pack_unfloat32():
    assert unpack(b"\x35\x00\x00\x80\x3f") == (1.0, b"")
Exemplo n.º 21
0
def test_unpack_unsupported_type():
    with pytest.raises(TypeError):
        unpack(b"\x00")
Exemplo n.º 22
0
def test_unpack_array():
    assert unpack(b"\xd0") == ([], b"")
    assert unpack(b"\xd3\x09\x44\x74\x65\x73\x74\x02") == ([1, "test",
                                                            False], b"")
    assert unpack(b"\xd1\xd1\x01") == ([[True]], b"")
Exemplo n.º 23
0
def test_unpack_longer_strings():
    assert unpack(b"\x61\x21" + (33 * b"\x61")) == (33 * "a", b"")
    assert unpack(b"\x62\x00\x01" + (256 * b"\x61")) == (256 * "a", b"")
Exemplo n.º 24
0
def test_unpack_small_integers():
    assert unpack(b"\x08") == (0, b"")
    assert unpack(b"\x17") == (0xF, b"")
    assert unpack(b"\x2F") == (0x27, b"")