summaryrefslogtreecommitdiff
path: root/protocols/WhatsAppWeb/src/server.cpp
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-10-15 13:06:52 +0300
committerGeorge Hazan <ghazan@miranda.im>2019-10-15 13:06:52 +0300
commit71c1ad117340f089d4820bf7c7bddce20a5e113a (patch)
treefb53900b4db14e958d3445c8ebd634073835d6f6 /protocols/WhatsAppWeb/src/server.cpp
parentfb3fad1e6519b029cd06e7c7113fc948aaef6770 (diff)
WhatsAppWeb: session restoration code
Diffstat (limited to 'protocols/WhatsAppWeb/src/server.cpp')
-rw-r--r--protocols/WhatsAppWeb/src/server.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/protocols/WhatsAppWeb/src/server.cpp b/protocols/WhatsAppWeb/src/server.cpp
index 3a682e00fa..be9fc55200 100644
--- a/protocols/WhatsAppWeb/src/server.cpp
+++ b/protocols/WhatsAppWeb/src/server.cpp
@@ -199,10 +199,57 @@ void WhatsAppProto::OnLoggedOut(void)
setAllContactStatuses(ID_STATUS_OFFLINE, false);
}
+//////////////////////////////////////////////////////////////////////////////////////
+
+void WhatsAppProto::ProcessChallenge(const CMStringA &szChallenge)
+{
+ if (mac_key.isEmpty()) {
+ ShutdownSession();
+ return;
+ }
+
+ size_t cbLen;
+ void *pChallenge = mir_base64_decode(szChallenge, &cbLen);
+
+ BYTE digest[32];
+ unsigned cbResult = sizeof(digest);
+ HMAC(EVP_sha256(), mac_key.data(), mac_key.length(), (BYTE*)pChallenge, cbLen, digest, &cbResult);
+
+ ptrA szServer(getStringA(DBKEY_SERVER_TOKEN));
+ CMStringA payload(FORMAT, "[\"admin\",\"challenge\",\"%s\",\"%s\",\"%s\"]",
+ ptrA(mir_base64_encode(digest, cbResult)).get(), szServer.get(), m_szClientId.c_str());
+ WSSend(payload);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+
void WhatsAppProto::RestoreSession()
{
+ ptrA szClient(getStringA(DBKEY_CLIENT_TOKEN)), szServer(getStringA(DBKEY_SERVER_TOKEN));
+ if (szClient == nullptr || szServer == nullptr) {
+ ShutdownSession();
+ return;
+ }
+
+ CMStringA payload(FORMAT, "[\"admin\",\"login\",\"%s\",\"%s\",\"%s\",\"takeover\"]", szClient.get(), szServer.get(), m_szClientId.c_str());
+ WSSend(payload, &WhatsAppProto::OnRestoreSession);
+}
+
+void WhatsAppProto::OnRestoreSession(const JSONNode &root)
+{
+ int status = root["status"].as_int();
+ if (status != 200) {
+ debugLogA("Attmept to restore session failed with error %d", status);
+ delSetting(DBKEY_CLIENT_TOKEN);
+ delSetting(DBKEY_SERVER_TOKEN);
+
+ ShutdownSession();
+ return;
+ }
}
+//////////////////////////////////////////////////////////////////////////////////////
+
void WhatsAppProto::ShutdownSession()
{
if (m_bTerminated)
@@ -217,6 +264,8 @@ void WhatsAppProto::ShutdownSession()
OnLoggedOut();
}
+//////////////////////////////////////////////////////////////////////////////////////
+
void WhatsAppProto::StartSession()
{
CMStringA payload(FORMAT, "[\"admin\",\"init\",[0,3,4940],[\"Windows\",\"Chrome\",\"10\"],\"%s\",true]", m_szClientId.c_str());
@@ -400,6 +449,18 @@ void WhatsAppProto::ProcessPacket(const JSONNode &root)
if (szType == "Conn")
ProcessConn(content);
+ else if (szType == "Cmd")
+ ProcessCmd(content);
+}
+
+void WhatsAppProto::ProcessCmd(const JSONNode &root)
+{
+ CMStringW wszType(root["type"].as_mstring());
+ if (wszType == L"challenge") {
+ CMStringA szChallenge(root["challenge"].as_mstring());
+ if (!szChallenge.IsEmpty())
+ ProcessChallenge(szChallenge);
+ }
}
void WhatsAppProto::ProcessConn(const JSONNode &root)