summaryrefslogtreecommitdiff
path: root/protocols/ICQ-WIM/src/server.cpp
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-03-11 20:14:39 +0300
committerGeorge Hazan <ghazan@miranda.im>2019-03-11 20:14:39 +0300
commit35b203ece84f45a3ebc51f164e3710e0504df648 (patch)
tree32008e21776e712dcfe273b1f7107fbf61ecfa21 /protocols/ICQ-WIM/src/server.cpp
parent657afe8e174e6f0e9a2de1848546db8caa19dad4 (diff)
fixes #1741 (ICQ10: Invalid Request. statusDetailCode 1015)
Diffstat (limited to 'protocols/ICQ-WIM/src/server.cpp')
-rw-r--r--protocols/ICQ-WIM/src/server.cpp30
1 files changed, 23 insertions, 7 deletions
diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp
index 217760f12c..27e813e940 100644
--- a/protocols/ICQ-WIM/src/server.cpp
+++ b/protocols/ICQ-WIM/src/server.cpp
@@ -387,9 +387,9 @@ bool CIcqProto::RefreshRobustToken()
bool bRet = false;
auto *tmp = new AsyncHttpRequest(CONN_RAPI, REQUEST_POST, ICQ_ROBUST_SERVER "/genToken");
- time_t ts = time(0);
+ time_t ts = TS();
tmp << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("k", ICQ_APP_ID)
- << CHAR_PARAM("nonce", CMStringA(FORMAT, "%d-%d", ts, rand() % 10)) << INT_PARAM("ts", ts);
+ << CHAR_PARAM("nonce", CMStringA(FORMAT, "%d-%d", ts, rand() % 10)) << INT_PARAM("ts", TS());
CalcHash(tmp);
tmp->flags |= NLHRF_PERSISTENT;
tmp->nlc = m_ConnPool[CONN_RAPI].s;
@@ -547,7 +547,7 @@ void CIcqProto::StartSession()
RpcStringFreeA(&szId);
}
- int ts = time(0);
+ int ts = TS();
CMStringA nonce(FORMAT, "%d-2", ts);
CMStringA caps(WIM_CAP_UNIQ_REQ_ID "," WIM_CAP_EMOJI "," WIM_CAP_MAIL_NOTIFICATIONS "," WIM_CAP_INTRO_DLG_STATE);
if (g_bSecureIM) {
@@ -635,6 +635,9 @@ void CIcqProto::OnCheckPassword(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
if (szUin)
m_szOwnId = szUin;
+ int srvTS = data["hostTime"].as_int();
+ m_iTimeShift = (srvTS) ? time(0) - srvTS : 0;
+
StartSession();
}
@@ -681,7 +684,7 @@ void CIcqProto::OnFileContinue(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld
}
pReq << AIMSID(this) << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("k", ICQ_APP_ID) << CHAR_PARAM("mentions", "") << WCHAR_PARAM("message", wszUrl)
- << CHAR_PARAM("offlineIM", "true") << WCHAR_PARAM("parts", wszParts) << WCHAR_PARAM("t", GetUserId(pTransfer->pfts.hContact)) << INT_PARAM("ts", time(0));
+ << CHAR_PARAM("offlineIM", "true") << WCHAR_PARAM("parts", wszParts) << WCHAR_PARAM("t", GetUserId(pTransfer->pfts.hContact)) << INT_PARAM("ts", TS());
Push(pReq);
}
else ProtoBroadcastAck(pTransfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, pTransfer);
@@ -691,7 +694,7 @@ void CIcqProto::OnFileContinue(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld
// else send the next portion
auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_POST, pTransfer->m_szHost, &CIcqProto::OnFileContinue);
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("k", ICQ_APP_ID) << INT_PARAM("ts", time(0));
+ pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("k", ICQ_APP_ID) << INT_PARAM("ts", TS());
CalcHash(pReq);
pReq->m_szUrl.AppendChar('?');
pReq->m_szUrl += pReq->m_szParam; pReq->m_szParam.Empty();
@@ -722,7 +725,7 @@ void CIcqProto::OnFileInit(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld)
pTransfer->m_szHost = L"https://" + wszHost + wszUrl;
auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_POST, pTransfer->m_szHost, &CIcqProto::OnFileContinue);
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("k", ICQ_APP_ID) << INT_PARAM("ts", time(0));
+ pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("k", ICQ_APP_ID) << INT_PARAM("ts", TS());
CalcHash(pReq);
pReq->m_szUrl.AppendChar('?');
pReq->m_szUrl += pReq->m_szParam; pReq->m_szParam.Empty();
@@ -764,7 +767,7 @@ void CIcqProto::OnGetUserInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
ProtoBroadcastAck(pReq->hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, nullptr);
}
-void CIcqProto::OnStartSession(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+void CIcqProto::OnStartSession(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *)
{
JsonReply root(pReply);
switch (root.error()) {
@@ -780,6 +783,16 @@ void CIcqProto::OnStartSession(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
else ConnectionFailed(LOGINERR_WRONGPASSWORD, root.error());
return;
+ case 400:
+ if (root.detail() == 1015 && m_iTimeShift == 0) { // wrong timestamp
+ JSONNode &data = root.data();
+ int srvTS = data["ts"].as_int();
+ m_iTimeShift = (srvTS) ? time(0) - srvTS : 0;
+ StartSession();
+ return;
+ }
+ __fallthrough;
+
default:
ConnectionFailed(LOGINERR_WRONGPROTOCOL, root.error());
return;
@@ -789,6 +802,9 @@ void CIcqProto::OnStartSession(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
m_fetchBaseURL = data["fetchBaseURL"].as_mstring();
m_aimsid = data["aimsid"].as_mstring();
+ int srvTS = data["ts"].as_int();
+ m_iTimeShift = (srvTS) ? time(0) - srvTS : 0;
+
OnLoggedIn();
for (auto &it : data["events"])