diff options
| -rw-r--r-- | protocols/MSN/src/msn_auth.cpp | 87 | ||||
| -rw-r--r-- | protocols/MSN/src/msn_commands.cpp | 136 | ||||
| -rw-r--r-- | protocols/MSN/src/msn_errors.cpp | 33 | ||||
| -rw-r--r-- | protocols/MSN/src/msn_global.h | 4 | ||||
| -rw-r--r-- | protocols/MSN/src/msn_misc.cpp | 15 | ||||
| -rw-r--r-- | protocols/MSN/src/msn_proto.cpp | 248 | ||||
| -rw-r--r-- | protocols/MSN/src/msn_proto.h | 6 | ||||
| -rw-r--r-- | 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<CMsnProto>  	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<CMsnProto>  	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<CMsnProto>  	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<CMsnProto>  	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";
  | 
