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)
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
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)
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
def test_decrypt(): assert dec_text == decrypt(enc_text, password).rstrip(b"\xee")
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
def _decode(self, obj, context, path): try: return decrypt(obj, context._.password)[:context.header.length] except AttributeError: raise