def _handle_message(self, room, event): """ Handle text messages sent to listening rooms """ if event['type'] != 'm.room.message' or event['content'][ 'msgtype'] != 'm.text': # Ignore non-messages and non-text messages return sender_id = event['sender'] if sender_id == self._client.user_id: # Ignore our own messages return user = self._client.get_user(sender_id) peer_address = self._userids_to_address.get(sender_id) if not peer_address: try: # recover displayname signature peer_address = signing.recover_address( sender_id.encode(), signature=data_decoder(user.get_display_name()), hasher=eth_sign_sha3) except AssertionError: log.warning('INVALID MESSAGE', sender_id=sender_id) return node_address_hex = address_encoder(peer_address) if node_address_hex.lower() not in sender_id: log.warning('INVALID SIGNATURE', peer_address=node_address_hex, sender_id=sender_id) return self._userids_to_address[sender_id] = peer_address data = event['content']['body'] if data.startswith('0x'): message = message_from_bytes(data_decoder(data)) else: message_dict = json.loads(data) log.trace('MESSAGE_DATA', data=message_dict) message = message_from_dict(message_dict) if isinstance(message, SignedMessage) and not message.sender: # FIXME: This can't be right message.sender = peer_address if isinstance(message, Delivered): self._receive_delivered(message) elif isinstance(message, Ping): log.warning( 'Not required Ping received', message=data, ) elif isinstance(message, SignedMessage): self._receive_message(message) elif log.isEnabledFor(logging.ERROR): log.error( 'Invalid message', message=data, )
def _handle_message(self, room, event): """ Handle text messages sent to listening rooms """ if ( event['type'] != 'm.room.message' or event['content']['msgtype'] != 'm.text' or not self._running ): # Ignore non-messages and non-text messages return sender_id = event['sender'] if sender_id == self._client.user_id: # Ignore our own messages return user = self._client.get_user(sender_id) peer_address = self._validate_userid_signature(user) if not peer_address: self.log.debug( 'INVALID SIGNATURE', user=user, name=user.get_display_name(), ) return data = event['content']['body'] if data.startswith('0x'): message = message_from_bytes(decode_hex(data)) if not message: return else: try: message_dict = json.loads(data) self.log.debug('MESSAGE_DATA', data=message_dict) message = message_from_dict(message_dict) except (UnicodeDecodeError, JSONDecodeError) as ex: self.log.warning( "Can't parse message data JSON", message_data=data, peer_address=pex(peer_address), exception=ex, ) return if isinstance(message, Delivered): self._receive_delivered(message) elif isinstance(message, Ping): self.log.warning( 'Not required Ping received', message=data, ) elif isinstance(message, SignedMessage): self._receive_message(message) else: self.log.error( 'Invalid message', message=data, )
def _handle_message(self, room, event): """ Handle text messages sent to listening rooms """ if (event['type'] != 'm.room.message' or event['content']['msgtype'] != 'm.text' or not self._running): # Ignore non-messages and non-text messages return sender_id = event['sender'] if sender_id == self._client.user_id: # Ignore our own messages return user = self._get_user(sender_id) peer_address = self._validate_userid_signature(user) if not peer_address: # invalid user displayName signature return old_room = self._get_room_id_for_address(peer_address) if old_room != room.room_id: self.log.debug( 'received message triggered new room for peer', peer_user=user.user_id, peer_address=to_checksum_address(peer_address), old_room=old_room, room=room, ) self._set_room_id_for_address(peer_address, room.room_id) if peer_address not in self._address_to_userids: # user not start_health_check'ed return data = event['content']['body'] if data.startswith('0x'): try: message = message_from_bytes(decode_hex(data)) assert message except (DecodeError, AssertionError) as ex: self.log.warning( "Can't parse message binary data", message_data=data, peer_address=pex(peer_address), exception=ex, ) return else: try: message_dict = json.loads(data) self.log.debug('MESSAGE_DATA', data=message_dict) message = message_from_dict(message_dict) except (UnicodeDecodeError, JSONDecodeError) as ex: self.log.warning( "Can't parse message data JSON", message_data=data, peer_address=pex(peer_address), exception=ex, ) return if isinstance(message, Delivered): self._receive_delivered(message) elif isinstance(message, Ping): self.log.warning( 'Not required Ping received', message=data, ) elif isinstance(message, SignedMessage): if message.sender != peer_address: self.log.warning( 'Message not signed by sender!', message=message, signer=message.sender, peer_address=peer_address, ) return self._receive_message(message) else: self.log.error( 'Invalid message', message=data, )
def _handle_message(self, room, event): """ Handle text messages sent to listening rooms """ if ( event['type'] != 'm.room.message' or event['content']['msgtype'] != 'm.text' or not self._running ): # Ignore non-messages and non-text messages return sender_id = event['sender'] if sender_id == self._client.user_id: # Ignore our own messages return user = self._client.get_user(sender_id) peer_address = self._userids_to_address.get(sender_id) if not peer_address: try: # recover displayname signature peer_address = signing.recover_address( sender_id.encode(), signature=data_decoder(user.get_display_name()), hasher=eth_sign_sha3, ) except AssertionError: self.log.warning('INVALID MESSAGE', sender_id=sender_id) return node_address_hex = to_normalized_address(peer_address) if node_address_hex.lower() not in sender_id: self.log.warning( 'INVALID SIGNATURE', peer_address=node_address_hex, sender_id=sender_id, ) return self._userids_to_address[sender_id] = peer_address data = event['content']['body'] if data.startswith('0x'): message = message_from_bytes(data_decoder(data)) else: try: message_dict = json.loads(data) except (UnicodeDecodeError, JSONDecodeError) as ex: self.log.warning( "Can't parse message data JSON", message_data=data, peer_address=pex(peer_address), exception=ex, ) return self.log.debug('MESSAGE_DATA', data=message_dict) message_dict = json.loads(data) self.log.debug('MESSAGE_DATA', data=message_dict) message = message_from_dict(message_dict) if isinstance(message, SignedMessage) and not message.sender: # FIXME: This can't be right message.sender = peer_address if isinstance(message, Delivered): self._receive_delivered(message) elif isinstance(message, Ping): self.log.warning( 'Not required Ping received', message=data, ) elif isinstance(message, SignedMessage): self._receive_message(message) else: self.log.error( 'Invalid message', message=data, )
def validate_and_parse_message(data, peer_address) -> List[Message]: messages = list() if not isinstance(data, str): log.warning( "Received ToDevice Message body not a string", message_data=data, peer_address=pex(peer_address), ) return [] if data.startswith("0x"): try: message = message_from_bytes(decode_hex(data)) if not message: raise InvalidProtocolMessage except (DecodeError, AssertionError) as ex: log.warning( "Can't parse ToDevice Message binary data", message_data=data, peer_address=pex(peer_address), _exc=ex, ) return [] except InvalidProtocolMessage as ex: log.warning( "Received ToDevice Message binary data is not a valid message", message_data=data, peer_address=pex(peer_address), _exc=ex, ) return [] else: messages.append(message) else: for line in data.splitlines(): line = line.strip() if not line: continue try: message_dict = json.loads(line) message = message_from_dict(message_dict) except (UnicodeDecodeError, json.JSONDecodeError) as ex: log.warning( "Can't parse ToDevice Message data JSON", message_data=line, peer_address=pex(peer_address), _exc=ex, ) continue except InvalidProtocolMessage as ex: log.warning( "ToDevice Message data JSON are not a valid ToDevice Message", message_data=line, peer_address=pex(peer_address), _exc=ex, ) continue if not isinstance(message, SignedMessage): log.warning( "ToDevice Message not a SignedMessage!", message=message, peer_address=pex(peer_address), ) continue if message.sender != peer_address: log.warning( "ToDevice Message not signed by sender!", message=message, signer=message.sender, peer_address=pex(peer_address), ) continue messages.append(message) return messages
def _handle_message(self, room, event): """ Handle text messages sent to listening rooms """ if ( event['type'] != 'm.room.message' or event['content']['msgtype'] != 'm.text' or not self._running ): # Ignore non-messages and non-text messages return sender_id = event['sender'] if sender_id == self._client.user_id: # Ignore our own messages return user = self._get_user(sender_id) peer_address = self._validate_userid_signature(user) if not peer_address: # invalid user displayName signature return old_room = self._get_room_id_for_address(peer_address) if old_room != room.room_id: self.log.debug( 'received message triggered new room for peer', peer_user=user.user_id, peer_address=to_checksum_address(peer_address), old_room=old_room, room=room, ) self._set_room_id_for_address(peer_address, room.room_id) if peer_address not in self._address_to_userids: # user not start_health_check'ed return data = event['content']['body'] if data.startswith('0x'): try: message = message_from_bytes(decode_hex(data)) assert message except (DecodeError, AssertionError) as ex: self.log.warning( "Can't parse message binary data", message_data=data, peer_address=pex(peer_address), exception=ex, ) return else: try: message_dict = json.loads(data) self.log.debug('MESSAGE_DATA', data=message_dict) message = message_from_dict(message_dict) except (UnicodeDecodeError, JSONDecodeError) as ex: self.log.warning( "Can't parse message data JSON", message_data=data, peer_address=pex(peer_address), exception=ex, ) return if isinstance(message, Delivered): self._receive_delivered(message) elif isinstance(message, Ping): self.log.warning( 'Not required Ping received', message=data, ) elif isinstance(message, SignedMessage): if message.sender != peer_address: self.log.warning( 'Message not signed by sender!', message=message, signer=message.sender, peer_address=peer_address, ) return self._receive_message(message) else: self.log.error( 'Invalid message', message=data, )
def _handle_message(self, room, event) -> bool: """ Handle text messages sent to listening rooms """ if (event['type'] != 'm.room.message' or event['content']['msgtype'] != 'm.text' or self._stop_event.ready()): # Ignore non-messages and non-text messages return False sender_id = event['sender'] if sender_id == self._user_id: # Ignore our own messages return False user = self._get_user(sender_id) peer_address = self._validate_userid_signature(user) if not peer_address: self.log.debug( 'message from invalid user displayName signature', peer_user=user.user_id, room=room, ) return False # don't proceed if user isn't healthchecked (yet) if peer_address not in self._address_to_userids: # user not start_health_check'ed self.log.debug( 'message from non-healthchecked peer - ignoring', sender=user, sender_address=pex(peer_address), room=room, ) return False # rooms we created and invited user, or were invited specifically by them room_ids = self._get_room_ids_for_address(peer_address) if room.room_id not in room_ids: # this should not happen, but is not fatal, as we may not know user yet if bool(room.invite_only) < self._private_rooms: reason = 'required private room, but received message in a public' else: reason = 'unknown room for user' self.log.debug( 'received peer message in an invalid room - ignoring', peer_user=user.user_id, peer_address=pex(peer_address), room=room, reason=reason, ) return False if not room_ids or room.room_id != room_ids[0]: self.log.debug( 'received message triggered new comms room for peer', peer_user=user.user_id, peer_address=pex(peer_address), known_user_rooms=room_ids, room=room, ) self._set_room_id_for_address(peer_address, room.room_id) data = event['content']['body'] if not isinstance(data, str): self.log.warning( 'Received message body not a string', peer_user=user.user_id, peer_address=to_checksum_address(peer_address), room=room, ) return False if data.startswith('0x'): try: message = message_from_bytes(decode_hex(data)) if not message: raise InvalidProtocolMessage except (DecodeError, AssertionError) as ex: self.log.warning( "Can't parse message binary data", message_data=data, peer_address=pex(peer_address), _exc=ex, ) return False except InvalidProtocolMessage as ex: self.log.warning( "Received message binary data is not a valid message", message_data=data, peer_address=pex(peer_address), _exc=ex, ) return False else: try: message_dict = json.loads(data) message = message_from_dict(message_dict) except (UnicodeDecodeError, json.JSONDecodeError) as ex: self.log.warning( "Can't parse message data JSON", message_data=data, peer_address=pex(peer_address), _exc=ex, ) return False except InvalidProtocolMessage as ex: self.log.warning( "Message data JSON are not a valid message", message_data=data, peer_address=pex(peer_address), _exc=ex, ) return False self.log.debug( 'MESSAGE_DATA', data=data, sender=pex(peer_address), sender_user=user, room=room, ) if isinstance(message, Ping): self.log.warning( 'Not required Ping received', message=data, ) return False elif isinstance(message, SignedMessage): if message.sender != peer_address: self.log.warning( 'Message not signed by sender!', message=message, signer=message.sender, peer_address=peer_address, ) return False if isinstance(message, Delivered): self._receive_delivered(message) else: self._receive_message(message) else: self.log.warning( 'Received Invalid message', message=data, ) return False return True