def parseAndHandleMessageProto(self, encMessageProtocolEntity, serializedData): node = encMessageProtocolEntity.toProtocolTreeNode() m = Message() handled = False try: m.ParseFromString(serializedData) except: print("DUMP:") print(serializedData) print([s for s in serializedData]) print([ord(s) for s in serializedData]) raise if not m or not serializedData: raise ValueError("Empty message") logger.debug("AXOLOT RECIVE") logger.debug(m) if m.HasField("sender_key_distribution_message"): handled = True axolotlAddress = AxolotlAddress( encMessageProtocolEntity.getParticipant(False), 0) self.handleSenderKeyDistributionMessage( m.sender_key_distribution_message, axolotlAddress) if m.HasField("conversation"): handled = True self.handleConversationMessage(node, m.conversation) elif m.HasField("contact_message"): handled = True self.handleContactMessage(node, m.contact_message) elif m.HasField("url_message"): handled = True self.handleUrlMessage(node, m.url_message) elif m.HasField("location_message"): handled = True self.handleLocationMessage(node, m.location_message) elif m.HasField("image_message"): handled = True self.handleImageMessage(node, m.image_message) elif m.HasField("audio_message"): handled = True self.handleAudioMessage(node, m.audio_message) elif m.HasField("video_message"): handled = True self.handleVideoMessage(node, m.video_message) elif m.HasField("document_message"): handled = True self.handleDocumentMessage(node, m.document_message) if not handled: print(m) raise ValueError("Unhandled")
def handleSenderKeyMessage(self, node): encMessageProtocolEntity = EncryptedMessageProtocolEntity(node) enc_ = encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_SKMSG) senderKeyName = SenderKeyName( encMessageProtocolEntity.sender, AxolotlAddress( Jid.denormalize(encMessageProtocolEntity.participant), 0)) groupCipher = GroupCipher(self.store, senderKeyName) try: plaintext = groupCipher.decrypt(enc_.getData()) paddingByte = plaintext[-1] if type(plaintext[-1]) is int else ord( plaintext[-1]) padding = paddingByte & 0xFF self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext[:-padding]) except NoSessionException: logger.warning( "No session for %s, going to send a retry", Jid.denormalize(encMessageProtocolEntity.getAuthor())) retry = RetryOutgoingReceiptProtocolEntity.fromMessageNode( node, self.store.getLocalRegistrationId()) self.toLower(retry.toProtocolTreeNode()) except Exception as ex: # (AttributeError, TypeError) logger.error('Exception in handleSenderKeyMessage: %s' % ex) raise
def handleSenderKeyMessage(self, node): encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode( node) enc = encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_SKMSG) senderKeyName = SenderKeyName( encMessageProtocolEntity.getFrom(True), AxolotlAddress(encMessageProtocolEntity.getParticipant(False), 0)) groupCipher = GroupCipher(self.store, senderKeyName) try: plaintext = groupCipher.decrypt(enc.getData()) #print("Plain before:", plaintext) padding = ord(plaintext[-1]) & 0xFF plaintext = plaintext[:-padding] plaintext = plaintext.encode() if sys.version_info >= ( 3, 0) else plaintext #print("Plain:", plaintext) self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext) except NoSessionException as e: logger.warning("No session for %s, going to send a retry", encMessageProtocolEntity.getAuthor(False)) retry = RetryOutgoingReceiptProtocolEntity.fromMessageNode( node, self.store.getLocalRegistrationId()) self.toLower(retry.toProtocolTreeNode())
def sendToGroup(self, node, retryReceiptEntity=None): groupJid = node["to"] ownNumber = self.getLayerInterface( YowAuthenticationProtocolLayer).getUsername(False) ownJid = self.getLayerInterface( YowAuthenticationProtocolLayer).getUsername(True) senderKeyName = SenderKeyName(node["to"], AxolotlAddress(ownNumber, 0)) senderKeyRecord = self.store.loadSenderKey(senderKeyName) def sendToGroup(resultNode, requestEntity): groupInfo = InfoGroupsResultIqProtocolEntity.fromProtocolTreeNode( resultNode) jids = list(groupInfo.getParticipants().keys() ) #keys in py3 returns dict_keys if ownJid in jids: jids.remove(ownJid) return self.ensureSessionsAndSendToGroup(node, jids) if senderKeyRecord.isEmpty(): groupInfoIq = InfoGroupsIqProtocolEntity(groupJid) self._sendIq(groupInfoIq, sendToGroup) else: retryCount = 0 jidsNeedSenderKey = [] if retryReceiptEntity is not None: retryCount = retryReceiptEntity.getRetryCount() jidsNeedSenderKey.append(retryReceiptEntity.getRetryJid()) self.sendToGroupWithSessions(node, jidsNeedSenderKey, retryCount)
def sendToGroupWithSessions(self, node, jidsNeedSenderKey = None, retryCount=0): jidsNeedSenderKey = jidsNeedSenderKey or [] groupJid = node["to"] ownNumber = self.getLayerInterface(YowAuthenticationProtocolLayer).getUsername(False) senderKeyName = SenderKeyName(groupJid, AxolotlAddress(ownNumber, 0)) cipher = self.getGroupCipher(groupJid, ownNumber) encEntities = [] if len(jidsNeedSenderKey): senderKeyDistributionMessage = self.groupSessionBuilder.create(senderKeyName) for jid in jidsNeedSenderKey: sessionCipher = self.getSessionCipher(jid.split('@')[0]) message = self.serializeSenderKeyDistributionMessageToProtobuf(node["to"], senderKeyDistributionMessage) if retryCount > 0: message = self.serializeToProtobuf(node, message) ciphertext = sessionCipher.encrypt(message.SerializeToString() + self.getPadding()) encEntities.append( EncProtocolEntity( EncProtocolEntity.TYPE_MSG if ciphertext.__class__ == WhisperMessage else EncProtocolEntity.TYPE_PKMSG , 2, ciphertext.serialize(), jid=jid ) ) if not retryCount: messageData = self.serializeToProtobuf(node).SerializeToString() ciphertext = cipher.encrypt(messageData + self.getPadding()) mediaType = node.getChild("media")["type"] if node.getChild("media") else None encEntities.append(EncProtocolEntity(EncProtocolEntity.TYPE_SKMSG, 2, ciphertext, mediaType)) self.sendEncEntities(node, encEntities)
def getGroupCipher(self, groupId, senderId): senderKeyName = SenderKeyName(groupId, AxolotlAddress(senderId, 0)) if senderKeyName in self.groupCiphers: groupCipher = self.groupCiphers[senderKeyName] else: groupCipher = GroupCipher(self.store, senderKeyName) self.groupCiphers[senderKeyName] = groupCipher return groupCipher
def _get_group_cipher(self, groupid, username): logger.debug("get_group_cipher(groupid=%s, username=%s)" % (groupid, username)) senderkeyname = SenderKeyName(groupid, AxolotlAddress(username, 0)) if senderkeyname in self._group_ciphers: group_cipher = self._group_ciphers[senderkeyname] else: group_cipher = GroupCipher(self._store.senderKeyStore, senderkeyname) self._group_ciphers[senderkeyname] = group_cipher return group_cipher
def parseAndHandleMessageProto(self, encMessageProtocolEntity, serializedData): node = encMessageProtocolEntity.toProtocolTreeNode() m = Message() try: if sys.version_info >= (3, 0) and isinstance(serializedData, str): serializedData = serializedData.encode() except AttributeError: logger.warning( "AttributeError: 'bytes' object has no attribute 'encode'. Skipping 'encode()'" ) pass handled = False try: m.ParseFromString(serializedData) except: raise if not m or not serializedData: raise ValueError("Empty message") if m.HasField("sender_key_distribution_message"): handled = True axolotlAddress = AxolotlAddress( encMessageProtocolEntity.getParticipant(False), 0) self.handleSenderKeyDistributionMessage( m.sender_key_distribution_message, axolotlAddress) if m.HasField("conversation"): handled = True self.handleConversationMessage(node, m.conversation) elif m.HasField("contact_message"): handled = True self.handleContactMessage(node, m.contact_message) elif m.HasField("url_message"): handled = True self.handleUrlMessage(node, m.url_message) elif m.HasField("location_message"): handled = True self.handleLocationMessage(node, m.location_message) elif m.HasField("image_message"): handled = True self.handleImageMessage(node, m.image_message) elif m.HasField("video_message"): handled = True self.handleVideoMessage(node, m.video_message) elif m.HasField("audio_message"): self.handleAudioMessage(node, m.audio_message) elif m.HasField("document_message"): handled = True self.handleDocumentMessage(node, m.document_message) elif not handled: raise ValueError("Unhandled")
def parseAndHandleMessageProto(self, encMessageProtocolEntity, serializedData): node = encMessageProtocolEntity.toProtocolTreeNode() m = Message() try: m.ParseFromString(serializedData) except: #print("DUMP:") #print(serializedData) #print([s for s in serializedData]) #print([ord(s) for s in serializedData]) #raise pass if not m or not serializedData: raise ValueError("Empty message") if m.HasField("sender_key_distribution_message"): logger.debug("Sender key distribution message") axolotlAddress = AxolotlAddress( encMessageProtocolEntity.getParticipant(False), 0) self.handleSenderKeyDistributionMessage( m.sender_key_distribution_message, axolotlAddress) if m.HasField("conversation"): logger.debug("Handle conversation") self.handleConversationMessage(node, m.conversation) elif m.HasField("contact_message"): logger.debug("Handle contact message") self.handleContactMessage(node, m.contact_message) elif m.HasField("url_message"): logger.debug("Handle url message") self.handleUrlMessage(node, m.url_message) elif m.HasField("location_message"): logger.debug("Handle location message") self.handleLocationMessage(node, m.location_message) elif m.HasField("image_message"): logger.debug("Handle image message") self.handleImageMessage(node, m.image_message) elif m.HasField("document_message"): logger.debug("Handle document message") self.handleDocumentMessage(node, m.document_message) elif m.HasField("video_message"): logger.debug("Handle video message") self.handleDocumentMessage(node, m.video_message) elif m.HasField("audio_message"): logger.debug("Handle audio message") self.handleAudioMessage(node, m.audio_message) else: logger.debug("Unhandled message") print(m) raise ValueError("Unhandled")
def parseAndHandleMessageProto(self, encMessageProtocolEntity, serializedData): node = encMessageProtocolEntity.toProtocolTreeNode() m = Message() if sys.version_info >= (3, 0) and isinstance(serializedData, str): serializedData = serializedData.encode() handled = False try: m.ParseFromString(serializedData) except: print("DUMP:") print(serializedData) print([s for s in serializedData]) #print([ord(s) for s in serializedData]) raise if not m or not serializedData: raise ValueError("Empty message") if m.HasField("sender_key_distribution_message"): handled = True axolotlAddress = AxolotlAddress( encMessageProtocolEntity.getParticipant(False), 0) self.handleSenderKeyDistributionMessage( m.sender_key_distribution_message, axolotlAddress) print("MESSAGE") print(node) print(m) if m.HasField("conversation"): handled = True self.handleConversationMessage(node, m.conversation) elif m.HasField("contact_message"): handled = True self.handleContactMessage(node, m.contact_message) elif m.HasField("url_message"): handled = True self.handleUrlMessage(node, m.url_message) elif m.HasField("location_message"): handled = True self.handleLocationMessage(node, m.location_message) elif m.HasField("image_message"): handled = True self.handleImageMessage(node, m.image_message) elif m.HasField("video_message"): handled = True print(node) #raise("OPA") if not handled: print(m) raise ValueError("Unhandled")
def parseAndHandleMessageProto(self, encMessageProtocolEntity, serializedData): node = encMessageProtocolEntity.toProtocolTreeNode() m = Message() try: if sys.version_info >= (3, 0) and isinstance(serializedData, str): serializedData = serializedData.encode() except AttributeError: logger.warning( "AttributeError: 'bytes' object has no attribute 'encode'. Skipping 'encode()'" ) pass if "YOWSUP_PROTOBUF_DEBUG" in os.environ: from yowsup.common.protobuf_inspect.types import StandardParser parser = StandardParser() parser.types["root"] = {} parser.types["root"]["compact"] = False print( parser.safe_call(parser.match_handler("message"), BytesIO(serializedData), "root")) handled = False try: m.ParseFromString(serializedData) params = protobuf_to_dict(m) except Exception: raise if not m or not serializedData: raise ValueError("Empty message") if m.HasField("sender_key_distribution_message"): handled = True axolotlAddress = AxolotlAddress( Jid.denormalize(encMessageProtocolEntity.participant), 0) self.handleSenderKeyDistributionMessage( params['sender_key_distribution_message'], axolotlAddress) params.pop('sender_key_distribution_message') body_type = m.WhichOneof("body") if len(params) and body_type: messageNode = copy.deepcopy(node) messageNode.addChild( ProtocolTreeNode("body", {"type": body_type}, data=params[body_type])) self.toUpper(messageNode) elif not handled: raise ValueError("Unhandled")
def handleSenderKeyMessage(self, node): encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node) enc = encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_SKMSG) senderKeyName = SenderKeyName(encMessageProtocolEntity.getFrom(True), AxolotlAddress(encMessageProtocolEntity.getParticipant(False), 0)) groupCipher = GroupCipher(self.store, senderKeyName) try: plaintext = groupCipher.decrypt(enc.getData()) padding = ord(plaintext[-1]) & 0xFF self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext[:-padding]) except NoSessionException as e: logger.error(e) retry = RetryOutgoingReceiptProtocolEntity.fromMessageNode(node) retry.setRegData(self.store.getLocalRegistrationId()) self.toLower(retry.toProtocolTreeNode())
def group_create_session(self, groupid, participantid, skmsgdata): """ :param groupid: :type groupid: str :param participantid: :type participantid: str :param skmsgdata: :type skmsgdata: bytearray :return: :rtype: """ logger.debug("group_create_session(groupid=%s, participantid=%s, skmsgdata=[omitted])" % (groupid, participantid)) senderKeyName = SenderKeyName(groupid, AxolotlAddress(participantid, 0)) senderkeydistributionmessage = SenderKeyDistributionMessage(serialized=skmsgdata) self._group_session_builder.process(senderKeyName, senderkeydistributionmessage)
def parseAndHandleMessageProto(self, encMessageProtocolEntity, serializedData): node = encMessageProtocolEntity.toProtocolTreeNode() m = Message() try: if sys.version_info >= (3,0): serializedData = serializedData.encode() except AttributeError: logger.error("AttributeError: 'bytes' object has no attribute 'encode'. Skipping 'encode()'") pass handled = False try: m.ParseFromString(serializedData) except: print("DUMP:") print(serializedData) print([s for s in serializedData]) # print([ord(s) for s in serializedData]) raise if not m or not serializedData: raise ValueError("Empty message") if m.HasField("sender_key_distribution_message"): handled = True axolotlAddress = AxolotlAddress(encMessageProtocolEntity.getParticipant(False), 0) self.handleSenderKeyDistributionMessage(m.sender_key_distribution_message, axolotlAddress) if m.HasField("conversation"): handled = True self.handleConversationMessage(node, m.conversation) elif m.HasField("contact_message"): handled = True self.handleContactMessage(node, m.contact_message) elif m.HasField("url_message"): handled = True self.handleUrlMessage(node, m.url_message) elif m.HasField("location_message"): handled = True self.handleLocationMessage(node, m.location_message) elif m.HasField("image_message"): handled = True self.handleImageMessage(node, m.image_message) if not handled: # raise ValueError("Unhandled") logger.error("Unhandled message. Skipping...") self.toLower(OutgoingReceiptProtocolEntity(node["id"], node["from"], read= True, participant=node["participant"]).toProtocolTreeNode()) return
def handleSenderKeyMessage(self, node): encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode( node) enc = encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_SKMSG) senderKeyName = SenderKeyName( encMessageProtocolEntity.getFrom(True), AxolotlAddress(encMessageProtocolEntity.getParticipant(False), 0)) groupCipher = GroupCipher(self.store, senderKeyName) try: plaintext = groupCipher.decrypt(enc.getData()) if type(plaintext) == bytes: # DEBUG SET RECEIPT # self.toLower(OutgoingReceiptProtocolEntity(node["id"], node["from"], 'read', participant=node["participant"]).toProtocolTreeNode()) if plaintext[0:1] == b'\n': msg = plaintext[3:3 + plaintext[1:2][-1]] elif plaintext[2:3] == b'\x01': msg = plaintext[5:5 + plaintext[4:5][-1]] if msg[0:1] == b'\x01': msg = plaintext[6:6 + plaintext[4:5][-1]] else: msg = plaintext[4:4 + plaintext[3:4][-1]] # self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext) self.handleConversationMessage(node, msg.decode()) # self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext.split(b'\x8a')[0]) return try: padding = ord(plaintext[-1]) & 0xFF plaintext = plaintext[:-padding] plaintext = plaintext.encode() if sys.version_info >= ( 3, 0) else plaintext self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext) except Exception as ex: #(AttributeError, TypeError) logger.error('Exception') logger.error('Exception %s' % ex) except NoSessionException as e: logger.warning("No session for %s, going to send a retry", encMessageProtocolEntity.getAuthor(False)) retry = RetryOutgoingReceiptProtocolEntity.fromMessageNode( node, self.store.getLocalRegistrationId()) self.toLower(retry.toProtocolTreeNode())
def parseAndHandleMessageProto(self, encMessageProtocolEntity, serializedData): node = encMessageProtocolEntity.toProtocolTreeNode() m = Message() handled = False try: m.ParseFromString(serializedData) except: #print("DUMP:") #print(serializedData) #print([s for s in serializedData]) #print([ord(s) for s in serializedData]) #raise pass if not m or not serializedData: raise ValueError("Empty message") if m.HasField("sender_key_distribution_message"): handled = True axolotlAddress = AxolotlAddress( encMessageProtocolEntity.getParticipant(False), 0) self.handleSenderKeyDistributionMessage( m.sender_key_distribution_message, axolotlAddress) if m.HasField("conversation"): handled = True self.handleConversationMessage(node, m.conversation) elif m.HasField("contact_message"): handled = True self.handleContactMessage(node, m.contact_message) elif m.HasField("url_message"): handled = True self.handleUrlMessage(node, m.url_message) elif m.HasField("location_message"): handled = True self.handleLocationMessage(node, m.location_message) elif m.HasField("image_message"): handled = True self.handleImageMessage(node, m.image_message) if not handled: handled = True self.handleConversationMessage(node, serializedData)
def parseAndHandleMessageProto(self, encMessageProtocolEntity, serializedData): node = encMessageProtocolEntity.toProtocolTreeNode() m = Message() try: m.ParseFromString(serializedData) except: print("DUMP:") #with open("/tmp/protobuf.bin", "wb") as f: # f.write(serializedData) print(serializedData) print([s for s in serializedData]) print([ord(s) for s in serializedData]) raise if not m or not serializedData: raise ValueError("Empty message") if m.HasField("sender_key_distribution_message"): axolotlAddress = AxolotlAddress( encMessageProtocolEntity.getParticipant(False), 0) self.handleSenderKeyDistributionMessage( m.sender_key_distribution_message, axolotlAddress) if m.HasField("conversation"): self.handleConversationMessage(node, m.conversation) elif m.HasField("contact_message"): self.handleContactMessage(node, m.contact_message) elif m.HasField("url_message"): self.handleUrlMessage(node, m.url_message) elif m.HasField("location_message"): self.handleLocationMessage(node, m.location_message) elif m.HasField("image_message"): self.handleImageMessage(node, m.image_message) elif m.HasField("document_message"): self.handleDocumentMessage(node, m.document_message) elif m.HasField("video_message"): self.handleVideoMessage(node, m.video_message) elif m.HasField("audio_message"): self.handleAudioMessage(node, m.audio_message) else: print(m) raise ValueError("Unhandled")
def parseAndHandleMessageProto(self, encMessageProtocolEntity, serializedData): node = encMessageProtocolEntity.toProtocolTreeNode() m = Message() signals.node_intercepted.send((node, serializedData)) handled = False try: m.ParseFromString(serializedData) #pprint(m) except: logger.debug("Failed to serialize message") if PROP_IGNORE_UNHANDLED: logger.debug("Ignoring, send ack") self.toLower( OutgoingReceiptProtocolEntity( node["id"], node["from"], participant=node["participant"]).toProtocolTreeNode()) return else: raise ValueError("Unhandled") if not m or not serializedData: raise ValueError("Empty message") if m.HasField("sender_key_distribution_message"): axolotlAddress = AxolotlAddress( encMessageProtocolEntity.getParticipant(False), 0) self.handleSenderKeyDistributionMessage( m.sender_key_distribution_message, axolotlAddress) if m.HasField("conversation"): self.handleConversationMessage(node, m.conversation) elif m.HasField("contact_message"): self.handleContactMessage(node, m.contact_message) # TODO: Change name of this message type since its not url_message anymore # Whenever a @tag message or an anwer message is sended fits inside here elif m.HasField("url_message"): #print("Special message received") #self.handleUrlMessage(node, m.url_message) self.handleComplexMessage(node, m.url_message) elif m.HasField("location_message"): self.handleLocationMessage(node, m.location_message) elif m.HasField("image_message"): self.handleImageMessage(node, m.image_message) #elif m.HasField("document_message"): # logger.debug("Handle document message") # self.handleDocumentMessage(node, m.document_message) #elif m.HasField("video_message"): # logger.debug("Handle video message") # self.handleDocumentMessage(node, m.video_message) #elif m.HasField("audio_message"): # logger.debug("Handle audio message") # self.handleAudioMessage(node, m.audio_message) else: logger.warning("Unhandled message") pprint(m) pprint(serializedData) if PROP_IGNORE_UNHANDLED: print("Ignoring, send ack") self.toLower( OutgoingReceiptProtocolEntity( node["id"], node["from"], participant=node["participant"]).toProtocolTreeNode()) else: raise ValueError("Unhandled message")
def load_senderkey(self, groupid): logger.debug("load_senderkey(groupid=%s)" % groupid) senderkeyname = SenderKeyName(groupid, AxolotlAddress(self._username, 0)) return self._store.loadSenderKey(senderkeyname)
def group_create_skmsg(self, groupid): logger.debug("group_create_skmsg(groupid=%s)" % groupid) senderKeyName = SenderKeyName(groupid, AxolotlAddress(self._username, 0)) return self._group_session_builder.create(senderKeyName)