-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Message decrypt error #683
Comments
Just followed this issue response #593 [Try to connect several times] but it only works for some time then the error resumes. |
For those who have experienced the same problem, here is what I did. Rather than letting the exception to terminate my program, I had to try catch the sections that raised exceptions both in the axolotl layer.py(NoSession exception) - issue #593 and protocol messages/message_text.py(AttributeError: 'NoneType' object has no attribute 'getData' ) - issue #690 Here is my fix. yowsup/layers/axolotl/layer.py - from line 179def handlePreKeyWhisperMessage(self, node):
plaintext = None
try:
pkMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node)
preKeyWhisperMessage = PreKeyWhisperMessage(serialized=pkMessageProtocolEntity.getEncData())
sessionCipher = self.getSessionCipher(pkMessageProtocolEntity.getFrom(False))
plaintext = sessionCipher.decryptPkmsg(preKeyWhisperMessage)
except Exception as e:
print 'Message decript error -> %s' %(str(e))
bodyNode = ProtocolTreeNode("body", data = plaintext)
node.addChild(bodyNode)
self.toUpper(node)
def handleWhisperMessage(self, node):
plaintext = None
try:
encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node)
whisperMessage = WhisperMessage(serialized=encMessageProtocolEntity.getEncData())
sessionCipher = self.getSessionCipher(encMessageProtocolEntity.getFrom(False))
plaintext = sessionCipher.decryptMsg(whisperMessage)
except Exception as e:
print 'Message decript error -> %s' %(str(e))
bodyNode = ProtocolTreeNode("body", data = plaintext)
node.addChild(bodyNode)
self.toUpper(node)
#### yowsup/layers/protocol_messages/protocolentities/message_text.py - from line 35@staticmethod
def fromProtocolTreeNode(node):
entity = MessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = TextMessageProtocolEntity
#entity.setBody(node.getChild("body").getData())
#return entity
try:
entity.setBody(node.getChild("body").getData())
return entity
except Exception, e:
pass
entity.setBody( None )
return entity After doing this, In my layer onMessage method, I check if the message is empty then return an error message to my customer. NB: I realized that the next time a message comes the same number which was initialized raising exceptions, It doesn't raise it again - a new session created - This quick fix helped me out. Similar issue was created here #593 |
@tgalal I'm trying to do something similar as in handlePlaintextNode, where it does a _sendIq with GetKeysIqProtocolEntity and then processes a pendingMessages on the onGetKeysResult callback. Is there a way to do this? Thank you in advance for any help. def handleEncMessage(self, node):
encEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node)
mFrom = encEntity.getFrom()
if not self.store.containsSession(encEntity.getFrom(False), 1):
if mFrom not in self.pendingMessagesFrom:
self.pendingMessagesFrom[mFrom] = []
self.pendingMessagesFrom[mFrom].append(node)
entity = GetKeysIqProtocolEntity([mFrom])
self._sendIq(entity, self.onGetKeysResult, self.onGetKeysError)
else:
try:
if node.getChild("enc")["type"] == "pkmsg":
plaintext = self.handlePreKeyWhisperMessage(encEntity)
else:
plaintext = self.handleWhisperMessage(encEntity)
except InvalidMessageException:
logger.error("Invalid message from %s!! Your axololtl database data might be inconsistent with WhatsApp, or with what that contact has" % node["from"])
sys.exit(1)
bodyNode = ProtocolTreeNode("body", data = plaintext)
node.addChild(bodyNode)
self.toUpper(node)
def handlePreKeyWhisperMessage(self, pkMessageProtocolEntity):
preKeyWhisperMessage = PreKeyWhisperMessage(serialized=pkMessageProtocolEntity.getEncData())
sessionCipher = self.getSessionCipher(pkMessageProtocolEntity.getFrom(False))
try:
return sessionCipher.decryptPkmsg(preKeyWhisperMessage)
except Exception,e:
return None
def handleWhisperMessage(self, encMessageProtocolEntity):
whisperMessage = WhisperMessage(serialized=encMessageProtocolEntity.getEncData())
sessionCipher = self.getSessionCipher(encMessageProtocolEntity.getFrom(False))
try:
return sessionCipher.decryptMsg(whisperMessage)
except Exception,e:
return None
def onGetKeysResult(self, resultNode, getKeysEntity):
entity = ResultGetKeysIqProtocolEntity.fromProtocolTreeNode(resultNode)
resultJids = entity.getJids()
for jid in getKeysEntity.getJids():
if jid not in resultJids:
self.skipEncJids.append(jid)
self.processPendingMessages(jid)
self.processPendingMessagesFrom(jid)
continue
recipient_id = jid.split('@')[0]
preKeyBundle = entity.getPreKeyBundleFor(jid)
sessionBuilder = SessionBuilder(self.store, self.store, self.store,
self.store, recipient_id, 1)
sessionBuilder.processPreKeyBundle(preKeyBundle)
self.processPendingMessages(jid)
self.processPendingMessagesFrom(jid)
def processPendingMessagesFrom(self, jid):
if jid in self.pendingMessagesFrom:
for node in self.pendingMessagesFrom[jid]:
self.handleEncMessage(node)
del self.pendingMessagesFrom[jid] |
@tgalal I got it! I don't know if you're interested in the solution, worthing a pull request.. But I created a new protocol entity to ask Whatsapp to retry the message after my session was created, and then this new retry comes with ratcket keys I can decrypt :) |
retry receipt node PR would be cool |
yowsup.layers.protocol_receipts.protocolentities.retry_receipt_outgoing from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .receipt_outgoing import OutgoingReceiptProtocolEntity
from yowsup.layers.axolotl.protocolentities.iq_keys_get_result import ResultGetKeysIqProtocolEntity
class RetryReceiptProtocolEntity(OutgoingReceiptProtocolEntity):
'''
<receipt type="retry" to="xxxxxxxxxxx@s.whatsapp.net" id="1415389947-12" t="1432833777">
<retry count="1" t="1432833266" id="1415389947-12" v="1">
</retry>
<registration>
HEX:xxxxxxxxx
</registration>
</receipt>
'''
def __init__(self, _id, to, t, v = "1", count = "1",regData = ""):
super(RetryReceiptProtocolEntity, self).__init__(_id,to)
self.setRetryData(t,v,count,regData)
def setRetryData(self, t,v,count,regData):
self.t = t
self.v = v
self.count = count
self.regData = regData
def setRegData(self,regData):
'''
In axolotl layer:
regData = self.store.getLocalRegistrationId()
'''
self.regData = ResultGetKeysIqProtocolEntity._intToBytes(regData)
def toProtocolTreeNode(self):
node = super(RetryReceiptProtocolEntity, self).toProtocolTreeNode()
node.setAttribute("type", "retry")
retry = ProtocolTreeNode("retry", {"count": self.count,"t":self.t,"id":self.getId(),"v":self.v})
node.addChild(retry)
registration = ProtocolTreeNode("registration",data=self.regData)
node.addChild(registration)
return node
def __str__(self):
out = super(RetryReceiptProtocolEntity, self).__str__()
return out
@staticmethod
def fromProtocolTreeNode(MessageNodeToBeRetried):
return RetryReceiptProtocolEntity(
MessageNodeToBeRetried.getAttributeValue("id"),
MessageNodeToBeRetried.getAttributeValue("from"),
MessageNodeToBeRetried.getAttributeValue("t"),
MessageNodeToBeRetried.getChild("enc").getAttributeValue("v")
) |
@danielapsmaior thanks for the code! |
Please try code from develop branch |
I have same problem, with deployment and with official version. DEBUG:yowsup.layers.logger.layer:rx: ERROR:yowsup.layers.axolotl.layer:No valid sessionsBad Mac! DEBUG:yowsup.layers.logger.layer:rx: |
I removed axolotl.db from my .yowsup folder... last beach. |
yowsup.layers.axolotl.layer:No session for: 3393939337777 but after 10 messages now is working again... |
I seem to be getting this exception for some messages. I have enabled axolotl for encryption.
What might be the issue??
This is the error stack trace.
The text was updated successfully, but these errors were encountered: