summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authorPiotr Piastucki <leech.miranda@gmail.com>2015-10-19 23:49:45 +0000
committerPiotr Piastucki <leech.miranda@gmail.com>2015-10-19 23:49:45 +0000
commit1f9219eb0abc61710a0ed5ddf0b23877be08360d (patch)
treef01701f493132a3fa0abbc20db581987456d9b69 /protocols
parent53fe38bb0e7f94a58c3e4edc21581fdd4c5b3e5e (diff)
MSN: Periodically refresh OAuth so that connection doesn't timeout with error 922 after 24 hours.
git-svn-id: http://svn.miranda-ng.org/main/trunk@15573 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols')
-rw-r--r--protocols/MSN/src/msn_auth.cpp98
-rw-r--r--protocols/MSN/src/msn_commands.cpp73
-rw-r--r--protocols/MSN/src/msn_ieembed.cpp3
-rw-r--r--protocols/MSN/src/msn_proto.h7
-rw-r--r--protocols/MSN/src/msn_threads.cpp10
5 files changed, 139 insertions, 52 deletions
diff --git a/protocols/MSN/src/msn_auth.cpp b/protocols/MSN/src/msn_auth.cpp
index 0485fd1ae0..35c9fd3b9e 100644
--- a/protocols/MSN/src/msn_auth.cpp
+++ b/protocols/MSN/src/msn_auth.cpp
@@ -158,6 +158,26 @@ int CMsnProto::MSN_GetPassportAuth(void)
{
int retVal = -1;
+ if (!bPassportAuth && authRefreshToken) {
+ // Slow authentication required by fetching multiple tokens, i.e. 2-factor auth :(
+ char szToken[1024];
+
+ if (authMethod == 2 && RefreshOAuth(authRefreshToken, "service::chatservice.live.com::MBI_SSL", szToken+2)) {
+ memcpy (szToken, "t=", 2);
+ replaceStr(authStrToken, szToken);
+ setString("authStrToken", authStrToken);
+ }
+ if (RefreshOAuth(authRefreshToken, "service::contacts.msn.com::MBI_SSL", szToken)) {
+ replaceStr(authContactToken, szToken);
+ setString("authContactToken", authContactToken);
+ }
+ if (RefreshOAuth(authRefreshToken, "service::storage.msn.com::MBI_SSL", szToken)) {
+ replaceStr(authStorageToken, szToken);
+ setString("authStorageToken", authStorageToken);
+ }
+ return 0;
+ }
+
char szPassword[100];
db_get_static(NULL, m_szModuleName, "Password", szPassword, sizeof(szPassword));
szPassword[16] = 0;
@@ -666,6 +686,7 @@ void CMsnProto::LoadAuthTokensDB(void)
authTokenExpiretime = getDword("authTokenExpiretime", 0);
authMethod = getDword("authMethod", 0);
+ bPassportAuth = getByte("PassportAuth", true);
if (getString("authUser", &dbv) == 0) {
replaceStr(authUser, dbv.pszVal);
db_free(&dbv);
@@ -800,7 +821,7 @@ LRESULT CALLBACK AuthWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar
else pAuth->pszCookies = mir_u2a(pAuth->pEmbed->getCookies());
PostMessage(hwnd, WM_CLOSE, 0, 0);
}
- else if (wcsstr((WCHAR*)lParam, L"res=cancel")) {
+ else if (wcsstr((WCHAR*)lParam, L"res=cancel") || wcsstr((WCHAR*)lParam, L"access_denied")) {
PostMessage(hwnd, WM_CLOSE, 0, 0);
}
return(0);
@@ -887,6 +908,77 @@ bool CMsnProto::parseLoginPage(char *pszHTML, NETLIBHTTPREQUEST *nlhr, CMStringA
return false;
}
+// -1 - Refresh failed
+// 0 - No need to refresh
+// 1 - Refresh succeeded
+int CMsnProto::MSN_RefreshOAuthTokens(void)
+{
+ time_t t;
+ char szToken[1024], szRefreshToken[1024];
+ bool bPassportAuthBak = bPassportAuth;
+
+ if (!authTokenExpiretime || time(&t)+3600 < authTokenExpiretime) return 0;
+
+ // Ensure that we won't be invoked twice
+ t = authTokenExpiretime;
+ authTokenExpiretime = 0x7FFFFFFF;
+
+ bPassportAuth = false;
+ MSN_GetPassportAuth();
+ bPassportAuth = bPassportAuthBak;
+
+ if (authSSLToken && RefreshOAuth(authRefreshToken, "service::ssl.live.com::MBI_SSL", szToken)) {
+ replaceStr(authSSLToken, szToken);
+ setString("authSSLToken", authSSLToken);
+ }
+
+ if (!RefreshOAuth(authRefreshToken, "service::skype.com::MBI_SSL", szToken, szRefreshToken, &authTokenExpiretime)) {
+ authTokenExpiretime = t;
+ return -1;
+ }
+ if (authSkypeComToken) replaceStr(authSkypeComToken, szToken);
+ replaceStr(authRefreshToken, szRefreshToken);
+ setDword("authTokenExpiretime", authTokenExpiretime);
+ setString("authRefreshToken", authRefreshToken);
+
+ return 1;
+}
+
+void CMsnProto::MSN_SendATH(ThreadData* info)
+{
+ if (MyOptions.netId!=NETID_SKYPE) {
+ /* MSN account login */
+
+ switch (authMethod)
+ {
+ case 1:
+ info->sendPacketPayload("ATH", "CON\\USER",
+ "<user><ssl-compact-ticket>t=%s</ssl-compact-ticket>"
+ "<uic>%s</uic>"
+ "<id>%s</id><alias>%s</alias></user>\r\n",
+ authSSLToken ? ptrA(HtmlEncode(authSSLToken)) : "",
+ authUIC,
+ GetMyUsername(NETID_MSN), GetMyUsername(NETID_SKYPE));
+ break;
+
+ case 2:
+ info->sendPacketPayload("ATH", "CON\\USER",
+ "<user><ssl-compact-ticket>%s</ssl-compact-ticket>"
+ "<uic>%s</uic>"
+ "<ssl-site-name>chatservice.live.com</ssl-site-name>"
+ "</user>\r\n",
+ authStrToken ? ptrA(HtmlEncode(authStrToken)) : "",
+ authUIC);
+ break;
+ }
+
+ } else {
+ info->sendPacketPayload("ATH", "CON\\USER",
+ "<user><uic>%s</uic><id>%s</id></user>\r\n",
+ authUIC, MyOptions.szEmail);
+ }
+}
+
// -1 - Error on login sequence
// 0 - Login failed (invalid username?)
// 1 - Login via Skype login server succeeded
@@ -894,7 +986,6 @@ bool CMsnProto::parseLoginPage(char *pszHTML, NETLIBHTTPREQUEST *nlhr, CMStringA
int CMsnProto::MSN_AuthOAuth(void)
{
int retVal = -1;
- bool bPassportAuth = true;
NETLIBHTTPREQUEST nlhr = { 0 };
NETLIBHTTPREQUEST *nlhrReply;
NETLIBHTTPHEADER headers[3];
@@ -952,6 +1043,8 @@ int CMsnProto::MSN_AuthOAuth(void)
char *pszURL=NULL, *pAccessToken, *pEnd;
hHttpsConnection = nlhrReply2->nlc;
+ bPassportAuth = true;
+
if (nlhrReply2->resultCode == 302) {
/* Extract access_token from Location can be found */
for (int i = 0; i < nlhrReply2->headersCount; i++) {
@@ -979,6 +1072,7 @@ int CMsnProto::MSN_AuthOAuth(void)
bPassportAuth = false;
}
}
+ setByte("PassportAuth", bPassportAuth);
CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
nlhrReply = nlhrReply2;
diff --git a/protocols/MSN/src/msn_commands.cpp b/protocols/MSN/src/msn_commands.cpp
index 38539e0658..a55920569f 100644
--- a/protocols/MSN/src/msn_commands.cpp
+++ b/protocols/MSN/src/msn_commands.cpp
@@ -418,7 +418,7 @@ void CMsnProto::MSN_ProcessURIObject(MCONTACT hContact, ezxml_t xmli)
if ((pszSkypeToken=GetSkypeToken(true)) && xmli) {
/* FIXME: As soon as core has functions to POST images in a conversation AND gives the possibility to supply a
- * callback for fetching thta image, this may be possible, but currently due to required Auth-Header, this
+ * callback for fetching that image, this may be possible, but currently due to required Auth-Header, this
* is not possible and we just send an incoming file transfer
const char *thumb = ezxml_attr(xmli, "url_thumbnail");
if (thumb && ServiceExists("IEVIEW/NewWindow")) {
@@ -914,26 +914,28 @@ LBL_InvalidCommand:
HReadBuffer buf(info, 0);
buf.surelyRead(atol(data.strMsgBytes));
- if (!bSentBND)
- {
- info->sendPacketPayload("BND", "CON\\MSGR",
- "<msgr><ver>%d</ver>%s<client><name>%s</name><ver>%s</ver></client>"
- "<epid>%.*s</epid></msgr>\r\n",
- msnP24Ver, (msnP24Ver>1?"<altVersions><ver>1</ver></altVersions>":""),
- msnStoreAppId, msnProductVer,
- mir_strlen(MyOptions.szMachineGuid)-2, MyOptions.szMachineGuid+1);
- bSentBND = true;
- }
- else
- {
- msnLoggedIn = true;
- isConnectSuccess = true;
- emailEnabled = MyOptions.netId==NETID_MSN; // Let's assume it?
- MSN_SetServerStatus(m_iDesiredStatus);
- MSN_EnableMenuItems(true);
- // Fork refreshing and populating contact list to the background
- ForkThread(&CMsnProto::msn_loginThread, NULL);
- }
+ if (!bIgnoreATH) {
+ if (!bSentBND)
+ {
+ info->sendPacketPayload("BND", "CON\\MSGR",
+ "<msgr><ver>%d</ver>%s<client><name>%s</name><ver>%s</ver></client>"
+ "<epid>%.*s</epid></msgr>\r\n",
+ msnP24Ver, (msnP24Ver>1?"<altVersions><ver>1</ver></altVersions>":""),
+ msnStoreAppId, msnProductVer,
+ mir_strlen(MyOptions.szMachineGuid)-2, MyOptions.szMachineGuid+1);
+ bSentBND = true;
+ }
+ else
+ {
+ msnLoggedIn = true;
+ isConnectSuccess = true;
+ emailEnabled = MyOptions.netId==NETID_MSN; // Let's assume it?
+ MSN_SetServerStatus(m_iDesiredStatus);
+ MSN_EnableMenuItems(true);
+ // Fork refreshing and populating contact list to the background
+ ForkThread(&CMsnProto::msn_loginThread, NULL);
+ }
+ } else bIgnoreATH = false;
}
break;
@@ -985,29 +987,7 @@ LBL_InvalidCommand:
if (MyOptions.netId!=NETID_SKYPE) {
/* MSN account login */
- switch (MSN_AuthOAuth())
- {
- case 1:
- info->sendPacketPayload("ATH", "CON\\USER",
- "<user><ssl-compact-ticket>t=%s</ssl-compact-ticket>"
- "<uic>%s</uic>"
- "<id>%s</id><alias>%s</alias></user>\r\n",
- authSSLToken ? ptrA(HtmlEncode(authSSLToken)) : "",
- authUIC,
- GetMyUsername(NETID_MSN), GetMyUsername(NETID_SKYPE));
- break;
-
- case 2:
- info->sendPacketPayload("ATH", "CON\\USER",
- "<user><ssl-compact-ticket>%s</ssl-compact-ticket>"
- "<uic>%s</uic>"
- "<ssl-site-name>chatservice.live.com</ssl-site-name>"
- "</user>\r\n",
- authStrToken ? ptrA(HtmlEncode(authStrToken)) : "",
- authUIC);
- break;
-
- default:
+ if (MSN_AuthOAuth()<1) {
m_iDesiredStatus = ID_STATUS_OFFLINE;
return 1;
}
@@ -1020,12 +1000,11 @@ LBL_InvalidCommand:
char szUIC[1024]={0};
MSN_SkypeAuth(xmlnonce->txt, szUIC);
- info->sendPacketPayload("ATH", "CON\\USER",
- "<user><uic>%s</uic><id>%s</id></user>\r\n",
- szUIC, MyOptions.szEmail);
+ replaceStr(authUIC, szUIC);
}
ezxml_free(xmlcnt);
}
+ MSN_SendATH(info);
bSentBND = false;
if (!hKeepAliveThreadEvt) ForkThread(&CMsnProto::msn_keepAliveThread, NULL);
diff --git a/protocols/MSN/src/msn_ieembed.cpp b/protocols/MSN/src/msn_ieembed.cpp
index f231bbafed..996a531093 100644
--- a/protocols/MSN/src/msn_ieembed.cpp
+++ b/protocols/MSN/src/msn_ieembed.cpp
@@ -126,7 +126,8 @@ static LRESULT CALLBACK IEEmbedServerWindowProcedure(HWND hwnd, UINT message, WP
break; */
case WM_KEYDOWN:
- (*view)->translateAccelerator(message, wParam, lParam);
+ if (LOWORD(wParam) != VK_BACK)
+ (*view)->translateAccelerator(message, wParam, lParam);
break;
/*
diff --git a/protocols/MSN/src/msn_proto.h b/protocols/MSN/src/msn_proto.h
index d5dc0d0152..528be998a8 100644
--- a/protocols/MSN/src/msn_proto.h
+++ b/protocols/MSN/src/msn_proto.h
@@ -118,10 +118,10 @@ struct CMsnProto : public PROTO<CMsnProto>
char *authStorageToken;
char *hotSecretToken, *hotAuthToken;
char *authUser, *authUIC, *authCookies, *authSSLToken, *authAccessToken, *authRefreshToken, *authSkypeComToken, *authSkypeToken;
- bool bAskingForAuth;
+ bool bAskingForAuth, bPassportAuth;
int authMethod;
time_t authTokenExpiretime;
- bool bSentBND;
+ bool bSentBND, bIgnoreATH;
char *abCacheKey, *sharingCacheKey, *storageCacheKey;
@@ -278,6 +278,7 @@ struct CMsnProto : public PROTO<CMsnProto>
void __cdecl msn_keepAliveThread(void* arg);
void __cdecl msn_loginThread(void* arg);
void __cdecl msn_IEAuthThread(void* arg);
+ void __cdecl msn_refreshOAuthThread(void*);
void __cdecl MSNServerThread(void* arg);
void __cdecl MsnFileAckThread(void* arg);
@@ -499,6 +500,8 @@ struct CMsnProto : public PROTO<CMsnProto>
int LoginSkypeOAuth(const char *pRefreshToken);
bool RefreshOAuth(const char *pszRefreshToken, const char *pszService, char *pszAccessToken, char *pszOutRefreshToken=NULL, time_t *ptExpires=NULL);
int MSN_AuthOAuth(void);
+ int MSN_RefreshOAuthTokens(void);
+ void MSN_SendATH(ThreadData* info);
CMStringA HotmailLogin(const char* url);
void FreeAuthTokens(void);
int GetMyNetID(void);
diff --git a/protocols/MSN/src/msn_threads.cpp b/protocols/MSN/src/msn_threads.cpp
index e72575e1fb..8671f2032a 100644
--- a/protocols/MSN/src/msn_threads.cpp
+++ b/protocols/MSN/src/msn_threads.cpp
@@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
void __cdecl CMsnProto::msn_keepAliveThread(void*)
{
bool keepFlag = true;
+ time_t t;
hKeepAliveThreadEvt = CreateEvent(NULL, FALSE, FALSE, NULL);
@@ -58,6 +59,8 @@ void __cdecl CMsnProto::msn_keepAliveThread(void*)
mStatusMsgTS = 0;
ForkThread(&CMsnProto::msn_storeProfileThread, NULL);
}
+ if (MyOptions.netId!=NETID_SKYPE && time(&t) >= authTokenExpiretime-3600)
+ ForkThread(&CMsnProto::msn_refreshOAuthThread, msnNsThread);
break;
case WAIT_OBJECT_0:
@@ -80,6 +83,13 @@ void __cdecl CMsnProto::msn_loginThread(void*)
MSN_FetchRecentMessages();
}
+void __cdecl CMsnProto::msn_refreshOAuthThread(void *param)
+{
+ if (MSN_RefreshOAuthTokens() > 0) {
+ bIgnoreATH = true;
+ MSN_SendATH((ThreadData*)param);
+ }
+}
/////////////////////////////////////////////////////////////////////////////////////////
// MSN server thread - read and process commands from a server