From f81688b2ca172fd4d39f365d26d2a0efa3c613f6 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 20 May 2017 21:07:04 +0300 Subject: MSN: crash fix for extra-long auth tokens --- protocols/MSN/src/msn_auth.cpp | 69 +++++++++++++++++++++------------------ protocols/MSN/src/msn_proto.h | 11 +++---- protocols/MSN/src/msn_skypeab.cpp | 4 +-- protocols/MSN/src/stdafx.h | 1 + protocols/MSN/src/version.h | 2 +- 5 files changed, 47 insertions(+), 40 deletions(-) diff --git a/protocols/MSN/src/msn_auth.cpp b/protocols/MSN/src/msn_auth.cpp index 4cc45d04a6..74ff67c075 100644 --- a/protocols/MSN/src/msn_auth.cpp +++ b/protocols/MSN/src/msn_auth.cpp @@ -228,14 +228,16 @@ OAuthToken::OAuthToken(const char *pszTokenName, const char *pszService, bool bP bool OAuthToken::Refresh(bool bForce) { - char szToken[1024], szRefreshToken[1024]; + if ((!bForce && !Expired()) || !m_proto->authRefreshToken) + return false; + time_t tExpires; + CMStringA szToken, szRefreshToken; + if (!m_proto->RefreshOAuth(m_proto->authRefreshToken, m_pszService, &szToken, &szRefreshToken, &tExpires)) + return false; + if (m_bPreprendT) + szToken.Insert(0, "t="); - if ((!bForce && !Expired()) || !m_proto->authRefreshToken || - !m_proto->RefreshOAuth(m_proto->authRefreshToken, m_pszService, szToken+(m_bPreprendT?2:0), - szRefreshToken, &tExpires)) return false; - if (m_bPreprendT) memcpy (szToken, "t=", 2); - //replaceStr(m_pszRefreshToken, szRefreshToken); replaceStr(m_proto->authRefreshToken, szRefreshToken); m_proto->setString("authRefreshToken", szRefreshToken); SetToken(szToken, tExpires); @@ -691,21 +693,19 @@ int CMsnProto::MSN_SkypeAuth(const char *pszNonce, char *pszUIC) /* 1 - Login successful 0 - Login failed - -1 - Loading Skylogin library failed - -2 - Functions cannot be loaded from Skylogin library - -3 - Initializing Skylogin library failed - */ +*/ + int CMsnProto::LoginSkypeOAuth(const char *pRefreshToken) { - int iRet = -1; + int iRet = 0; // Perform login SkyLogin hLogin = SkyLogin_Init(); if (hLogin) { - char szLoginToken[1024]; + CMStringA szLoginToken; SkyLogin_SetLogFunction(hLogin, debugLogSkyLoginA, this); - if (RefreshOAuth(pRefreshToken, "service::login.skype.com::MBI_SSL", szLoginToken) && - SkyLogin_PerformLoginOAuth(hLogin, szLoginToken)) + if (RefreshOAuth(pRefreshToken, "service::login.skype.com::MBI_SSL", &szLoginToken, nullptr, nullptr) && + SkyLogin_PerformLoginOAuth(hLogin, szLoginToken)) { char szUIC[1024]; if (SkyLogin_GetCredentialsUIC(hLogin, szUIC)) { @@ -757,7 +757,7 @@ static int CopyCookies(NETLIBHTTPREQUEST *nlhrReply, NETLIBHTTPHEADER *hdr) service::skype.com::MBI_SSL - Root of all OAuth tokens service::skype.net::MBI_SSL - ? */ -bool CMsnProto::RefreshOAuth(const char *pszRefreshToken, const char *pszService, char *pszAccessToken, char *pszOutRefreshToken, time_t *ptExpires) +bool CMsnProto::RefreshOAuth(const char *pszRefreshToken, const char *pszService, CMStringA *pszAccessToken, CMStringA *pszOutRefreshToken, time_t *ptExpires) { NETLIBHTTPREQUEST nlhr = { 0 }; NETLIBHTTPHEADER headers[3]; @@ -779,8 +779,7 @@ bool CMsnProto::RefreshOAuth(const char *pszRefreshToken, const char *pszService nlhr.headers[1].szValue = "application/x-www-form-urlencoded"; nlhr.headers[2].szName = "Cookie"; nlhr.headers[2].szValue = authCookies; - post.Format("client_id=00000000480BC46C&scope=%s&grant_type=refresh_token&refresh_token=%s", - ptrA(mir_urlEncode(pszService)), pszRefreshToken); + post.Format("client_id=00000000480BC46C&scope=%s&grant_type=refresh_token&refresh_token=%s", ptrA(mir_urlEncode(pszService)), pszRefreshToken); nlhr.pData = (char*)(const char*)post; nlhr.dataLength = (int)mir_strlen(nlhr.pData); @@ -793,24 +792,32 @@ bool CMsnProto::RefreshOAuth(const char *pszRefreshToken, const char *pszService if (nlhrReply) { hHttpsConnection = nlhrReply->nlc; if (nlhrReply->resultCode == 200 && nlhrReply->pData) { - char *p; - bRet = true; - - if (pszAccessToken && (p=strstr(nlhrReply->pData, "\"access_token\":"))) - bRet &= sscanf(p+sizeof("\"access_token\""), "\"%[^\"]\"", pszAccessToken)==1; - if (pszOutRefreshToken && (p=strstr(nlhrReply->pData, "\"refresh_token\":"))) - bRet &= sscanf(p+sizeof("\"refresh_token\""), "\"%[^\"]\"", pszOutRefreshToken)==1; - if (ptExpires && (p=strstr(nlhrReply->pData, "\"expires_in\""))) { - int expires; - if (sscanf(p+sizeof("\"expires_in\""), "%d,", &expires) == 1) { - time(ptExpires); - *ptExpires+=expires; - bRet&=true; + JSONROOT root(nlhrReply->pData); + if (root) { + bRet = true; + + if (pszAccessToken) { + *pszAccessToken = (*root)["access_token"].as_mstring(); + if (pszAccessToken->IsEmpty()) + bRet = false; + } + + if (pszOutRefreshToken) { + *pszOutRefreshToken = (*root)["refresh_token"].as_mstring(); + if (pszOutRefreshToken->IsEmpty()) + bRet = false; + } + + if (ptExpires) { + *ptExpires = (*root)["expires_in"].as_int(); + if (*ptExpires == 0) + bRet = false; } } } Netlib_FreeHttpRequest(nlhrReply); - } else hHttpsConnection = NULL; + } + else hHttpsConnection = NULL; return bRet; } diff --git a/protocols/MSN/src/msn_proto.h b/protocols/MSN/src/msn_proto.h index 9aeb60b56b..3db4644cbd 100644 --- a/protocols/MSN/src/msn_proto.h +++ b/protocols/MSN/src/msn_proto.h @@ -489,17 +489,16 @@ struct CMsnProto : public PROTO int MSN_GetPassportAuth(void); int MSN_SkypeAuth(const char *pszNonce, char *pszUIC); - int MSN_DoOAuth(void); char* GenerateLoginBlob(char* challenge); void LoadAuthTokensDB(void); void SaveAuthTokensDB(void); - bool parseLoginPage(char *pszHTML, NETLIBHTTPREQUEST *nlhr, CMStringA *post); + bool parseLoginPage(char *pszHTML, NETLIBHTTPREQUEST *nlhr, CMStringA *post); int LoginSkypeOAuth(const char *pRefreshToken); - bool RefreshOAuth(const char *pszRefreshToken, const char *pszService, char *pszAccessToken, char *pszOutRefreshToken=NULL, time_t *ptExpires=NULL); + bool RefreshOAuth(const char *pszRefreshToken, const char *pszService, CMStringA *pszAccessToken, CMStringA *pszOutRefreshToken, time_t *ptExpires); int MSN_AuthOAuth(void); - int MSN_RefreshOAuthTokens(bool bJustCheck); - void MSN_SendATH(ThreadData* info); - CMStringA HotmailLogin(const char* url); + int MSN_RefreshOAuthTokens(bool bJustCheck); + void MSN_SendATH(ThreadData *info); + CMStringA HotmailLogin(const char *url); void FreeAuthTokens(void); int GetMyNetID(void); LPCSTR GetMyUsername(int netId); diff --git a/protocols/MSN/src/msn_skypeab.cpp b/protocols/MSN/src/msn_skypeab.cpp index 1a34f71ec0..3f09287e92 100644 --- a/protocols/MSN/src/msn_skypeab.cpp +++ b/protocols/MSN/src/msn_skypeab.cpp @@ -20,7 +20,6 @@ along with this program. If not, see . #include "stdafx.h" #include "msn_proto.h" -#include bool CMsnProto::APISkypeComRequest(NETLIBHTTPREQUEST *nlhr, NETLIBHTTPHEADER *headers) { @@ -74,7 +73,8 @@ bool CMsnProto::MSN_SKYABRefreshClist(void) hHttpsConnection = nlhrReply->nlc; if (nlhrReply->resultCode == 200 && nlhrReply->pData) { JSONROOT root(nlhrReply->pData); - if (root == NULL) return false; + if (root == NULL) + return false; JSONNode *items = json_as_array(root), *item; for (size_t i = 0; i < json_size(items); i++) { diff --git a/protocols/MSN/src/stdafx.h b/protocols/MSN/src/stdafx.h index 27667ebadd..449d947bb3 100644 --- a/protocols/MSN/src/stdafx.h +++ b/protocols/MSN/src/stdafx.h @@ -60,6 +60,7 @@ along with this program. If not, see . #include #include #include +#include #include "m_proto_listeningto.h" #include "m_folders.h" diff --git a/protocols/MSN/src/version.h b/protocols/MSN/src/version.h index 5277e31e30..597dbd6529 100644 --- a/protocols/MSN/src/version.h +++ b/protocols/MSN/src/version.h @@ -21,7 +21,7 @@ along with this program. If not, see . #define __MAJOR_VERSION 0 #define __MINOR_VERSION 12 #define __RELEASE_NUM 1 -#define __BUILD_NUM 4 +#define __BUILD_NUM 5 #include -- cgit v1.2.3