diff options
Diffstat (limited to 'protocols/Steam/src/steam_account.cpp')
-rw-r--r-- | protocols/Steam/src/steam_account.cpp | 202 |
1 files changed, 196 insertions, 6 deletions
diff --git a/protocols/Steam/src/steam_account.cpp b/protocols/Steam/src/steam_account.cpp index 812962db81..59915ddeac 100644 --- a/protocols/Steam/src/steam_account.cpp +++ b/protocols/Steam/src/steam_account.cpp @@ -14,6 +14,196 @@ bool CSteamProto::IsMe(const char *steamId) return false;
}
+void CSteamProto::OnGotRsaKey(const NETLIBHTTPREQUEST *response, void *arg)
+{
+ // load rsa key parts
+ JSONNODE *root = json_parse(response->pData), *node;
+ if (!root) return;
+
+ node = json_get(root, "success");
+ if (!json_as_bool(node)) return;
+
+ node = json_get(root, "publickey_mod");
+ ptrA modulus(mir_u2a(json_as_string(node)));
+
+ // exponent "010001" is used as constant in CSteamProto::RsaEncrypt
+ /*node = json_get(root, "publickey_exp");
+ ptrA exponent(mir_u2a(json_as_string(node)));*/
+
+ node = json_get(root, "timestamp");
+ ptrA timestamp(mir_u2a(json_as_string(node)));
+ setString("Timestamp", timestamp);
+
+ // encrcrypt password
+ ptrA base64RsaEncryptedPassword;
+ ptrA password(getStringA("Password"));
+
+ DWORD error = 0;
+ DWORD encryptedSize = 0;
+ DWORD passwordSize = (DWORD)strlen(password);
+ if ((error = RsaEncrypt(modulus, password, NULL, encryptedSize)) != 0)
+ {
+ debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error);
+ return;
+ }
+
+ BYTE *encryptedPassword = (BYTE*)mir_calloc(encryptedSize);
+ if ((error = RsaEncrypt(modulus, password, encryptedPassword, encryptedSize)) != 0)
+ {
+ debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error);
+ return;
+ }
+
+ base64RsaEncryptedPassword = mir_base64_encode(encryptedPassword, encryptedSize);
+ mir_free(encryptedPassword);
+
+ setString("EncryptedPassword", base64RsaEncryptedPassword);
+
+ // run authorization request
+ ptrA username(mir_urlEncode(ptrA(mir_utf8encodeW(getWStringA("Username")))));
+
+ PushRequest(
+ new SteamWebApi::AuthorizationRequest(username, base64RsaEncryptedPassword, timestamp),
+ &CSteamProto::OnAuthorization);
+}
+
+void CSteamProto::OnAuthorization(const NETLIBHTTPREQUEST *response, void *arg)
+{
+ JSONNODE *root = json_parse(response->pData), *node;
+
+ node = json_get(root, "success");
+ if (json_as_bool(node) == 0)
+ {
+ node = json_get(root, "emailauth_needed");
+ if (json_as_bool(node) > 0)
+ {
+ node = json_get(root, "emailsteamid");
+ ptrA guardId(mir_u2a(json_as_string(node)));
+
+ node = json_get(root, "emaildomain");
+ ptrA emailDomain(mir_utf8encodeW(json_as_string(node)));
+
+ GuardParam guard;
+ lstrcpyA(guard.domain, emailDomain);
+
+ if (DialogBoxParam(
+ g_hInstance,
+ MAKEINTRESOURCE(IDD_GUARD),
+ NULL,
+ CSteamProto::GuardProc,
+ (LPARAM)&guard) != 1)
+ return;
+
+ ptrA username(mir_urlEncode(ptrA(mir_utf8encodeW(getWStringA("Username")))));
+ ptrA base64RsaEncryptedPassword(getStringA("EncryptedPassword"));
+ ptrA timestamp(getStringA("Timestamp"));
+
+ PushRequest(
+ new SteamWebApi::AuthorizationRequest(username, base64RsaEncryptedPassword, timestamp, guardId, guard.code),
+ &CSteamProto::OnAuthorization);
+ }
+
+ // todo: show captcha dialog
+ /*node = json_get(root, "captcha_needed");
+ if (json_as_bool(node) > 0)
+ {
+ node = json_get(root, "captcha_gid");
+ authResult->captchagid = ptrA(mir_u2a(json_as_string(node)));
+ }
+
+ if (!authResult->emailauth_needed && !authResult->captcha_needed)
+ {
+ node = json_get(root, "message");
+ authResult->message = json_as_string(node);
+ }*/
+
+ return;
+ }
+
+ node = json_get(root, "login_complete");
+ if (!json_as_bool(node))
+ return;
+
+ node = json_get(root, "oauth");
+ root = json_parse(ptrA(mir_u2a(json_as_string(node))));
+
+ node = json_get(root, "steamid");
+ ptrA steamId(mir_u2a(json_as_string(node)));
+ setString("SteamID", steamId);
+
+ node = json_get(root, "oauth_token");
+ ptrA token(mir_u2a(json_as_string(node)));
+ setString("TokenSecret", token);
+
+ node = json_get(root, "webcookie");
+ ptrA cookie(mir_u2a(json_as_string(node)));
+
+ delSetting("Timestamp");
+ delSetting("EncryptedPassword");
+
+ PushRequest(
+ new SteamWebApi::GetSessionRequest(token, steamId, cookie),
+ &CSteamProto::OnGotSession);
+
+ PushRequest(
+ new SteamWebApi::LogonRequest(token),
+ &CSteamProto::OnLoggedOn);
+}
+
+void CSteamProto::OnGotSession(const NETLIBHTTPREQUEST *response, void *arg)
+{
+ for (int i = 0; i < response->headersCount; i++)
+ {
+ if (lstrcmpiA(response->headers[i].szName, "Set-Cookie"))
+ continue;
+
+ std::string cookies = response->headers[i].szValue;
+ size_t start = cookies.find("sessionid=") + 10;
+ size_t end = cookies.substr(start).find(';');
+ std::string sessionId = cookies.substr(start, end - start + 10);
+ setString("SessionID", sessionId.c_str());
+ break;
+ }
+}
+
+void CSteamProto::OnLoggedOn(const NETLIBHTTPREQUEST *response, void *arg)
+{
+ JSONNODE *root = json_parse(response->pData), *node;
+
+ node = json_get(root, "error");
+ ptrW error(json_as_string(node));
+ if (lstrcmpi(error, L"OK")/* || response->resultCode == HTTP_STATUS_UNAUTHORIZED*/)
+ {
+ //delSetting("TokenSecret");
+ //delSetting("Cookie");
+
+ // set status to offline
+ m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, ID_STATUS_OFFLINE);
+ return;
+ }
+
+ node = json_get(root, "umqid");
+ setString("UMQID", ptrA(mir_u2a(json_as_string(node))));
+
+ node = json_get(root, "message");
+ setDword("MessageID", json_as_int(node));
+
+ // load contact list
+ ptrA token(getStringA("TokenSecret"));
+ ptrA steamId(getStringA("SteamID"));
+
+ PushRequest(
+ new SteamWebApi::GetFriendListRequest(token, steamId),
+ &CSteamProto::OnGotFriendList);
+
+ // start polling thread
+ m_hPollingThread = ForkThreadEx(&CSteamProto::PollingThread, 0, NULL);
+
+ // go to online now
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus = m_iDesiredStatus);
+}
+
void CSteamProto::SetServerStatusThread(void *arg)
{
WORD status = *((WORD*)&arg);
@@ -66,7 +256,7 @@ void CSteamProto::Authorize(SteamWebApi::AuthorizationApi::AuthResult *authResul ptrA password(getStringA("Password"));
- DWORD error = 0;
+ /*DWORD error = 0;
DWORD encryptedSize = 0;
DWORD passwordSize = (DWORD)strlen(password);
if ((error = RsaEncrypt(rsaKey, password, passwordSize, NULL, encryptedSize)) != 0)
@@ -83,7 +273,7 @@ void CSteamProto::Authorize(SteamWebApi::AuthorizationApi::AuthResult *authResul }
base64RsaEncryptedPassword = mir_base64_encode(encryptedPassword, encryptedSize);
- mir_free(encryptedPassword);
+ mir_free(encryptedPassword);*/
// try to authorize
debugLogA("CSteamProto::Authorize: call SteamWebApi::AuthorizationApi::Authorize");
@@ -123,7 +313,7 @@ void CSteamProto::Authorize(SteamWebApi::AuthorizationApi::AuthResult *authResul void CSteamProto::LogInThread(void* param)
{
- while (m_bTerminated || m_hPollingThread != NULL)
+ while (isTerminated || m_hPollingThread != NULL)
Sleep(500);
ptrA token(getStringA("TokenSecret"));
@@ -195,7 +385,7 @@ void CSteamProto::LogInThread(void* param) // start pooling thread
if (m_hPollingThread == NULL)
{
- m_bTerminated = false;
+ isTerminated = false;
m_hPollingThread = ForkThreadEx(&CSteamProto::PollingThread, NULL, NULL);
}
}
@@ -205,12 +395,12 @@ void CSteamProto::LogOutThread(void*) ptrA token(getStringA("TokenSecret"));
ptrA umqId(getStringA("UMQID"));
- while (!Miranda_Terminated() && m_bTerminated && m_hPollingThread != NULL)
+ while (!Miranda_Terminated() && isTerminated && m_hPollingThread != NULL)
Sleep(200);
debugLogA("CSteamProto::LogOutThread: call SteamWebApi::LoginApi::Logoff");
SteamWebApi::LoginApi::Logoff(m_hNetlibUser, token, umqId);
delSetting("UMQID");
- m_bTerminated = false;
+ isTerminated = false;
}
\ No newline at end of file |