From 456be9f558f2cf23414bdff1aabd0fb5a4866238 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 25 Nov 2022 11:19:16 +0300 Subject: WhatsApp: retrieving keys for multiple jids --- protocols/WhatsApp/src/iq.cpp | 25 ++++++++++++++----------- protocols/WhatsApp/src/message.cpp | 30 ++++++++++++++++++++++-------- protocols/WhatsApp/src/proto.h | 2 +- protocols/WhatsApp/src/server.cpp | 6 ++++-- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/protocols/WhatsApp/src/iq.cpp b/protocols/WhatsApp/src/iq.cpp index ccc9ad6f1a..b9cf5bd7d2 100644 --- a/protocols/WhatsApp/src/iq.cpp +++ b/protocols/WhatsApp/src/iq.cpp @@ -107,7 +107,10 @@ void WhatsAppProto::OnIqGetKeys(const WANode &node, void *pUserInfo) void WhatsAppProto::OnIqGetUsync(const WANode &node, void *pUserInfo) { - if (auto *nUser = node.getChild("usync")->getChild("list")->getChild("user")) { + WANodeIq iq(IQ::GET, "encrypt"); + auto *pKey = iq.addChild("key"); + + for (auto *nUser : node.getChild("usync")->getChild("list")->getChildren()) { auto *pszJid = nUser->getAttr("jid"); auto *pUser = AddUser(pszJid, false); @@ -119,20 +122,17 @@ void WhatsAppProto::OnIqGetUsync(const WANode &node, void *pUserInfo) if (it->title == "device") pUser->arDevices.insert(new WAJid(pszJid, it->getAttrInt("id"))); - WANodeIq iq(IQ::GET, "encrypt"); - auto *pKey = iq.addChild("key"); for (auto &it : pUser->arDevices) { auto blob = getBlob(MSignalSession(it->user, it->device).getSetting()); if (blob.isEmpty()) pKey->addChild("user")->addAttr("jid", it->toString()); } - - if (pKey->getChildren().getCount() > 0) - WSSendNode(iq, &WhatsAppProto::OnIqGetKeys, pUserInfo); - else if (pUserInfo) - FinishTask((WASendTask *)pUserInfo); - } + + if (pKey->getChildren().getCount() > 0) + WSSendNode(iq, &WhatsAppProto::OnIqGetKeys, pUserInfo); + else if (pUserInfo) + FinishTask((WASendTask *)pUserInfo); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -470,8 +470,11 @@ void WhatsAppProto::OnReceiveInfo(const WANode &node) WSSendNode(WANodeIq(IQ::GET, "encrypt") << XCHILD("count"), &WhatsAppProto::OnIqCountPrekeys); auto *pUser = FindUser(m_szJid); - if (pUser->arDevices.getCount() == 0) - SendUsync(m_szJid, nullptr); + if (pUser->arDevices.getCount() == 0) { + LIST jids(1); + jids.insert(m_szJid.GetBuffer()); + SendUsync(jids, nullptr); + } for (auto &it : m_arCollections) { if (it->version == 0) { diff --git a/protocols/WhatsApp/src/message.cpp b/protocols/WhatsApp/src/message.cpp index 2c9149c45b..eef12963f1 100644 --- a/protocols/WhatsApp/src/message.cpp +++ b/protocols/WhatsApp/src/message.cpp @@ -374,7 +374,7 @@ int WhatsAppProto::SendTextMessage(const char *jid, const char *pszMsg) Wa__Message body; body.extendedtextmessage = &extMessage; - bool bNeedsCheck = false; + LIST arCheckList(1); if (toJid.isGroup()) { MBinBuffer encodedMsg(proto::Serialize(&body)); padBuffer16(encodedMsg); @@ -397,10 +397,21 @@ int WhatsAppProto::SendTextMessage(const char *jid, const char *pszMsg) pTask->content.append(proto::Serialize(&msg)); - if (auto *pUser = FindUser(jid)) - if (pUser->si) - for (auto &it : pUser->si->arUsers) - pTask->arDest.insert(new WAJid(T2Utf(it->pszUID))); + if (auto *pChatUser = FindUser(jid)) { + if (pChatUser->si) { + for (auto &it : pChatUser->si->arUsers) { + T2Utf userJid(it->pszUID); + auto *pUser = FindUser(jid); + if (pUser == nullptr) + m_arUsers.insert(pUser = new WAUser(INVALID_CONTACT_ID, userJid, false)); + if (pUser->bDeviceInit) { + for (auto &jt : pUser->arDevices) + pTask->arDest.insert(new WAJid(*jt)); + } + else arCheckList.insert(mir_strdup(userJid)); + } + } + } } else { Wa__Message__DeviceSentMessage sentBody; @@ -417,7 +428,7 @@ int WhatsAppProto::SendTextMessage(const char *jid, const char *pszMsg) for (auto &it : pUser->arDevices) pTask->arDest.insert(new WAJid(*it)); } - else bNeedsCheck = true; + else arCheckList.insert(mir_strdup(jid));; } } @@ -437,8 +448,11 @@ int WhatsAppProto::SendTextMessage(const char *jid, const char *pszMsg) } // if some keys are missing, schedule task for execution & retrieve keys - if (bNeedsCheck) - SendUsync(jid, pTask); + if (arCheckList.getCount()) { + SendUsync(arCheckList, pTask); + for (auto &it : arCheckList) + mir_free(it); + } else // otherwise simply execute the task SendTask(pTask); diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h index b192696410..0d4fd624a0 100644 --- a/protocols/WhatsApp/src/proto.h +++ b/protocols/WhatsApp/src/proto.h @@ -373,7 +373,7 @@ class WhatsAppProto : public PROTO void SendReceipt(const char *pszTo, const char *pszParticipant, const char *pszId, const char *pszType); void SendKeepAlive(); int SendTextMessage(const char *jid, const char *pszMsg); - void SendUsync(const char *jid, void *pUserInfo); + void SendUsync(const LIST &jids, void *pUserInfo); void SetServerStatus(int iStatus); void FinishTask(WASendTask *pTask); diff --git a/protocols/WhatsApp/src/server.cpp b/protocols/WhatsApp/src/server.cpp index df9e3ec86e..8e211535e7 100644 --- a/protocols/WhatsApp/src/server.cpp +++ b/protocols/WhatsApp/src/server.cpp @@ -399,7 +399,7 @@ void WhatsAppProto::SetServerStatus(int iStatus) &WhatsAppProto::OnIqDoNothing); } -void WhatsAppProto::SendUsync(const char *jid, void *pUserInfo) +void WhatsAppProto::SendUsync(const LIST &jids, void *pUserInfo) { WANodeIq iq(IQ::GET, "usync"); @@ -408,7 +408,9 @@ void WhatsAppProto::SendUsync(const char *jid, void *pUserInfo) << CHAR_PARAM("index", "0") << CHAR_PARAM("context", "message"); pNode1->addChild("query")->addChild("devices")->addAttr("version", "2"); - pNode1->addChild("list")->addChild("user")->addAttr("jid", jid); + auto *pList = pNode1->addChild("list"); + for (auto &it : jids) + pList->addChild("user")->addAttr("jid", it); WSSendNode(iq, &WhatsAppProto::OnIqGetUsync, pUserInfo); } -- cgit v1.2.3