Ejemplo n.º 1
0
def decrypt_file(file, password):
    PASSWORD2 = None
    try:
        data = ordered_load(file, yaml.loader.SafeLoader)

        n = 0
        for key, value in data.items():
            header = value[0:16]
            body = value[16:]
            decrypted = decrypt(body, password if n < 2 else PASSWORD2)
            if n < 2 and "peer1_" in key:
                PASSWORD2 = decrypted[1:17]
                print(len(PASSWORD2))

            print("PC->IP: " if "peer0_" in key else "IP->PC: ",
                  binascii.hexlify(header), binascii.hexlify(decrypted),
                  decrypted)

            if "peer1_" in key:
                print(
                    '----end %s-------------------------------------------------------------'
                    % key)
            n += 1

    except yaml.YAMLError as exc:
        print(exc)
Ejemplo n.º 2
0
    def get_message_payload(self, data):
        message = ip_message.parse(data)

        if len(message.payload) >= 16 and len(message.payload) % 16 == 0 and message.header.flags & 0x01 != 0:
            message_payload = decrypt(data[16:], self.key)[:message.header.length]
        else:
            message_payload = message.payload

        return message, message_payload
Ejemplo n.º 3
0
    def process_client_message(self, client, data):
        message = ip_message.parse(data)
        message_payload = data[16:]
        self.logger.debug("AP -> IP: {}".format(binascii.hexlify(data)))
        if len(message_payload) >= 16  and message.header.flags & 0x01 != 0 and len(message_payload) % 16 == 0:
            message_payload = decrypt(message_payload, self.key)[:37]

        force_plain_text = False
        response_code = 0x01
        if message.header.command == 0xf0:
            password = message_payload[:4]

            if password != cfg.IP_INTERFACE_PASSWORD:
                self.logger.warn("Authentication Error")
                return

            # Generate a new key
            self.key = binascii.hexlify(os.urandom(8)).upper()

            payload = ip_payload_connect_response.build(dict(key=self.key, major=0x0, minor=32, ip_major=4, ip_minor=48))
            force_plain_text = True

        elif message.header.command == 0xf2:
            payload = b'\x00'
        elif message.header.command == 0xf3:
            payload = binascii.unhexlify('0100000000000000000000000000000000')
        elif message.header.command == 0xf8:
            payload = b'\x01'
        elif message.header.command == 0x00:
            response_code = 0x02
            try:
                payload = self.alarm.send_wait_simple(message=message_payload[:37])
            except Exception:
                self.logger.exception("Send to panel")
                return
        else:
            self.logger.warn("UNKNOWN: {}".format(binascii.hexlify(data)))
            return

        if payload is not None:
            flags = 0x38
            payload_length = len(payload)

            if message.header.flags & 0x01 != 0 and not force_plain_text:
                payload = encrypt(payload, self.key)

                if message.header.command == 0x00:
                    flags = 0x73
                else:
                    flags = 0x39

            m = ip_message.build(dict(header=dict(length=payload_length, unknown0=response_code, flags=flags, command=message.header.command), payload=payload))
            self.logger.debug("IP -> AP: {}".format(binascii.hexlify(m)))
            client.send(m)
Ejemplo n.º 4
0
    def _get_message_payload(self, data):
        message = ip_message.parse(data)

        if len(message.payload) >= 16 and len(message.payload) % 16 == 0 and message.header.flags & 0x01 != 0:
            message_payload = decrypt(data[16:], self.key)[:message.header.length]
        else:
            message_payload = message.payload[:message.header.length]

        if cfg.LOGGING_DUMP_PACKETS:
            logger.debug("IPC -> PAI {}".format(binascii.hexlify(message_payload)))

        return message, message_payload
Ejemplo n.º 5
0
def test_decrypt():
    assert dec_text == decrypt(enc_text, password).rstrip(b"\xee")
Ejemplo n.º 6
0
    async def handle(self):
        next_connection_key = self.connection_key
        status = 'connecting'

        while True:
            try:
                data = await self.client_reader.read(1000)
            except:
                logger.info("Client disconnected")
                break

            if not data:
                continue

            if cfg.LOGGING_DUMP_PACKETS:
                logger.debug("APP -> IPI (raw) {}".format(
                    binascii.hexlify(data)))

            message = ip_message.parse(data)
            in_payload = message.payload

            if len(in_payload
                   ) >= 16 and message.header.flags & 0x01 != 0 and len(
                       in_payload) % 16 == 0:
                in_payload = decrypt(
                    in_payload, self.connection_key)[:message.header.length]

            in_payload = in_payload[:message.header.length]

            assert len(in_payload) == message.header.length, "Message payload length does not match with length in " \
                                                             "header "
            if cfg.LOGGING_DUMP_PACKETS:
                logger.debug("APP -> IPI (payload) {}".format(
                    binascii.hexlify(in_payload)))

            force_plain_text = False
            response_code = 0x01
            out_payload = None
            if message.header.command == 0xf0:
                password = in_payload

                if password != self.interface_password:
                    logger.warn("Authentication Error")
                    break
                else:
                    logger.info("Authentication Success")

                # Generate a new key
                next_connection_key = binascii.hexlify(os.urandom(8)).upper()

                out_payload = ip_payload_connect_response.build(
                    dict(key=next_connection_key,
                         major=0,
                         minor=32,
                         ip_major=1,
                         ip_minor=50,
                         unknown=113,
                         unknown2=6,
                         unknown3=0x15,
                         unknown4=44))

                flags = 0x39
            elif message.header.command == 0xf2:
                out_payload = b'\x00'
                flags = 0x39
            elif message.header.command == 0xf3:
                out_payload = binascii.unhexlify(
                    '0100000000000000000000000000000000')
                flags = 0x3b
            elif message.header.command == 0xf4:
                out_payload = b'\x01' if status == 'closing_connection' else b'\x00'
                flags = 0x39
            elif message.header.command == 0xf8:
                out_payload = b'\x01'
                flags = 0x39
            elif message.header.command == 0x00:
                response_code = 0x02
                flags = 0x73
                if in_payload[0] == 0x70 and in_payload[
                        2] == 0x05:  # Close connection
                    out_payload = self.alarm.panel.get_message(
                        'CloseConnection').build({})
                    status = 'closing_connection'
                else:
                    try:
                        self.alarm.connection.write(in_payload)
                    except Exception:
                        logger.exception("Send to panel")
                        break

                if in_payload[0] == 0x00:  # Just a status update
                    status = 'connected'

            else:
                logger.warn("UNKNOWN: raw: {}, payload: {}".format(
                    binascii.hexlify(data), binascii.hexlify(in_payload)))
                continue

            if out_payload is not None:
                payload_length = len(out_payload)

                if message.header.flags & 0x08 != 0:
                    out_payload = out_payload.ljust(
                        (payload_length // 16) * 16, bytes([0xee]))

                if cfg.LOGGING_DUMP_PACKETS:
                    logger.debug("IPI -> IPI (payload) {}".format(
                        binascii.hexlify(out_payload)))

                if message.header.flags & 0x01 != 0 and not force_plain_text:
                    out_payload = encrypt(out_payload, self.connection_key)

                m = ip_message.build(
                    dict(header=dict(length=payload_length,
                                     unknown0=response_code,
                                     flags=flags,
                                     command=message.header.command),
                         payload=out_payload))

                if cfg.LOGGING_DUMP_PACKETS:
                    logger.debug("IPI -> APP (raw) {}".format(
                        binascii.hexlify(m)))

                self.client_writer.write(m)
                await self.client_writer.drain()

                if self.connection_key != next_connection_key:
                    self.connection_key = next_connection_key

            if status == 'closing_connection':
                break
Ejemplo n.º 7
0
 def _decode(self, obj, context, path):
     try:
         return decrypt(obj, context._.password)[:context.header.length]
     except AttributeError:
         raise