summaryrefslogtreecommitdiff
path: root/protocols/WhatsApp/src/iq.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/WhatsApp/src/iq.cpp')
-rw-r--r--protocols/WhatsApp/src/iq.cpp195
1 files changed, 23 insertions, 172 deletions
diff --git a/protocols/WhatsApp/src/iq.cpp b/protocols/WhatsApp/src/iq.cpp
index c0a2c414ac..258b466ac3 100644
--- a/protocols/WhatsApp/src/iq.cpp
+++ b/protocols/WhatsApp/src/iq.cpp
@@ -30,6 +30,8 @@ void WhatsAppProto::OnIqBlockList(const WANode &node)
void WhatsAppProto::OnIqCountPrekeys(const WANode &node)
{
+ m_bUpdatedPrekeys = true;
+
int iCount = node.getChild("count")->getAttrInt("value");
if (iCount < 5)
UploadMorePrekeys();
@@ -78,191 +80,39 @@ void WhatsAppProto::OnIqDoNothing(const WANode &)
/////////////////////////////////////////////////////////////////////////////////////////
-void WhatsAppProto::OnNotifyEncrypt(const WANode &node)
+void WhatsAppProto::OnNotifyDevices(const WANode &node)
{
- auto *pszFrom = node.getAttr("from");
- if (!mir_strcmp(pszFrom, S_WHATSAPP_NET)) {
-
- }
+ if (!mir_strcmp(node.getAttr("jid"), m_szJid))
+ debugLogA("received list of my own devices");
}
/////////////////////////////////////////////////////////////////////////////////////////
-void WhatsAppProto::OnReceiveInfo(const WANode &node)
+void WhatsAppProto::OnNotifyEncrypt(const WANode &node)
{
- if (auto *pChild = node.getFirstChild()) {
- if (pChild->title == "offline") {
- debugLogA("Processed %d offline events", pChild->getAttrInt("count"));
-
- if (getDword("lastResyncTime") == 0) {
- m_impl.m_resyncApp.Stop();
- m_impl.m_resyncApp.Start(1000);
- }
- }
- }
+ if (!mir_strcmp(node.getAttr("from"), S_WHATSAPP_NET))
+ OnIqCountPrekeys(node);
}
/////////////////////////////////////////////////////////////////////////////////////////
-void WhatsAppProto::OnReceiveMessage(const WANode &node)
+void WhatsAppProto::OnReceiveInfo(const WANode &node)
{
- auto *msgId = node.getAttr("id");
- auto *msgType = node.getAttr("type");
- auto *msgFrom = node.getAttr("from");
- auto *category = node.getAttr("category");
- auto *recipient = node.getAttr("recipient");
- auto *participant = node.getAttr("participant");
-
- if (msgType == nullptr || msgFrom == nullptr || msgId == nullptr) {
- debugLogA("bad message received: <%s> <%s> <%s>", msgType, msgFrom, msgId);
- return;
- }
-
- WAMSG type;
- WAJid jid(msgFrom);
- CMStringA szAuthor, szChatId;
-
- if (node.getAttr("offline"))
- type.bOffline = true;
-
- // message from one user to another
- if (jid.isUser()) {
- if (recipient) {
- if (m_szJid != msgFrom) {
- debugLogA("strange message: with recipient, but not from me");
- return;
- }
- szChatId = recipient;
- }
- else szChatId = msgFrom;
-
- type.bPrivateChat = true;
- szAuthor = msgFrom;
- }
- else if (jid.isGroup()) {
- if (!participant) {
- debugLogA("strange message: from group, but without participant");
- return;
- }
-
- type.bGroupChat = true;
- szAuthor = participant;
- szChatId = msgFrom;
- }
- else if (jid.isBroadcast()) {
- if (!participant) {
- debugLogA("strange message: from group, but without participant");
- return;
- }
-
- bool bIsMe = m_szJid == participant;
- if (jid.isStatusBroadcast()) {
- if (bIsMe)
- type.bDirectStatus = true;
- else
- type.bOtherStatus = true;
- }
- else {
- if (bIsMe)
- type.bPeerBroadcast = true;
- else
- type.bOtherBroadcast = true;
- }
- szChatId = msgFrom;
- szAuthor = participant;
- }
- else {
- debugLogA("invalid message type");
- return;
- }
-
- CMStringA szSender = (type.bPrivateChat) ? szAuthor : szChatId;
- bool bFromMe = (m_szJid == msgFrom);
- if (!bFromMe && participant)
- bFromMe = m_szJid == participant;
-
- auto *pKey = new proto::MessageKey();
- pKey->set_remotejid(szChatId);
- pKey->set_id(msgId);
- pKey->set_fromme(bFromMe);
- if (participant)
- pKey->set_participant(participant);
-
- proto::WebMessageInfo msg;
- msg.set_allocated_key(pKey);
- msg.set_messagetimestamp(_atoi64(node.getAttr("t")));
- msg.set_pushname(node.getAttr("notify"));
- if (bFromMe)
- msg.set_status(proto::WebMessageInfo_Status_SERVER_ACK);
-
- int iDecryptable = 0;
-
- for (auto &it: node.getChildren()) {
- if (it->title == "verified_name") {
- proto::VerifiedNameCertificate cert;
- cert << it->content;
+ if (auto *pChild = node.getFirstChild()) {
+ if (pChild->title == "offline") {
+ debugLogA("Processed %d offline events", pChild->getAttrInt("count"));
- proto::VerifiedNameCertificate::Details details;
- details.ParseFromString(cert.details());
-
- msg.set_verifiedbizname(details.verifiedname());
- continue;
- }
-
- if (it->title != "enc" || it->content.length() == 0)
- continue;
-
- SignalBuffer msgBody;
- auto *pszType = it->getAttr("type");
- try {
- if (!mir_strcmp(pszType, "pkmsg") || !mir_strcmp(pszType, "msg")) {
- CMStringA szUser = (WAJid(szSender).isUser()) ? szSender : szAuthor;
- msgBody = m_signalStore.decryptSignalProto(szUser, pszType, it->content);
- }
- else if (!mir_strcmp(pszType, "skmsg")) {
- msgBody = m_signalStore.decryptGroupSignalProto(szSender, szAuthor, it->content);
+ // retrieve loaded prekeys count
+ if (!m_bUpdatedPrekeys)
+ WSSendNode(WANodeIq(IQ::GET, "encrypt") << XCHILD("count"), &WhatsAppProto::OnIqCountPrekeys);
+
+ for (auto &it: m_arCollections) {
+ if (it->version == 0) {
+ m_impl.m_resyncApp.Stop();
+ m_impl.m_resyncApp.Start(1000);
+ break;
+ }
}
- else throw "Invalid e2e type";
-
- if (!msgBody)
- throw "Invalid e2e message";
-
- iDecryptable++;
-
- proto::Message encMsg;
- encMsg.ParseFromArray(msgBody.data(), msgBody.len());
- if (encMsg.devicesentmessage().has_message())
- msg.set_allocated_message(new proto::Message(encMsg.devicesentmessage().message()));
- else
- msg.set_allocated_message(new proto::Message(encMsg));
-
- if (encMsg.has_senderkeydistributionmessage())
- m_signalStore.processSenderKeyMessage(encMsg.senderkeydistributionmessage());
-
- ProcessMessage(type, msg);
- msg.clear_message();
-
- // send receipt
- const char *pszReceiptType = nullptr, *pszReceiptTo = participant;
- if (!mir_strcmp(category, "peer"))
- pszReceiptType = "peer_msg";
- else if (bFromMe) {
- // message was sent by me from a different device
- pszReceiptType = "sender";
- if (WAJid(szChatId).isUser())
- pszReceiptTo = szAuthor;
- }
- else if (!m_hServerConn)
- pszReceiptType = "inactive";
-
- SendReceipt(szChatId, pszReceiptTo, msgId, pszReceiptType);
- }
- catch (const char *) {
- }
-
- if (!iDecryptable) {
- debugLogA("Nothing to decrypt");
- return;
}
}
}
@@ -579,6 +429,7 @@ void WhatsAppProto::InitPersistentHandlers()
m_arPersistent.insert(new WAPersistentHandler("iq", "set", "md", "pair-device", &WhatsAppProto::OnIqPairDevice));
m_arPersistent.insert(new WAPersistentHandler("iq", "set", "md", "pair-success", &WhatsAppProto::OnIqPairSuccess));
+ m_arPersistent.insert(new WAPersistentHandler("notification", "devices", 0, 0, &WhatsAppProto::OnNotifyDevices));
m_arPersistent.insert(new WAPersistentHandler("notification", "encrypt", 0, 0, &WhatsAppProto::OnNotifyEncrypt));
m_arPersistent.insert(new WAPersistentHandler("notification", "account_sync", 0, 0, &WhatsAppProto::OnAccountSync));
m_arPersistent.insert(new WAPersistentHandler("notification", "server_sync", 0, 0, &WhatsAppProto::OnServerSync));