diff options
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/SkypeWeb/src/requests/login.h | 41 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_login.cpp | 72 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_proto.cpp | 8 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_proto.h | 4 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_utils.cpp | 20 |
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 |