From c014bd45e4761fd8da881e4f726022fc918624b2 Mon Sep 17 00:00:00 2001 From: Piotr Piastucki Date: Wed, 27 May 2015 01:13:45 +0000 Subject: Implemented fetching Skype Token for Cloud storage API. Fixed error handling. Implemented handling of RichText/UriObject git-svn-id: http://svn.miranda-ng.org/main/trunk@13855 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/MSN/src/msn_auth.cpp | 87 +++++++++++++ protocols/MSN/src/msn_commands.cpp | 136 ++++++++++++++++---- protocols/MSN/src/msn_errors.cpp | 33 +++++ protocols/MSN/src/msn_global.h | 4 +- protocols/MSN/src/msn_misc.cpp | 15 ++- protocols/MSN/src/msn_proto.cpp | 248 +++++++++++++++++++++++++++---------- protocols/MSN/src/msn_proto.h | 6 +- protocols/MSN/src/msn_threads.cpp | 6 +- 8 files changed, 438 insertions(+), 97 deletions(-) diff --git a/protocols/MSN/src/msn_auth.cpp b/protocols/MSN/src/msn_auth.cpp index e8282c00bd..47192116cd 100644 --- a/protocols/MSN/src/msn_auth.cpp +++ b/protocols/MSN/src/msn_auth.cpp @@ -692,6 +692,18 @@ void CMsnProto::LoadAuthTokensDB(void) replaceStr(authStorageToken, dbv.pszVal); db_free(&dbv); } + if (getString("authRefreshToken", &dbv) == 0) { + replaceStr(authRefreshToken, dbv.pszVal); + db_free(&dbv); + } + if (getString("authSkypeComToken", &dbv) == 0) { + replaceStr(authSkypeComToken, dbv.pszVal); + db_free(&dbv); + } + if (getString("authSkypeToken", &dbv) == 0) { + replaceStr(authSkypeToken, dbv.pszVal); + db_free(&dbv); + } } void CMsnProto::SaveAuthTokensDB(void) @@ -703,6 +715,7 @@ void CMsnProto::SaveAuthTokensDB(void) setString("authUIC", authUIC); setString("authCookies", authCookies); setString("authStrToken", authStrToken); + setString("authRefreshToken", authRefreshToken); } // -1 - Error on login sequence @@ -815,6 +828,7 @@ int CMsnProto::MSN_AuthOAuth(void) *pEnd = 0; pRefreshToken+=14; } + replaceStr(authRefreshToken, pRefreshToken); /* Extract expire time */ time(&authTokenExpiretime); @@ -841,6 +855,8 @@ int CMsnProto::MSN_AuthOAuth(void) authMethod=retVal=1; } } + mir_free(authSkypeComToken); authSkypeComToken = NULL; + mir_free(authSkypeToken); authSkypeToken = NULL; /* If you need Skypewebexperience login, as i.e. skylogin.dll is not available, we do this here */ @@ -920,6 +936,74 @@ const char *CMsnProto::GetMyUsername(int netId) return MyOptions.szEmail; } +const char *CMsnProto::GetSkypeToken(bool bAsAuthHeader) +{ + char szToken[1024]; + + // Ensure that token isn't expired + MSN_AuthOAuth(); + + // No token available, fetch it + if (!authSkypeToken) { + // Get skype.com OAuth token needed to acquire skype_token + if (!authSkypeComToken) { + if (RefreshOAuth(authRefreshToken, "service::skype.com::MBI_SSL", szToken)) + replaceStr(authSkypeComToken, szToken); + else return NULL; + } + + // Get skype_token + NETLIBHTTPREQUEST nlhr = { 0 }; + NETLIBHTTPREQUEST *nlhrReply; + NETLIBHTTPHEADER headers[1]; + char szPOST[2048]; + + nlhr.cbSize = sizeof(nlhr); + nlhr.requestType = REQUEST_POST; + nlhr.flags = NLHRF_HTTP11 | NLHRF_DUMPASTEXT | NLHRF_PERSISTENT | NLHRF_REDIRECT; + nlhr.nlc = hHttpsConnection; + nlhr.headersCount = SIZEOF(headers); + nlhr.headers = headers; + nlhr.headers[0].szName = "User-Agent"; + nlhr.headers[0].szValue = (char*)MSN_USER_AGENT; + nlhr.szUrl = "https://api.skype.com/rps/skypetoken"; + mir_snprintf(szPOST, sizeof(szPOST), "scopes=client&clientVersion=%s&access_token=%s&partner=999", + msnProductVer, authSkypeComToken); + nlhr.dataLength = (int)strlen(szPOST); + nlhr.pData = (char*)(const char*)szPOST; + + + mHttpsTS = clock(); + nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUserHttps, (LPARAM)&nlhr); + mHttpsTS = clock(); + + if (nlhrReply) { + hHttpsConnection = nlhrReply->nlc; + + if (nlhrReply->resultCode == 200 && nlhrReply->pData) { + char *pSkypeToken, *pEnd; + + if ((pSkypeToken = strstr(nlhrReply->pData, "\"skypetoken\":\"")) && + (pEnd=strchr(pSkypeToken+15, '"'))) + { + *pEnd = 0; + pSkypeToken+=14; + mir_snprintf (szToken, sizeof(szToken), "skype_token %s", pSkypeToken); + replaceStr(authSkypeToken, szToken); + setString("authSkypeToken", authSkypeToken); + } + + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply); + } else hHttpsConnection = NULL; + } + if (!bAsAuthHeader && authSkypeToken) { + char *pszRet = strchr(authSkypeToken, ' '); + if (pszRet) return pszRet+1; + } + return authSkypeToken; +} + void CMsnProto::FreeAuthTokens(void) { mir_free(pAuthToken); @@ -933,7 +1017,10 @@ void CMsnProto::FreeAuthTokens(void) mir_free(authUIC); mir_free(authCookies); mir_free(authSSLToken); + mir_free(authSkypeComToken); + mir_free(authSkypeToken); mir_free(authUser); mir_free(authAccessToken); + mir_free(authRefreshToken); free(hotAuthToken); } diff --git a/protocols/MSN/src/msn_commands.cpp b/protocols/MSN/src/msn_commands.cpp index d80bddf470..8e51383a71 100644 --- a/protocols/MSN/src/msn_commands.cpp +++ b/protocols/MSN/src/msn_commands.cpp @@ -213,6 +213,13 @@ void CMsnProto::MSN_ReceiveMessage(ThreadData* info, char* cmdString, char* para (!_strnicmp(tContentType, "application/user+xml", 10) && tHeader["Message-Type"] && !strncmp(tHeader["Message-Type"], "RichText", 8))) { MCONTACT hContact = strncmp(email, "19:", 3)?MSN_HContactFromEmail(email, nick, true, true):NULL; + if (!_stricmp(tHeader["Message-Type"], "RichText/UriObject")) { + ezxml_t xmli = ezxml_parse_str(msgBody, strlen(msgBody)); + if (xmli) { + MSN_ProcessURIObject(hContact, xmli); + ezxml_free(xmli); + } + } else if (!_stricmp(tHeader["Message-Type"], "RichText/Contacts")) { ezxml_t xmli = ezxml_parse_str(msgBody, mir_strlen(msgBody)); if (xmli) { @@ -359,27 +366,11 @@ void CMsnProto::MSN_ReceiveMessage(ThreadData* info, char* cmdString, char* para else tContact = MSN_HContactFromEmail(email, nick, true, true); if (!mir_strcmp(tHeader["Message-Type"], "Nudge")) NotifyEventHooks(hMSNNudge, (WPARAM)tContact, 0); - -#ifdef OBSOLETE - MimeHeaders tFileInfo; - tFileInfo.readFromBuffer(msgBody); - - const char* id = tFileInfo["ID"]; - if (id != NULL) { - switch (atol(id)) { - case 1: // Nudge - NotifyEventHooks(hMSNNudge, (WPARAM)tContact, 0); - break; - - case 2: // Wink - break; - - case 4: // Action Message - break; - } - } - } -#endif + /* Other msg types: + * Wink + * Voice + * Data + */ } else if (!_strnicmp(tContentType, "text/x-msmsgsemailnotification", 30)) sttNotificationMessage(msgBody, false); @@ -421,6 +412,101 @@ void CMsnProto::MSN_ReceiveMessage(ThreadData* info, char* cmdString, char* para mir_free(newbody); } +void CMsnProto::MSN_ProcessURIObject(MCONTACT hContact, ezxml_t xmli) +{ + const char *pszSkypeToken; + + 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 + * is not possible and we just send an incoming file transfer + const char *thumb = ezxml_attr(xmli, "url_thumbnail"); + if (thumb && ServiceExists("IEVIEW/NewWindow")) { + // Supply callback to detch thumb with auth-header and embed [img] BB-code? + } + */ + char *uri = (char*)ezxml_attr(xmli, "uri"); + if (uri) { + // First get HTTP header of file to get content length + unsigned __int64 fileSize = 0; + NETLIBHTTPHEADER nlbhHeaders[2] = { 0 }; + nlbhHeaders[0].szName = "User-Agent"; nlbhHeaders[0].szValue = (LPSTR)MSN_USER_AGENT; + nlbhHeaders[1].szName = "Authorization"; nlbhHeaders[1].szValue = (char*)pszSkypeToken; + + NETLIBHTTPREQUEST nlhr = { 0 }, *nlhrReply; + nlhr.cbSize = sizeof(nlhr); + nlhr.requestType = REQUEST_GET; + nlhr.flags = NLHRF_GENERATEHOST | NLHRF_PERSISTENT | NLHRF_SMARTAUTHHEADER; + nlhr.szUrl = uri; + nlhr.headers = (NETLIBHTTPHEADER*)&nlbhHeaders; + nlhr.headersCount = SIZEOF(nlbhHeaders); + nlhr.nlc = hHttpsConnection; + + mHttpsTS = clock(); + nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUserHttps, (LPARAM)&nlhr); + mHttpsTS = clock(); + if (nlhrReply) { + hHttpsConnection = nlhrReply->nlc; + if (nlhrReply->resultCode == 200) { + char *pLength, *pEnd; + + if ((pLength = strstr(nlhrReply->pData, "\"contents\":")) && (pLength = strstr(pLength, "\"imgpsh\"")) && + (pLength = strstr(pLength, "\"length\":")) && (pEnd = strchr(pLength+9, ','))) { + pLength+=9; + *pEnd = 0; + fileSize=_atoi64(pLength); + } + } + + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply); + } else hHttpsConnection = NULL; + + if (fileSize) { + filetransfer* ft = new filetransfer(this); + char *pszFile; + ezxml_t originalName, desc; + + ft->std.hContact = hContact; + ft->tType = SERVER_HTTP; + ft->p2p_appID = MSN_APPID_FILE; + mir_free(ft->std.tszCurrentFile); + if (!((originalName = ezxml_child(xmli, "OriginalName")) && (pszFile = (char*)ezxml_attr(originalName, "v")))) { + if ((originalName = ezxml_child(xmli, "meta"))) + pszFile = (char*)ezxml_attr(originalName, "originalName"); + } + ft->std.tszCurrentFile = mir_utf8decodeT(pszFile); + ft->std.totalBytes = ft->std.currentFileSize = fileSize; + ft->std.totalFiles = 1; + ft->szInvcookie = (char*)mir_calloc(strlen(uri)+16); + sprintf(ft->szInvcookie, "%s/content/imgpsh", uri); + + TCHAR tComment[40]; + mir_sntprintf(tComment, SIZEOF(tComment), TranslateT("%I64u bytes"), ft->std.currentFileSize); + + PROTORECVFILET pre = { 0 }; + pre.dwFlags = PRFF_TCHAR; + pre.fileCount = 1; + pre.timestamp = time(NULL); + pre.tszDescription = (desc = ezxml_child(xmli, "Description"))?mir_utf8decodeT(desc->txt):tComment; + pre.ptszFiles = &ft->std.tszCurrentFile; + pre.lParam = (LPARAM)ft; + ProtoChainRecvFile(ft->std.hContact, &pre); + if (desc) mir_free(pre.tszDescription); + } else uri=NULL; + } + + if (uri == NULL) { + // Fallback: Just filter out the link and post it as a message + CallService(MS_PROTO_CONTACTISTYPING, WPARAM(hContact), 0); + + PROTORECVEVENT pre = { 0 }; + pre.szMessage = (char*)ezxml_txt(xmli); + pre.timestamp = (DWORD)time(NULL); + ProtoChainRecvMsg(hContact, &pre); + } + } +} + ///////////////////////////////////////////////////////////////////////////////////////// // Process Yahoo Find @@ -1032,8 +1118,12 @@ LBL_InvalidCommand: ezxml_free(xmlact); } continue; - } else if (mir_strcmp(msgtype->txt, "Text")) continue; - /* TODO: Implement i.e. RichText/Files for announcement of file transfers */ + } else if (!mir_strcmp(msgtype->txt, "RichText/UriObject")) { + if (ezxml_t xmlact = ezxml_parse_str(content->txt, mir_strlen(content->txt))) { + MSN_ProcessURIObject(hContact, xmlact); + ezxml_free(xmlact); + } + } else if (mir_strcmp(msgtype->txt, "Text")) continue; /* TODO: Implement i.e. RichText/Files for announcement of file transfers */ } if (bIsChat) { diff --git a/protocols/MSN/src/msn_errors.cpp b/protocols/MSN/src/msn_errors.cpp index 916ce9070e..2a5752f9f7 100644 --- a/protocols/MSN/src/msn_errors.cpp +++ b/protocols/MSN/src/msn_errors.cpp @@ -28,6 +28,39 @@ int CMsnProto::MSN_HandleErrors(ThreadData* info, char* cmdString) int errorCode, packetID = -1; sscanf(cmdString, "%d %d", &errorCode, &packetID); + char* params = ""; + int trid = -1; + + if (cmdString[3]) { + if (isdigit((BYTE)cmdString[4])) { + trid = strtol(cmdString + 4, ¶ms, 10); + switch (*params) { + case ' ': case '\0': case '\t': case '\n': + while (*params == ' ' || *params == '\t') + params++; + break; + + default: + params = cmdString + 4; + } + } + else params = cmdString + 4; + } + + union { + char* tWords[2]; + struct { char *typeId, *strMsgBytes; } data; + }; + + if (sttDivideWords(params, SIZEOF(tWords), tWords) < 2) { + debugLogA("Invalid %.3s command, ignoring", cmdString); + return 0; + } + + HReadBuffer buf(info, 0); + char* msgBody = (char*)buf.surelyRead(atol(data.strMsgBytes)); + + debugLogA("Server error:%s", cmdString); switch (errorCode) { diff --git a/protocols/MSN/src/msn_global.h b/protocols/MSN/src/msn_global.h index 59f8d78cd0..1ce626523e 100644 --- a/protocols/MSN/src/msn_global.h +++ b/protocols/MSN/src/msn_global.h @@ -374,7 +374,8 @@ enum TInfoType SERVER_NOTIFICATION, SERVER_SWITCHBOARD, SERVER_FILETRANS, - SERVER_P2P_DIRECT + SERVER_P2P_DIRECT, + SERVER_HTTP }; @@ -400,6 +401,7 @@ struct filetransfer int fileId; // handle of file being transferring (r/w) HANDLE hLockHandle; + HANDLE hResumeEvt; ThreadData *info; TInfoType tType; diff --git a/protocols/MSN/src/msn_misc.cpp b/protocols/MSN/src/msn_misc.cpp index f52e6a826e..a0657fec04 100644 --- a/protocols/MSN/src/msn_misc.cpp +++ b/protocols/MSN/src/msn_misc.cpp @@ -1112,7 +1112,6 @@ void CMsnProto::MSN_ShowPopup(const MCONTACT hContact, const TCHAR* msg, int fla ///////////////////////////////////////////////////////////////////////////////////////// // filetransfer class members -#ifdef OBSOLETE filetransfer::filetransfer(CMsnProto* prt) { memset(this, 0, sizeof(filetransfer)); @@ -1122,6 +1121,7 @@ filetransfer::filetransfer(CMsnProto* prt) proto = prt; hLockHandle = CreateMutex(NULL, FALSE, NULL); + hResumeEvt = CreateEvent(NULL, FALSE, FALSE, NULL); } filetransfer::~filetransfer(void) @@ -1131,11 +1131,14 @@ filetransfer::~filetransfer(void) WaitForSingleObject(hLockHandle, 2000); CloseHandle(hLockHandle); + CloseHandle(hResumeEvt); if (fileId != -1) { _close(fileId); - if (p2p_appID != MSN_APPID_FILE && !(std.flags & PFTS_SENDING)) +#ifdef OBSOLETE + if (tType != SERVER_HTTP && p2p_appID != MSN_APPID_FILE && !(std.flags & PFTS_SENDING)) proto->p2p_pictureTransferFailed(this); +#endif } if (!bCompleted && p2p_appID == MSN_APPID_FILE) { @@ -1176,7 +1179,10 @@ void filetransfer::complete(void) int filetransfer::create(void) { - fileId = _topen(std.tszCurrentFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE); + int flags = _O_BINARY | _O_CREAT | _O_WRONLY | _O_APPEND; + + if (std.currentFileProgress == 0) flags |= _O_TRUNC; + fileId = _topen(std.tszCurrentFile, flags, _S_IREAD | _S_IWRITE); if (fileId == -1) proto->MSN_ShowError("Cannot create file '%s' during a file transfer", std.tszCurrentFile); @@ -1225,6 +1231,7 @@ int filetransfer::openNext(void) return fileId; } +#ifdef OBSOLETE directconnection::directconnection(const char* CallID, const char* Wlid) { memset(this, 0, sizeof(directconnection)); @@ -1287,8 +1294,6 @@ void directconnection::xNonceToBin(UUID* nonce) p[len - 2] = 0; UuidFromStringA((BYTE*)p, nonce); } -#else -filetransfer::~filetransfer(void) { } #endif ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/protocols/MSN/src/msn_proto.cpp b/protocols/MSN/src/msn_proto.cpp index acf07cc3a4..cc8cf98566 100644 --- a/protocols/MSN/src/msn_proto.cpp +++ b/protocols/MSN/src/msn_proto.cpp @@ -458,10 +458,34 @@ HANDLE __cdecl CMsnProto::SearchByEmail(const PROTOCHAR* email) return SearchBasic(email); } -#ifdef OBSOLETE ///////////////////////////////////////////////////////////////////////////////////////// // MsnFileAllow - starts the file transfer +// stolen from netlibhttp.cpp +static void MyNetlibConnFromUrl(const char* szUrl, NETLIBOPENCONNECTION &nloc) +{ + bool secur =_strnicmp(szUrl, "https", 5) == 0; + const char* phost = strstr(szUrl, "://"); + + char* szHost = mir_strdup(phost ? phost + 3 : szUrl); + + char* ppath = strchr(szHost, '/'); + if (ppath) *ppath = '\0'; + + memset(&nloc, 0, sizeof(nloc)); + nloc.cbSize = sizeof(nloc); + nloc.szHost = szHost; + + char* pcolon = strrchr(szHost, ':'); + if (pcolon) { + *pcolon = '\0'; + nloc.wPort = (WORD)strtol(pcolon+1, NULL, 10); + } + else nloc.wPort = secur ? 443 : 80; + nloc.flags = (secur ? NLOCF_SSL : 0); +} + + void __cdecl CMsnProto::MsnFileAckThread(void* arg) { filetransfer* ft = (filetransfer*)arg; @@ -470,27 +494,92 @@ void __cdecl CMsnProto::MsnFileAckThread(void* arg) mir_sntprintf(filefull, SIZEOF(filefull), _T("%s\\%s"), ft->std.tszWorkingDir, ft->std.tszCurrentFile); replaceStrT(ft->std.tszCurrentFile, filefull); + ResetEvent(ft->hResumeEvt); if (ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, ft, (LPARAM)&ft->std)) - return; + WaitForSingleObject(ft->hResumeEvt, INFINITE); - bool fcrt = ft->create() != -1; + ft->create(); - if (ft->p2p_appID != 0) { - if (fcrt) - p2p_sendFeedStart(ft); - p2p_sendStatus(ft, fcrt ? 200 : 603); +#ifdef OBSOLETE + if (ft->tType != SERVER_HTTP) { + if (ft->p2p_appID != 0) { + if (fcrt) + p2p_sendFeedStart(ft); + p2p_sendStatus(ft, fcrt ? 200 : 603); + } + else msnftp_sendAcceptReject(ft, fcrt); } - else msnftp_sendAcceptReject(ft, fcrt); +#endif ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ft, 0); + + if (ft->tType == SERVER_HTTP) { + const char *pszSkypeToken; + + if (ft->fileId != -1 && (pszSkypeToken=GetSkypeToken(true))) { + NETLIBHTTPHEADER nlbhHeaders[3] = { 0 }; + NETLIBHTTPREQUEST nlhr = { 0 }, *nlhrReply; + char szRange[32]; + + nlbhHeaders[0].szName = "User-Agent"; nlbhHeaders[0].szValue = (LPSTR)MSN_USER_AGENT; + nlbhHeaders[1].szName = "Authorization"; nlbhHeaders[1].szValue = (char*)pszSkypeToken; + nlhr.headersCount = 2; + if (ft->std.currentFileProgress) { + mir_snprintf(szRange, sizeof(szRange), "bytes=%I64d-", ft->std.currentFileProgress); + nlbhHeaders[2].szName = "Range"; + nlbhHeaders[2].szValue = szRange; + nlhr.headersCount++; + } + + nlhr.cbSize = sizeof(nlhr); + nlhr.requestType = REQUEST_GET; + nlhr.flags = NLHRF_GENERATEHOST | NLHRF_SMARTREMOVEHOST | NLHRF_SMARTAUTHHEADER | NLHRF_HTTP11; + nlhr.szUrl = ft->szInvcookie; + nlhr.headers = (NETLIBHTTPHEADER*)&nlbhHeaders; + + NETLIBOPENCONNECTION nloc = { 0 }; + MyNetlibConnFromUrl(nlhr.szUrl, nloc); + nloc.flags |= NLOCF_HTTP; + if (nloc.flags & NLOCF_SSL) nlhr.flags |= NLHRF_SSL; + HANDLE nlc = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)m_hNetlibUser, (LPARAM)&nloc); + + if (nlc && CallService(MS_NETLIB_SENDHTTPREQUEST, (WPARAM)nlc, (LPARAM)&nlhr) != SOCKET_ERROR && + (nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_RECVHTTPHEADERS, (WPARAM)nlc, 0))) + { + if (nlhrReply->resultCode == 200 || nlhrReply->resultCode == 206) { + INT_PTR dw; + char buf[1024]; + + ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, ft, 0); + while (!ft->bCanceled && ft->std.currentFileProgress < ft->std.currentFileSize && + (dw = Netlib_Recv(nlc, buf, sizeof(buf), MSG_NODUMP))>0 && dw!=SOCKET_ERROR) + { + _write(ft->fileId, buf, dw); + ft->std.totalProgress += dw; + ft->std.currentFileProgress += dw; + ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&ft->std); + } + if (ft->std.currentFileProgress == ft->std.currentFileSize) ft->std.currentFileNumber++; + + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply); + } + Netlib_CloseHandle(nlc); + mir_free((char*)nloc.szHost); + if (ft->std.currentFileNumber >= ft->std.totalFiles) ft->complete(); + } + delete ft; + } } HANDLE __cdecl CMsnProto::FileAllow(MCONTACT, HANDLE hTransfer, const PROTOCHAR* szPath) { filetransfer* ft = (filetransfer*)hTransfer; - if (!msnLoggedIn || !p2p_sessionRegistered(ft)) +#ifdef OBSOLETE + if (ft->tType != SERVER_HTTP && (!msnLoggedIn || !p2p_sessionRegistered(ft))) return 0; +#endif if ((ft->std.tszWorkingDir = mir_tstrdup(szPath)) == NULL) { TCHAR szCurrDir[MAX_PATH]; @@ -515,26 +604,31 @@ int __cdecl CMsnProto::FileCancel(MCONTACT, HANDLE hTransfer) { filetransfer* ft = (filetransfer*)hTransfer; - if (!msnLoggedIn || !p2p_sessionRegistered(ft)) - return 0; - - if (!(ft->std.flags & PFTS_SENDING) && ft->fileId == -1) { - if (ft->p2p_appID != 0) - p2p_sendStatus(ft, 603); - else - msnftp_sendAcceptReject(ft, false); - } + if (ft->tType == SERVER_HTTP) ft->bCanceled = true; +#ifdef OBSOLETE else { - ft->bCanceled = true; - if (ft->p2p_appID != 0) { - p2p_sendCancel(ft); - if (!(ft->std.flags & PFTS_SENDING) && ft->p2p_isV2) - p2p_sessionComplete(ft); + if (!msnLoggedIn || !p2p_sessionRegistered(ft)) + return 0; + + if (!(ft->std.flags & PFTS_SENDING) && ft->fileId == -1) { + if (ft->p2p_appID != 0) + p2p_sendStatus(ft, 603); + else + msnftp_sendAcceptReject(ft, false); + } + else { + ft->bCanceled = true; + if (ft->p2p_appID != 0) { + p2p_sendCancel(ft); + if (!(ft->std.flags & PFTS_SENDING) && ft->p2p_isV2) + p2p_sessionComplete(ft); + } } - } - ft->std.ptszFiles = NULL; - ft->std.totalFiles = 0; + ft->std.ptszFiles = NULL; + ft->std.totalFiles = 0; + } +#endif return 0; } @@ -545,20 +639,25 @@ int __cdecl CMsnProto::FileDeny(MCONTACT, HANDLE hTransfer, const PROTOCHAR* /*s { filetransfer* ft = (filetransfer*)hTransfer; - if (!msnLoggedIn || !p2p_sessionRegistered(ft)) - return 1; - - if (!(ft->std.flags & PFTS_SENDING) && ft->fileId == -1) { - if (ft->p2p_appID != 0) - p2p_sendStatus(ft, 603); - else - msnftp_sendAcceptReject(ft, false); - } + if (ft->tType == SERVER_HTTP) delete ft; +#ifdef OBSOLETE else { - ft->bCanceled = true; - if (ft->p2p_appID != 0) - p2p_sendCancel(ft); + if (!msnLoggedIn || !p2p_sessionRegistered(ft)) + return 1; + + if (!(ft->std.flags & PFTS_SENDING) && ft->fileId == -1) { + if (ft->p2p_appID != 0) + p2p_sendStatus(ft, 603); + else + msnftp_sendAcceptReject(ft, false); + } + else { + ft->bCanceled = true; + if (ft->p2p_appID != 0) + p2p_sendCancel(ft); + } } +#endif return 0; } @@ -570,38 +669,63 @@ int __cdecl CMsnProto::FileResume(HANDLE hTransfer, int* action, const PROTOCHAR { filetransfer* ft = (filetransfer*)hTransfer; - if (!msnLoggedIn || !p2p_sessionRegistered(ft)) - return 1; + if (ft->tType == SERVER_HTTP) { + switch (*action) { + case FILERESUME_SKIP: + ft->close(); + ft->bCanceled = true; + break; + case FILERESUME_RENAME: + replaceStrT(ft->std.tszCurrentFile, *szFilename); + break; + case FILERESUME_OVERWRITE: + ft->std.currentFileProgress = 0; + break; + case FILERESUME_RESUME: + { + struct _stati64 statbuf; + _tstati64(ft->std.tszCurrentFile, &statbuf); + ft->std.currentFileProgress = statbuf.st_size; + } + break; + } + SetEvent(ft->hResumeEvt); + } +#ifdef OBSOLETE + else { + if (!msnLoggedIn || !p2p_sessionRegistered(ft)) + return 1; - switch (*action) { - case FILERESUME_SKIP: - if (ft->p2p_appID != 0) - p2p_sendStatus(ft, 603); - else - msnftp_sendAcceptReject(ft, false); - break; + switch (*action) { + case FILERESUME_SKIP: + if (ft->p2p_appID != 0) + p2p_sendStatus(ft, 603); + else + msnftp_sendAcceptReject(ft, false); + break; - case FILERESUME_RENAME: - replaceStrT(ft->std.tszCurrentFile, *szFilename); + case FILERESUME_RENAME: + replaceStrT(ft->std.tszCurrentFile, *szFilename); - default: - bool fcrt = ft->create() != -1; - if (ft->p2p_appID != 0) { - if (fcrt) - p2p_sendFeedStart(ft); + default: + bool fcrt = ft->create() != -1; + if (ft->p2p_appID != 0) { + if (fcrt) + p2p_sendFeedStart(ft); - p2p_sendStatus(ft, fcrt ? 200 : 603); - } - else - msnftp_sendAcceptReject(ft, fcrt); + p2p_sendStatus(ft, fcrt ? 200 : 603); + } + else + msnftp_sendAcceptReject(ft, fcrt); - ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ft, 0); - break; + ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ft, 0); + break; + } } +#endif return 0; } -#endif ///////////////////////////////////////////////////////////////////////////////////////// // MsnGetAwayMsg - reads the current status message for a user @@ -646,7 +770,7 @@ DWORD_PTR __cdecl CMsnProto::GetCaps(int type, MCONTACT) case PFLAGNUM_1: return PF1_IM | PF1_SERVERCLIST | PF1_AUTHREQ | PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_CHAT | PF1_CONTACT | - /*PF1_FILESEND | PF1_FILERECV | */PF1_URLRECV | PF1_VISLIST | PF1_MODEMSG; + /*PF1_FILESEND |*/ PF1_FILERECV | PF1_URLRECV | PF1_VISLIST | PF1_MODEMSG; case PFLAGNUM_2: return PF2_ONLINE | PF2_SHORTAWAY | PF2_LIGHTDND | PF2_INVISIBLE | PF2_ONTHEPHONE | PF2_IDLE; diff --git a/protocols/MSN/src/msn_proto.h b/protocols/MSN/src/msn_proto.h index f9d238475f..271f6b6100 100644 --- a/protocols/MSN/src/msn_proto.h +++ b/protocols/MSN/src/msn_proto.h @@ -40,12 +40,10 @@ struct CMsnProto : public PROTO virtual int __cdecl AuthRecv(MCONTACT hContact, PROTORECVEVENT*); virtual int __cdecl AuthRequest(MCONTACT hContact, const TCHAR* szMessage); -#ifdef OBSOLETE virtual HANDLE __cdecl FileAllow(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* szPath); virtual int __cdecl FileCancel(MCONTACT hContact, HANDLE hTransfer); virtual int __cdecl FileDeny(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* szReason); virtual int __cdecl FileResume(HANDLE hTransfer, int* action, const PROTOCHAR** szFilename); -#endif virtual DWORD_PTR __cdecl GetCaps(int type, MCONTACT hContact = NULL); @@ -118,7 +116,7 @@ struct CMsnProto : public PROTO char *authContactToken; char *authStorageToken; char *hotSecretToken, *hotAuthToken; - char *authUser, *authUIC, *authCookies, *authSSLToken, *authAccessToken; + char *authUser, *authUIC, *authCookies, *authSSLToken, *authAccessToken, *authRefreshToken, *authSkypeComToken, *authSkypeToken; int authMethod; time_t authTokenExpiretime; bool bSentBND; @@ -222,6 +220,7 @@ struct CMsnProto : public PROTO void MSN_ProcessRemove(char* buf, size_t len); void MSN_ProcessAdd(char* buf, size_t len); void MSN_ProcessYFind(char* buf, size_t len); + void MSN_ProcessURIObject(MCONTACT hContact, ezxml_t xmli); void MSN_CustomSmiley(const char* msgBody, char* email, char* nick, int iSmileyType); void MSN_InviteMessage(ThreadData* info, char* msgBody, char* email, char* nick); void MSN_SetMirVer(MCONTACT hContact, DWORD dwValue, bool always); @@ -498,6 +497,7 @@ struct CMsnProto : public PROTO CMStringA HotmailLogin(const char* url); void FreeAuthTokens(void); int GetMyNetID(void); + const char *GetSkypeToken(bool bAsAuthHeader); LPCSTR GetMyUsername(int netId); ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/protocols/MSN/src/msn_threads.cpp b/protocols/MSN/src/msn_threads.cpp index 41ba2551db..a28e381196 100644 --- a/protocols/MSN/src/msn_threads.cpp +++ b/protocols/MSN/src/msn_threads.cpp @@ -616,9 +616,9 @@ void ThreadData::applyGatewayData(HANDLE hConn, bool isPoll) void ThreadData::getGatewayUrl(char* dest, int destlen, bool isPoll) { - static const char openFmtStr[] = "https://%s/gateway/gateway.dll?Action=open&Server=%s&IP=%s"; - static const char pollFmtStr[] = "https://%s/gateway/gateway.dll?Action=poll&SessionID=%s"; - static const char cmdFmtStr[] = "https://%s/gateway/gateway.dll?SessionID=%s"; + static const char openFmtStr[] = "http://%s/gateway/gateway.dll?Action=open&Server=%s&IP=%s"; + static const char pollFmtStr[] = "http://%s/gateway/gateway.dll?Action=poll&SessionID=%s"; + static const char cmdFmtStr[] = "http://%s/gateway/gateway.dll?SessionID=%s"; if (mSessionID[0] == 0) { const char* svr = mType == SERVER_NOTIFICATION ? "NS" : "SB"; -- cgit v1.2.3