From 7578bfa80684cc791d2c5c3f0a5e3f461cbb767d Mon Sep 17 00:00:00 2001 From: MikalaiR Date: Wed, 3 Jun 2015 04:54:59 +0000 Subject: SkypeWeb: Login rewritted to OAuth. git-svn-id: http://svn.miranda-ng.org/main/trunk@13977 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/SkypeWeb/src/requests/login.h | 38 +++++------------- protocols/SkypeWeb/src/skype_login.cpp | 71 +++++---------------------------- protocols/SkypeWeb/src/skype_proto.cpp | 2 +- protocols/SkypeWeb/src/skype_proto.h | 3 +- 4 files changed, 22 insertions(+), 92 deletions(-) (limited to 'protocols') diff --git a/protocols/SkypeWeb/src/requests/login.h b/protocols/SkypeWeb/src/requests/login.h index 4e15557ab1..0b7ab60d29 100644 --- a/protocols/SkypeWeb/src/requests/login.h +++ b/protocols/SkypeWeb/src/requests/login.h @@ -18,41 +18,25 @@ along with this program. If not, see . #ifndef _SKYPE_REQUEST_LOGIN_H_ #define _SKYPE_REQUEST_LOGIN_H_ -class LoginRequest : public HttpRequest +class LoginOAuthRequest : public HttpRequest { public: - LoginRequest() : - HttpRequest(REQUEST_POST, "login.skype.com/login") + LoginOAuthRequest(const char *username, const char *password) : + HttpRequest(REQUEST_POST, "api.skype.com/login/skypetoken") { - Url - << INT_VALUE("client_id", 578134) - << CHAR_VALUE("redirect_uri", "https%3A%2F%2Fweb.skype.com"); - } + CMStringA str(::FORMAT, "%s\nskyper\n%s", username, password); - LoginRequest(const char *skypename, const char *password, const char *pie, const char *etm) : - HttpRequest(REQUEST_POST, "login.skype.com/login") - { - Url - << INT_VALUE("client_id", 578134) - << CHAR_VALUE("redirect_uri", "https%3A%2F%2Fweb.skype.com"); + BYTE digest[16]; - Headers - << CHAR_VALUE("Referer", "https://login.skype.com/login?method=skype&client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com"); + mir_md5_hash((BYTE*)str.GetString(), str.GetLength(), digest); - LPTIME_ZONE_INFORMATION tzi = tmi.getTziByContact(NULL); - char sign = tzi->Bias > 0 ? '-' : '+'; - int hours = tzi->Bias / -60; - int minutes = tzi->Bias % -60; + char *hash = mir_base64_encode(digest, sizeof(digest)); Body - << CHAR_VALUE("username", skypename) - << CHAR_VALUE("password", password) - << CHAR_VALUE("pie", ptrA(mir_urlEncode(pie))) - << CHAR_VALUE("etm", ptrA(mir_urlEncode(etm))) - << FORMAT_VALUE("timezone_field", "%c%02d|%02d", sign, hours, minutes) - << FORMAT_VALUE("js_time", "%d.00", time(NULL)) - << INT_VALUE("client_id", 578134) - << CHAR_VALUE("redirect_uri", "https%3A%2F%2Fweb.skype.com"); + << CHAR_VALUE("scopes", "client") + << CHAR_VALUE("clientVersion", "0/7.4.85.102/259/") + << CHAR_VALUE("username", username) + << CHAR_VALUE("passwordHash", hash); } }; diff --git a/protocols/SkypeWeb/src/skype_login.cpp b/protocols/SkypeWeb/src/skype_login.cpp index f814a4a56d..2de32f82be 100644 --- a/protocols/SkypeWeb/src/skype_login.cpp +++ b/protocols/SkypeWeb/src/skype_login.cpp @@ -17,94 +17,42 @@ along with this program. If not, see . #include "stdafx.h" -void CSkypeProto::OnLoginFirst(const NETLIBHTTPREQUEST *response) +void CSkypeProto::OnLoginOAuth(const NETLIBHTTPREQUEST *response) { if (response == NULL) { - debugLogA(__FUNCTION__ ": failed to get login page"); ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); SetStatus(ID_STATUS_OFFLINE); return; } - std::regex regex; - std::smatch match; - - std::string content = response->pData; - regex = ""; - if (!std::regex_search(content, match, regex)) - { - debugLogA(__FUNCTION__ ": failed to get pie"); - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); - SetStatus(ID_STATUS_OFFLINE); - } - std::string pie = match[1]; - - regex = ""; - if (!std::regex_search(content, match, regex)) + JSONNode json = JSONNode::parse(response->pData); + if (!json) { - debugLogA(__FUNCTION__ ": failed to get etm"); ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); SetStatus(ID_STATUS_OFFLINE); return; } - std::string etm = match[1]; - - ptrA skypename(getStringA(SKYPE_SETTINGS_ID)); - ptrA password(getStringA(SKYPE_SETTINGS_PASSWORD)); - SendRequest(new LoginRequest(skypename, password, pie.c_str(), etm.c_str()), &CSkypeProto::OnLoginSecond); -} -void CSkypeProto::OnLoginSecond(const NETLIBHTTPREQUEST *response) -{ - m_iStatus++; - - if (response == NULL) + if (response->resultCode != 200 || !json["skypetoken"] || !json["expiresIn"]) { - debugLogA(__FUNCTION__ ": failed to login"); ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); SetStatus(ID_STATUS_OFFLINE); return; } - std::regex regex; - std::smatch match; - - std::string content = response->pData; - regex = ""; - if (!std::regex_search(content, match, regex)) - { - debugLogA(__FUNCTION__ ": failed to get skype token"); - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); - SetStatus(ID_STATUS_OFFLINE); - return; - } - std::string token = match[1]; + std::string token = json["skypetoken"].as_string(); setString("TokenSecret", token.c_str()); - regex = ""; - if (std::regex_search(content, match, regex)) - { - std::string expiresIn = match[1]; - int seconds = atoi(expiresIn.c_str()); - setDword("TokenExpiresIn", time(NULL) + seconds); - } - - for (int i = 0; i < response->headersCount; i++) - { - if (mir_strcmpi(response->headers[i].szName, "Set-Cookie")) - continue; + int expiresIn = json["expiresIn"].as_int(); + setDword("TokenExpiresIn", time(NULL) + expiresIn); - regex = "^(.+?)=(.+?);"; - content = response->headers[i].szValue; - if (std::regex_search(content, match, regex)) - cookies[match[1]] = match[2]; - } OnLoginSuccess(); } void CSkypeProto::OnLoginSuccess() { + ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_SUCCESS, NULL, 0); SelfSkypeName = getStringA(SKYPE_SETTINGS_ID); TokenSecret = getStringA("TokenSecret"); Server = getStringA("Server") != NULL ? getStringA("Server") : SKYPE_ENDPOINTS_HOST; @@ -166,7 +114,7 @@ void CSkypeProto::OnEndpointCreated(const NETLIBHTTPREQUEST *response) if (response->resultCode == 401) { delSetting("TokenExpiresIn"); - SendRequest(new LoginRequest(), &CSkypeProto::OnLoginFirst); + SendRequest(new LoginOAuthRequest(SelfSkypeName, ptrA(getStringA(SKYPE_SETTINGS_PASSWORD))), &CSkypeProto::OnLoginOAuth); return; } else //it should be rewritten @@ -266,5 +214,4 @@ void CSkypeProto::OnStatusChanged(const NETLIBHTTPREQUEST *response) int oldStatus = m_iStatus; m_iStatus = m_iDesiredStatus = iNewStatus; ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_SUCCESS, NULL, 0); } diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp index f01f932b9e..4b72a863ee 100644 --- a/protocols/SkypeWeb/src/skype_proto.cpp +++ b/protocols/SkypeWeb/src/skype_proto.cpp @@ -255,7 +255,7 @@ int CSkypeProto::SetStatus(int iNewStatus) if ((tokenExpires - 1800) > time(NULL)) OnLoginSuccess(); else - SendRequest(new LoginRequest(), &CSkypeProto::OnLoginFirst); + SendRequest(new LoginOAuthRequest(ptrA(getStringA(SKYPE_SETTINGS_ID)), ptrA(getStringA(SKYPE_SETTINGS_PASSWORD))), &CSkypeProto::OnLoginOAuth); } else { diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h index 0a9ad9739f..6a16d06939 100644 --- a/protocols/SkypeWeb/src/skype_proto.h +++ b/protocols/SkypeWeb/src/skype_proto.h @@ -171,8 +171,7 @@ private: int __cdecl OnOptionsInit(WPARAM wParam, LPARAM lParam); // login - void OnLoginFirst(const NETLIBHTTPREQUEST *response); - void OnLoginSecond(const NETLIBHTTPREQUEST *response); + void OnLoginOAuth(const NETLIBHTTPREQUEST *response); void OnLoginSuccess(); void OnEndpointCreated(const NETLIBHTTPREQUEST *response); void OnSubscriptionsCreated(const NETLIBHTTPREQUEST *response); -- cgit v1.2.3