summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authorMikalaiR <nikolay.romanovich@narod.ru>2015-06-03 07:08:43 +0000
committerMikalaiR <nikolay.romanovich@narod.ru>2015-06-03 07:08:43 +0000
commit3545c5a4bf039680f7d7a5cdd6cac9d19ae084c3 (patch)
tree6d9a22e42caba41e60038251c64830fab01f2956 /protocols
parent2cb74cbf59d7a9a1de2efd9076d4c4d77f5ea47d (diff)
SkypeWeb: M$ account login support part 1.
git-svn-id: http://svn.miranda-ng.org/main/trunk@13979 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols')
-rw-r--r--protocols/SkypeWeb/src/requests/login.h41
-rw-r--r--protocols/SkypeWeb/src/skype_login.cpp72
-rw-r--r--protocols/SkypeWeb/src/skype_proto.cpp8
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h4
-rw-r--r--protocols/SkypeWeb/src/skype_utils.cpp20
5 files changed, 143 insertions, 2 deletions
diff --git a/protocols/SkypeWeb/src/requests/login.h b/protocols/SkypeWeb/src/requests/login.h
index 0b7ab60d29..eb8108cabf 100644
--- a/protocols/SkypeWeb/src/requests/login.h
+++ b/protocols/SkypeWeb/src/requests/login.h
@@ -40,4 +40,45 @@ public:
}
};
+class LoginOAuthRPSRequest : public HttpRequest
+{
+public:
+ LoginOAuthRPSRequest(const char *token) :
+ HttpRequest(REQUEST_POST, "api.skype.com/login/skypetoken")
+ {
+ Body
+ << CHAR_VALUE("scopes", "client")
+ << CHAR_VALUE("clientVersion", "0/7.4.85.102/259/")
+ << CHAR_VALUE("access_token", token)
+ << INT_VALUE("partner", 999);
+ }
+};
+
+class LoginMSRequest : public HttpRequest
+{
+public:
+ LoginMSRequest() : HttpRequest(REQUEST_GET, "login.live.com/oauth20_authorize.srf")
+ {
+
+ Url
+ << CHAR_VALUE("client_id", "00000000480BC46C")
+ << CHAR_VALUE("scope", "service::skype.com::MBI_SSL")
+ << CHAR_VALUE("response_type", "token")
+ << CHAR_VALUE("redirect_uri", ptrA(mir_urlEncode("https://login.live.com/oauth20_desktop.srf")));
+ }
+
+ LoginMSRequest(const char *ppft, const char* login, const char* password, const char *cookies) :
+ HttpRequest(REQUEST_POST, "https://login.live.com/ppsecure/post.srf")
+ {
+ Headers
+ << CHAR_VALUE("Content-Type", "application/x-www-form-urlencoded")
+ << CHAR_VALUE("Cookie", cookies);
+
+ Body
+ << CHAR_VALUE("PPFT", ptrA(mir_urlEncode(ppft)))
+ << CHAR_VALUE("login", ptrA(mir_urlEncode(login)))
+ << CHAR_VALUE("passwd", ptrA(mir_urlEncode(password)));
+ }
+};
+
#endif //_SKYPE_REQUEST_LOGIN_H_
diff --git a/protocols/SkypeWeb/src/skype_login.cpp b/protocols/SkypeWeb/src/skype_login.cpp
index 2de32f82be..ad6eab4769 100644
--- a/protocols/SkypeWeb/src/skype_login.cpp
+++ b/protocols/SkypeWeb/src/skype_login.cpp
@@ -17,9 +17,79 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
+void CSkypeProto::OnLoginMSFirst(const NETLIBHTTPREQUEST *response)
+{
+ if (response == NULL || response->pData == NULL)
+ {
+ 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 = "<input type=\"hidden\" name=\"PPFT\" id=\"i0327\" value=\"(.+?)\"/>";
+ if (!std::regex_search(content, match, regex))
+ {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
+ SetStatus(ID_STATUS_OFFLINE);
+ }
+ std::string pie = match[1];
+
+ for (int i = 0; i < response->headersCount; i++)
+ {
+ if (mir_strcmpi(response->headers[i].szName, "Set-Cookie"))
+ continue;
+
+ regex = "^(.+?)=(.+?);";
+ content = response->headers[i].szValue;
+
+ if (std::regex_search(content, match, regex))
+ cookies[match[1]] = match[2];
+ }
+
+ CMStringA allCookies;
+ if (!cookies.empty())
+ {
+ for (std::map<std::string, std::string>::iterator cookie = cookies.begin(); cookie != cookies.end(); ++cookie)
+ allCookies.AppendFormat("%s=%s; ", cookie->first.c_str(), cookie->second.c_str());
+ }
+
+ SendRequest(new LoginMSRequest(pie.c_str(), ptrA(getStringA(SKYPE_SETTINGS_ID)), ptrA(getStringA(SKYPE_SETTINGS_PASSWORD)), allCookies.GetBuffer()), &CSkypeProto::OnLoginMSSecond);
+}
+
+void CSkypeProto::OnLoginMSSecond(const NETLIBHTTPREQUEST *response)
+{
+ if (response == NULL || response->pData == NULL)
+ {
+ 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, token;
+
+ for (int i = 0; i < response->headersCount; i++)
+ {
+ if (!mir_strcmpi(response->headers[i].szName, "Location"))
+ {
+ regex = "access_token=(.+?)&";
+ content = response->headers[i].szValue;
+
+ if (std::regex_search(content, match, regex))
+ token = urlDecode(match[1]);
+ }
+ }
+ SendRequest(new LoginOAuthRPSRequest(token.c_str()), &CSkypeProto::OnLoginOAuth);
+}
+
void CSkypeProto::OnLoginOAuth(const NETLIBHTTPREQUEST *response)
{
- if (response == NULL)
+ if (response == NULL || response->pData == NULL)
{
ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
SetStatus(ID_STATUS_OFFLINE);
diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp
index 4b72a863ee..602ae7144f 100644
--- a/protocols/SkypeWeb/src/skype_proto.cpp
+++ b/protocols/SkypeWeb/src/skype_proto.cpp
@@ -255,7 +255,13 @@ int CSkypeProto::SetStatus(int iNewStatus)
if ((tokenExpires - 1800) > time(NULL))
OnLoginSuccess();
else
- SendRequest(new LoginOAuthRequest(ptrA(getStringA(SKYPE_SETTINGS_ID)), ptrA(getStringA(SKYPE_SETTINGS_PASSWORD))), &CSkypeProto::OnLoginOAuth);
+ {
+ if (strstr(ptrA(getStringA(SKYPE_SETTINGS_ID)), "@"))
+ SendRequest(new LoginMSRequest(), &CSkypeProto::OnLoginMSFirst);
+ else
+ 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 6a16d06939..faf3808607 100644
--- a/protocols/SkypeWeb/src/skype_proto.h
+++ b/protocols/SkypeWeb/src/skype_proto.h
@@ -171,6 +171,8 @@ private:
int __cdecl OnOptionsInit(WPARAM wParam, LPARAM lParam);
// login
+ void OnLoginMSFirst(const NETLIBHTTPREQUEST *response);
+ void OnLoginMSSecond(const NETLIBHTTPREQUEST *response);
void OnLoginOAuth(const NETLIBHTTPREQUEST *response);
void OnLoginSuccess();
void OnEndpointCreated(const NETLIBHTTPREQUEST *response);
@@ -337,6 +339,8 @@ private:
time_t GetLastMessageTime(MCONTACT hContact);
+ std::string urlDecode(std::string SRC);
+
//events
void InitDBEvents();
int __cdecl ProcessSrmmEvent(WPARAM, LPARAM);
diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp
index fe55c22841..d84fc3d86e 100644
--- a/protocols/SkypeWeb/src/skype_utils.cpp
+++ b/protocols/SkypeWeb/src/skype_utils.cpp
@@ -784,4 +784,24 @@ void CSkypeProto::SkypeUnsetTimer(void*)
if (CSkypeProto::m_timer)
KillTimer(NULL, CSkypeProto::m_timer);
CSkypeProto::m_timer = 0;
+}
+
+std::string CSkypeProto::urlDecode(std::string SRC)
+{
+ std::string ret;
+ char ch;
+ int i, ii;
+ for (i = 0; i < SRC.length(); i++)
+ {
+ if (int(SRC[i]) == 37)
+ {
+ sscanf(SRC.substr(i + 1, 2).c_str(), "%x", &ii);
+ ch = static_cast<char>(ii);
+ ret += ch;
+ i = i + 2;
+ }
+ else
+ ret += SRC[i];
+ }
+ return (ret);
} \ No newline at end of file