diff options
author | George Hazan <ghazan@miranda.im> | 2022-09-28 21:26:25 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2022-09-28 21:26:25 +0300 |
commit | cd30b43a4da9327cb5d7cb054b889350aedcf7e7 (patch) | |
tree | 24885fd24c0ecb77fe7f1bb782bd71f0549d62dc /protocols/WhatsAppWeb | |
parent | 96b7e711d06d0a673daf76a12c2bff4de14b0502 (diff) |
code cleaning
Diffstat (limited to 'protocols/WhatsAppWeb')
-rw-r--r-- | protocols/WhatsAppWeb/src/proto.cpp | 2 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/proto.h | 4 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/server.cpp | 4 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/utils.cpp | 39 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/utils.h | 11 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/wareader.cpp | 104 |
6 files changed, 89 insertions, 75 deletions
diff --git a/protocols/WhatsAppWeb/src/proto.cpp b/protocols/WhatsAppWeb/src/proto.cpp index c21b6e24c7..65b449807b 100644 --- a/protocols/WhatsAppWeb/src/proto.cpp +++ b/protocols/WhatsAppWeb/src/proto.cpp @@ -253,7 +253,7 @@ int WhatsAppProto::SendMsg(MCONTACT hContact, int, const char *pszMsg) payLoad.addAttr("type", "relay"); payLoad.content.assign(pBuf, cbBinaryLen); - int pktId = WSSendNode(0, payLoad); + int pktId = WSSendNode(payLoad); mir_cslock lck(m_csOwnMessages); m_arOwnMsgs.insert(new WAOwnMessage(pktId, hContact, szMsgId)); diff --git a/protocols/WhatsAppWeb/src/proto.h b/protocols/WhatsAppWeb/src/proto.h index 54ec389933..3383ee6306 100644 --- a/protocols/WhatsAppWeb/src/proto.h +++ b/protocols/WhatsAppWeb/src/proto.h @@ -8,6 +8,7 @@ Copyright © 2019-22 George Hazan #if !defined(PROTO_H) #define PROTO_H +#define S_WHATSAPP_NET "@s.whatsapp.net" #define APP_VERSION "2.2230.15" #define KEY_BUNDLE_TYPE "\x05" @@ -159,7 +160,6 @@ class WhatsAppProto : public PROTO<WhatsAppProto> /// Network //////////////////////////////////////////////////////////////////////////// - int m_iPktNumber; time_t m_iLoginTime; HNETLIBCONN m_hServerConn; @@ -168,7 +168,7 @@ class WhatsAppProto : public PROTO<WhatsAppProto> bool WSReadPacket(const WSHeader &hdr, MBinBuffer &buf); int WSSend(const MessageLite &msg, WA_PKT_HANDLER = nullptr, void *pUserIndo = nullptr); - int WSSendNode(int flags, WANode &node, WA_PKT_HANDLER = nullptr); + int WSSendNode(WANode &node, WA_PKT_HANDLER = nullptr); void OnLoggedIn(void); void OnLoggedOut(void); diff --git a/protocols/WhatsAppWeb/src/server.cpp b/protocols/WhatsAppWeb/src/server.cpp index 1ffa435579..192e203521 100644 --- a/protocols/WhatsAppWeb/src/server.cpp +++ b/protocols/WhatsAppWeb/src/server.cpp @@ -70,6 +70,9 @@ void WhatsAppProto::ShutdownSession() void WhatsAppProto::OnStartSession(const WANode &node) { + WANode reply("iq"); + reply << CHAR_PARAM("to", S_WHATSAPP_NET) << CHAR_PARAM("type", "result") << CHAR_PARAM("id", node.getAttr("id")); + WSSendNode(reply); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -256,7 +259,6 @@ bool WhatsAppProto::ServerThreadWorker() debugLogA("Server connection succeeded"); m_hServerConn = pReply->nlc; m_iLoginTime = time(0); - m_iPktNumber = 0; m_szClientToken = getMStringA(DBKEY_CLIENT_TOKEN); auto &pubKey = m_noise->ephemeral.pub; diff --git a/protocols/WhatsAppWeb/src/utils.cpp b/protocols/WhatsAppWeb/src/utils.cpp index 9d62432a10..85c545273a 100644 --- a/protocols/WhatsAppWeb/src/utils.cpp +++ b/protocols/WhatsAppWeb/src/utils.cpp @@ -76,46 +76,27 @@ int WhatsAppProto::WSSend(const MessageLite &msg, WA_PKT_HANDLER pHandler, void static char zeroData[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -int WhatsAppProto::WSSendNode(int flags, WANode &node, WA_PKT_HANDLER pHandler) +int WhatsAppProto::WSSendNode(WANode &node, WA_PKT_HANDLER pHandler) { if (m_hServerConn == nullptr) return 0; - { - char str[100]; - _i64toa(_time64(0), str, 10); - node.addAttr("epoch", str); - - CMStringA szText; - node.print(szText); - debugLogA("Sending binary node: %s", szText.c_str()); - } + CMStringA szText; + node.print(szText); + debugLogA("Sending binary node: %s", szText.c_str()); WAWriter writer; writer.writeNode(&node); - // AES block size = 16 bytes, let's expand data to block size boundary - size_t rest = writer.body.length() % 16; - if (rest != 0) - writer.body.append(zeroData, 16 - rest); - - BYTE iv[16]; - Utils_GetRandom(iv, sizeof(iv)); - - int pktId = ++m_iPktNumber; - if (pHandler != nullptr) { mir_cslock lck(m_csPacketQueue); m_arPacketQueue.insert(new WARequest(pHandler)); } - char postPrefix[3] = {',', 0, (char)flags}; - - MBinBuffer ret; - ret.append(postPrefix, sizeof(postPrefix)); - WebSocket_SendBinary(m_hServerConn, ret.data(), ret.length()); - - return pktId; + MBinBuffer encData = m_noise->encrypt(writer.body.data(), writer.body.length()); + MBinBuffer payload = m_noise->encodeFrame(encData.data(), encData.length()); + WebSocket_SendBinary(m_hServerConn, payload.data(), payload.length()); + return 1; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -124,6 +105,10 @@ int WhatsAppProto::WSSendNode(int flags, WANode &node, WA_PKT_HANDLER pHandler) WANode::WANode() {} +WANode::WANode(const char *pszTitle) : + title(pszTitle) +{} + WANode::~WANode() { for (auto &p: attrs) diff --git a/protocols/WhatsAppWeb/src/utils.h b/protocols/WhatsAppWeb/src/utils.h index 72d69c96f0..dfa98705c6 100644 --- a/protocols/WhatsAppWeb/src/utils.h +++ b/protocols/WhatsAppWeb/src/utils.h @@ -41,6 +41,7 @@ class WANode // kinda XML public: WANode(); + WANode(const char *pszTitle); ~WANode(); void addAttr(const char *pszName, const char *pszValue); @@ -53,6 +54,12 @@ public: std::list<WANode*> children; }; +__forceinline WANode& operator<<(WANode &node, const CHAR_PARAM ¶m) +{ + node.addAttr(param.szName, param.szValue); + return node; +} + class WAReader { const BYTE *m_buf, *m_limit; @@ -91,8 +98,8 @@ class WAWriter void writeInt20(int value); void writeLength(int value); void writeListSize(int tag); - void writePacked(const CMStringA &str); - void writeString(const char *str, bool bRaw = false); + void writePacked(const CMStringA &str, int tag); + void writeString(const char *str); bool writeToken(const char *str); public: diff --git a/protocols/WhatsAppWeb/src/wareader.cpp b/protocols/WhatsAppWeb/src/wareader.cpp index 0f6df4b31a..30d9aab7c0 100644 --- a/protocols/WhatsAppWeb/src/wareader.cpp +++ b/protocols/WhatsAppWeb/src/wareader.cpp @@ -190,18 +190,27 @@ CMStringA WAReader::readPacked(int tag) CMStringA WAReader::readString(int tag) { - if (tag >= 1 && tag < _countof(SingleByteTokens)) { - CMStringA ret = SingleByteTokens[tag]; - if (ret == "s.whatsapp.net") - return "c.us"; - return ret; - } + if (tag >= 1 && tag < _countof(SingleByteTokens)) + return SingleByteTokens[tag]; + int idx; switch (tag) { - case DICTIONARY_0: return dict0[readInt8()]; - case DICTIONARY_1: return dict1[readInt8()]; - case DICTIONARY_2: return dict2[readInt8()]; - case DICTIONARY_3: return dict3[readInt8()]; + case DICTIONARY_0: + idx = readInt8(); + return (idx < _countof(dict0)) ? dict0[idx] : ""; + + case DICTIONARY_1: + idx = readInt8(); + return (idx < _countof(dict1)) ? dict1[idx] : ""; + + case DICTIONARY_2: + idx = readInt8(); + return (idx < _countof(dict2)) ? dict2[idx] : ""; + + case DICTIONARY_3: + idx = readInt8(); + return (idx < _countof(dict3)) ? dict3[idx] : ""; + case LIST_EMPTY: return ""; @@ -302,6 +311,9 @@ void WAWriter::writeListSize(int length) void WAWriter::writeNode(const WANode *pNode) { + // we never send zipped content + writeByte(0); + int numAttrs = (int)pNode->attrs.size(); int hasContent = pNode->content.length() != 0; writeListSize(2 * numAttrs + 1 + hasContent); @@ -331,32 +343,6 @@ void WAWriter::writeNode(const WANode *pNode) } } -void WAWriter::writeString(const char *str, bool bRaw) -{ - if (!bRaw && !mir_strcmp(str, "c.us")) { - writeToken("s.whatsapp.net"); - return; - } - - if (writeToken(str)) - return; - - auto *pszDelimiter = strchr(str, '@'); - if (pszDelimiter) { - writeByte(JID_PAIR); - - if (pszDelimiter == str) // empty jid - writeByte(LIST_EMPTY); - else - writePacked(CMStringA(str, int(pszDelimiter - str))); - } - else { - int len = (int)strlen(str); - writeLength(len); - body.append(str, len); - } -} - bool WAWriter::writeToken(const char *str) { for (auto &it : SingleByteTokens) @@ -408,22 +394,56 @@ static BYTE packPair(int type, char c1, char c2) return (b1 << 4) + b2; } -void WAWriter::writePacked(const CMStringA &str) +static bool isNibble(const CMStringA &str) +{ + return strspn(str, "0123456789-.") == str.GetLength(); +} + +static bool isHex(const CMStringA &str) +{ + return strspn(str, "0123456789abcdefABCDEF-.") == str.GetLength(); +} + +void WAWriter::writePacked(const CMStringA &str, int tag) { if (str.GetLength() > 254) return; - // all symbols of str can be a nibble? - int type = (strspn(str, "0123456789-.") == str.GetLength()) ? NIBBLE_8 : HEX_8; - int len = str.GetLength() / 2; BYTE firstByte = (len % 2) == 0 ? 0 : 0x80; writeByte(firstByte | len); const char *p = str; for (int i = 0; i < len; i++, p += 2) - writeByte(packPair(type, p[0], p[1])); + writeByte(packPair(tag, p[0], p[1])); if (firstByte != 0) - writeByte(packPair(type, p[0], 0)); + writeByte(packPair(tag, p[0], 0)); +} + +void WAWriter::writeString(const char *str) +{ + if (writeToken(str)) + return; + + auto *pszDelimiter = strchr(str, '@'); + if (pszDelimiter) { + writeByte(JID_PAIR); + + if (pszDelimiter == str) // empty jid + writeByte(LIST_EMPTY); + else + writeString(CMStringA(str, int(pszDelimiter - str))); + } + else { + CMStringA buf(str); + if (isNibble(buf)) + writePacked(buf, NIBBLE_8); + else if (isHex(buf)) + writePacked(buf, HEX_8); + else { + writeLength(buf.GetLength()); + body.append(buf, buf.GetLength()); + } + } } |