diff options
author | dartraiden <wowemuh@gmail.com> | 2022-10-19 23:10:42 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2022-10-19 23:10:42 +0300 |
commit | f9842d5d09edeb40f296e9f09be9cc22ac810d41 (patch) | |
tree | a9dd970b81922851986e1611ad9e013894d711d0 /protocols/WhatsAppWeb/src/utils.cpp | |
parent | f56f50c2dcbd452868520a58c9ae811108545c0e (diff) |
Rename WhatsAppWeb to WhatsApp
Diffstat (limited to 'protocols/WhatsAppWeb/src/utils.cpp')
-rw-r--r-- | protocols/WhatsAppWeb/src/utils.cpp | 373 |
1 files changed, 0 insertions, 373 deletions
diff --git a/protocols/WhatsAppWeb/src/utils.cpp b/protocols/WhatsAppWeb/src/utils.cpp deleted file mode 100644 index c176a894fe..0000000000 --- a/protocols/WhatsAppWeb/src/utils.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* - -WhatsAppWeb plugin for Miranda NG -Copyright © 2019-22 George Hazan - -*/ - -#include "stdafx.h" - -WAJid::WAJid(const char *pszUser, const char *pszServer, int iDevice, int iAgent) : - user(pszUser ? pszUser : ""), - server(pszServer ? pszServer : ""), - device(iDevice), - agent(iAgent) -{} - -WAJid::WAJid(const char *pszJid) -{ - if (pszJid == nullptr) - pszJid = ""; - - auto *tmp = NEWSTR_ALLOCA(pszJid); - auto *p = strrchr(tmp, '@'); - if (p) { - *p = 0; - server = p + 1; - } - - if (p = strrchr(tmp, ':')) { - *p = 0; - device = atoi(p + 1); - } - else device = 0; - - if (p = strrchr(tmp, '_')) { - *p = 0; - agent = atoi(p + 1); - } - else agent = 0; - - user = tmp; -} - -bool WAJid::isUser() const -{ return server == "s.whatsapp.net"; -} - -bool WAJid::isGroup() const -{ return server == "g.us"; -} - -bool WAJid::isBroadcast() const -{ - return server == "broadcast"; -} - -bool WAJid::isStatusBroadcast() const -{ - return isBroadcast() && user == "status"; -} - -CMStringA WAJid::toString() const -{ - CMStringA ret(user); - if (agent > 0) - ret.AppendFormat("_%d", agent); - if (device > 0) - ret.AppendFormat(":%d", device); - ret.AppendFormat("@%s", server.c_str()); - return ret; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -WAUser* WhatsAppProto::FindUser(const char *szId) -{ - mir_cslock lck(m_csUsers); - auto *tmp = (WAUser *)_alloca(sizeof(WAUser)); - tmp->szId = (char*)szId; - return m_arUsers.find(tmp); -} - -WAUser* WhatsAppProto::AddUser(const char *szId, bool bTemporary, bool isChat) -{ - auto *pUser = FindUser(szId); - if (pUser != nullptr) - return pUser; - - MCONTACT hContact = db_add_contact(); - Proto_AddToContact(hContact, m_szModuleName); - - if (isChat) { - setByte(hContact, "ChatRoom", 1); - setString(hContact, "ChatRoomID", szId); - } - else { - setString(hContact, DBKEY_JID, szId); - if (m_wszDefaultGroup) - Clist_SetGroup(hContact, m_wszDefaultGroup); - } - - if (bTemporary) - Contact::RemoveFromList(hContact); - - pUser = new WAUser(hContact, mir_strdup(szId)); - pUser->bIsGroupChat = isChat; - - mir_cslock lck(m_csUsers); - m_arUsers.insert(pUser); - return pUser; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -WA_PKT_HANDLER WhatsAppProto::FindPersistentHandler(const WANode &pNode) -{ - auto *pChild = pNode.getFirstChild(); - CMStringA szChild = (pChild) ? pChild->title : ""; - CMStringA szTitle = pNode.title; - CMStringA szType = pNode.getAttr("type"); - CMStringA szXmlns = pNode.getAttr("xmlns"); - - for (auto &it : m_arPersistent) { - if (it->pszTitle && szTitle != it->pszTitle) - continue; - if (it->pszType && szType != it->pszType) - continue; - if (it->pszXmlns && szXmlns != it->pszXmlns) - continue; - if (it->pszChild && szChild != it->pszChild) - continue; - return it->pHandler; - } - - return nullptr; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -CMStringA WhatsAppProto::GenerateMessageId() -{ - return CMStringA(FORMAT, "%d.%d-%d", m_wMsgPrefix[0], m_wMsgPrefix[1], m_iPacketId++); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// sends a piece of JSON to a server via a websocket, masked - -int WhatsAppProto::WSSend(const MessageLite &msg) -{ - if (m_hServerConn == nullptr) - return -1; - - int cbLen = msg.ByteSize(); - ptrA protoBuf((char *)mir_alloc(cbLen)); - msg.SerializeToArray(protoBuf, cbLen); - - Netlib_Dump(m_hServerConn, protoBuf, cbLen, true, 0); - - MBinBuffer payload = m_noise->encodeFrame(protoBuf, cbLen); - WebSocket_SendBinary(m_hServerConn, payload.data(), payload.length()); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static char zeroData[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -int WhatsAppProto::WSSendNode(WANode &node, WA_PKT_HANDLER pHandler) -{ - if (m_hServerConn == nullptr) - return 0; - - if (pHandler != nullptr) { - CMStringA id(GenerateMessageId()); - node.addAttr("id", id); - - mir_cslock lck(m_csPacketQueue); - m_arPacketQueue.insert(new WARequest(id, pHandler)); - } - - CMStringA szText; - node.print(szText); - debugLogA("Sending binary node:\n%s", szText.c_str()); - - WAWriter writer; - writer.writeNode(&node); - - 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; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -uint32_t decodeBigEndian(const std::string &buf) -{ - uint32_t ret = 0; - for (auto &cc : buf) { - ret <<= 8; - ret += (uint8_t)cc; - } - - return ret; -} - -std::string encodeBigEndian(uint32_t num, size_t len) -{ - std::string res; - for (int i = 0; i < len; i++) { - char c = num & 0xFF; - res = c + res; - num >>= 8; - } - return res; -} - -void generateIV(uint8_t *iv, int &pVar) -{ - auto counter = encodeBigEndian(pVar); - memset(iv, 0, sizeof(iv)); - memcpy(iv + 8, counter.c_str(), sizeof(int)); - - pVar++; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Popups - -void WhatsAppProto::InitPopups(void) -{ - g_plugin.addPopupOption(CMStringW(FORMAT, TranslateT("%s error notifications"), m_tszUserName), m_bUsePopups); - - char name[256]; - mir_snprintf(name, "%s_%s", m_szModuleName, "Error"); - - wchar_t desc[256]; - mir_snwprintf(desc, L"%s/%s", m_tszUserName, TranslateT("Errors")); - - POPUPCLASS ppc = {}; - ppc.flags = PCF_UNICODE; - ppc.pszName = name; - ppc.pszDescription.w = desc; - ppc.hIcon = IcoLib_GetIconByHandle(m_hProtoIcon); - ppc.colorBack = RGB(191, 0, 0); //Red - ppc.colorText = RGB(255, 245, 225); //Yellow - ppc.iSeconds = 60; - m_hPopupClass = Popup_RegisterClass(&ppc); - - IcoLib_ReleaseIcon(ppc.hIcon); -} - -void WhatsAppProto::Popup(MCONTACT hContact, const wchar_t *szMsg, const wchar_t *szTitle) -{ - if (!m_bUsePopups) - return; - - char name[256]; - mir_snprintf(name, "%s_%s", m_szModuleName, "Error"); - - CMStringW wszTitle(szTitle); - if (hContact == 0) { - wszTitle.Insert(0, L": "); - wszTitle.Insert(0, m_tszUserName); - } - - POPUPDATACLASS ppd = {}; - ppd.szTitle.w = wszTitle; - ppd.szText.w = szMsg; - ppd.pszClassName = name; - ppd.hContact = hContact; - Popup_AddClass(&ppd); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -MBinBuffer WhatsAppProto::unzip(const MBinBuffer &src) -{ - z_stream strm = {}; - inflateInit(&strm); - - strm.avail_in = (uInt)src.length(); - strm.next_in = (Bytef *)src.data(); - - MBinBuffer res; - Bytef buf[2048]; - - while (strm.avail_in > 0) { - strm.avail_out = sizeof(buf); - strm.next_out = buf; - - int ret = inflate(&strm, Z_NO_FLUSH); - switch (ret) { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; - __fallthrough; - - case Z_DATA_ERROR: - case Z_MEM_ERROR: - inflateEnd(&strm); - return res; - } - - res.append(buf, sizeof(buf) - strm.avail_out); - } - - inflateEnd(&strm); - return res; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void bin2file(const MBinBuffer &buf, const wchar_t *pwszFileName) -{ - int fileId = _wopen(pwszFileName, _O_WRONLY | _O_TRUNC | _O_BINARY | _O_CREAT, _S_IREAD | _S_IWRITE); - if (fileId != -1) { - write(fileId, buf.data(), (unsigned)buf.length()); - close(fileId); - } -} - -void string2file(const std::string &str, const wchar_t *pwszFileName) -{ - int fileId = _wopen(pwszFileName, _O_WRONLY | _O_TRUNC | _O_BINARY | _O_CREAT, _S_IREAD | _S_IWRITE); - if (fileId != -1) { - write(fileId, str.c_str(), (unsigned)str.size()); - close(fileId); - } -} - -CMStringA directPath2url(const char *pszDirectPath) -{ - return CMStringA("https://mmg.whatsapp.net") + pszDirectPath; -} - -MBinBuffer WhatsAppProto::DownloadEncryptedFile(const char *url, const std::string &mediaKeys, const char *pszMediaType) -{ - NETLIBHTTPHEADER headers[1] = {{"Origin", "https://web.whatsapp.com"}}; - - NETLIBHTTPREQUEST req = {}; - req.cbSize = sizeof(req); - req.requestType = REQUEST_GET; - req.szUrl = (char*)url; - req.headersCount = _countof(headers); - req.headers = headers; - - MBinBuffer ret; - auto *pResp = Netlib_HttpTransaction(m_hNetlibUser, &req); - if (pResp) { - if (pResp->resultCode == 200) { - CMStringA pszHkdfString = pszMediaType; - pszHkdfString.SetAt(_toupper(pszHkdfString[0]), 0); - pszHkdfString = "WhatsApp " + pszHkdfString + " Keys"; - - // 0 - 15: iv - // 16 - 47: cipherKey - // 48 - 111: macKey - uint8_t out[112]; - HKDF(EVP_sha256(), (BYTE *)"", 0, (BYTE *)mediaKeys.c_str(), (int)mediaKeys.size(), (BYTE *)pszHkdfString.c_str(), pszHkdfString.GetLength(), out, sizeof(out)); - - ret = aesDecrypt(EVP_aes_256_cbc(), out + 16, out, pResp->pData, pResp->dataLength); - } - } - - return ret; -} - -CMStringW WhatsAppProto::GetTmpFileName(const char *pszClass, const char *pszAddition) -{ - CMStringW ret(VARSW(L"%miranda_userdata%")); - ret.AppendFormat(L"/%S/%S_%S", m_szModuleName, pszClass, pszAddition); - return ret; -} |