diff options
| -rw-r--r-- | protocols/MSN/src/msn_auth.cpp | 437 | ||||
| -rw-r--r-- | protocols/MSN/src/msn_errors.cpp | 1 | ||||
| -rw-r--r-- | protocols/MSN/src/msn_ieembed.cpp | 365 | ||||
| -rw-r--r-- | protocols/MSN/src/msn_ieembed.h | 140 | ||||
| -rw-r--r-- | protocols/MSN/src/msn_proto.h | 3 | ||||
| -rw-r--r-- | protocols/MSN/src/stdafx.h | 6 | 
6 files changed, 819 insertions, 133 deletions
| diff --git a/protocols/MSN/src/msn_auth.cpp b/protocols/MSN/src/msn_auth.cpp index ca0764fd11..0a7cff86bf 100644 --- a/protocols/MSN/src/msn_auth.cpp +++ b/protocols/MSN/src/msn_auth.cpp @@ -19,9 +19,21 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
  #include "stdafx.h"
 +#include <WinInet.h>
  #include "msn_proto.h"
 +#include "msn_ieembed.h"
  #include "des.h"
 +#define LOGIN_POST_PARAMS "client_id=00000000480BC46C&scope=service%3A%3Askype.com%3A%3AMBI_SSL&response_type=token&redirect_uri=https%3A%2F%2Flogin.live.com%2Foauth20_desktop.srf"
 +#define AUTH_URL "https://login.live.com/oauth20_authorize.srf?"LOGIN_POST_PARAMS
 +#define POST_URL "https://login.live.com/ppsecure/post.srf?"LOGIN_POST_PARAMS
 +
 +
 +/* WinINET delayloading */
 +typedef BOOL (*pfnInternetGetCookieExA)(LPCSTR, LPCSTR, LPSTR, LPDWORD, DWORD, LPVOID);
 +pfnInternetGetCookieExA fpInternetGetCookieExA = NULL;
 +
 +
  /* SkyLogin Prototypes */
  typedef void* SkyLogin;
  typedef SkyLogin (*pfnSkyLogin_Init)();
 @@ -717,6 +729,164 @@ void CMsnProto::SaveAuthTokensDB(void)  	setString("authRefreshToken", authRefreshToken);
  }
 +typedef struct {
 +	/* Input */
 +	CMsnProto *pProto;
 +	NETLIBHTTPREQUEST *nlhr;
 +	NETLIBHTTPREQUEST *nlhrReply;
 +	/* Output */
 +	char *pszURL;
 +	char *pszCookies;
 +	/* Internal */
 +	IEEmbed *pEmbed;
 +} IEAUTH_PARAM;
 +
 +LRESULT CALLBACK AuthWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 +{
 +	switch (uMsg)
 +	{
 +		case WM_SIZE:
 +		{
 +			IEAUTH_PARAM *pAuth = (IEAUTH_PARAM*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
 +			if (pAuth && pAuth->pEmbed) pAuth->pEmbed->ResizeBrowser();
 +			return(0);
 +		}
 +
 +		case WM_CREATE:
 +		{
 +			IEAUTH_PARAM *pAuth = (IEAUTH_PARAM*)((LPCREATESTRUCT)lParam)->lpCreateParams;
 +			pAuth->pEmbed = new IEEmbed(hwnd);
 +			WCHAR *pwszCookies = mir_a2u(pAuth->nlhr->headers[1].szValue);
 +			SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pAuth);
 +			pAuth->pEmbed->addCookie(pwszCookies);
 +			pAuth->pEmbed->navigate(AUTH_URL);
 +			mir_free(pwszCookies);
 +			return(0);
 +		}
 +
 +		case UM_DOCCOMPLETE:
 +		{
 +			if (!lParam) return 1;
 +			IEAUTH_PARAM *pAuth = (IEAUTH_PARAM*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
 +
 +			if (wcsstr((WCHAR*)lParam, L"oauth20_authorize")) {
 +				char *pszDoc = pAuth->pEmbed->GetHTMLDoc();
 +				CMStringA post;
 +
 +				if (pszDoc) {
 +					if (pAuth->pProto->parseLoginPage(pszDoc, pAuth->nlhr, &post)) {
 +						pAuth->pEmbed->navigate(pAuth->nlhr);
 +					}
 +					mir_free(pszDoc);
 +				}
 +			}
 +			else if (wcsstr((WCHAR*)lParam, L"access_token=")) {
 +				DWORD cbCookie = 0;
 +
 +				pAuth->pszURL = mir_u2a((WCHAR*)lParam);
 +
 +				/* get_cookie doesn't give us all the necessary cookies, therefore we need to use
 +				 * InternetGetCookieExA
 +				 */
 +				if (!fpInternetGetCookieExA) {
 +					HMODULE hMod = LoadLibrary(_T("wininet.dll"));
 +					if (hMod) fpInternetGetCookieExA = (pfnInternetGetCookieExA)GetProcAddress(hMod, "InternetGetCookieExA");
 +				}
 +				if (fpInternetGetCookieExA &&
 +					fpInternetGetCookieExA("https://login.live.com", NULL, NULL, &cbCookie, INTERNET_COOKIE_HTTPONLY, NULL) &&
 +					(pAuth->pszCookies = (char*)mir_alloc(cbCookie))) {
 +					fpInternetGetCookieExA("https://login.live.com", NULL, pAuth->pszCookies, &cbCookie, INTERNET_COOKIE_HTTPONLY, NULL);
 +				}
 +				else pAuth->pszCookies = mir_u2a(pAuth->pEmbed->getCookies());			
 +				PostMessage(hwnd, WM_CLOSE, 0, 0);
 +			}
 +			else if (wcsstr((WCHAR*)lParam, L"res=cancel")) {
 +				PostMessage(hwnd, WM_CLOSE, 0, 0);
 +			}
 +			return(0);
 +		}
 +
 +		case WM_CLOSE:
 +			DestroyWindow(hwnd);
 +			PostQuitMessage(0);
 +			break;
 +
 +		case WM_DESTROY:
 +		{
 +			IEAUTH_PARAM *pAuth = (IEAUTH_PARAM*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
 +			if (pAuth && pAuth->pEmbed) delete pAuth->pEmbed;
 +			return(0);
 +		}
 +
 +	}
 +
 +	return(DefWindowProc(hwnd, uMsg, wParam, lParam));
 +}
 +
 +
 +void __cdecl CMsnProto::msn_IEAuthThread(void *pParam)
 +{
 +	HWND hWnd;
 +	MSG msg;
 +    WNDCLASSEX wc={0};
 +    static const TCHAR  *ClassName = _T("SkypeLoginWindow");
 +
 +    CoInitialize(NULL);
 +
 +    wc.cbSize = sizeof(WNDCLASSEX);
 +    wc.cbWndExtra = sizeof(void*);
 +    wc.hInstance = hInst;
 +    wc.lpfnWndProc = AuthWindowProc;
 +    wc.lpszClassName = ClassName;
 +    RegisterClassEx(&wc);
 +
 +    if ((hWnd = CreateWindowEx(0, ClassName, _T("MSN Login"), WS_OVERLAPPEDWINDOW,
 +                                            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
 +                                            HWND_DESKTOP, NULL, hInst, pParam))) {
 +		ShowWindow( hWnd, SW_SHOW );
 +		UpdateWindow( hWnd );
 +
 +		while( GetMessage(&msg, NULL, 0, 0) ) 
 +		{
 +			TranslateMessage( &msg );
 +			DispatchMessage( &msg );
 +		}
 +	}
 +
 +	UnregisterClass(ClassName, hInst);
 +	CoUninitialize();
 +}
 +
 +bool CMsnProto::parseLoginPage(char *pszHTML, NETLIBHTTPREQUEST *nlhr, CMStringA *post)
 +{
 +	char *pPPFT, *pEnd;
 +
 +	/* Get PPFT */
 +	if ((pPPFT = strstr(pszHTML, "name=\"PPFT\"")) && (pPPFT = strstr(pPPFT, "value=\"")) && (pEnd=strchr(pPPFT+7, '"'))) {
 +		*pEnd=0;
 +		pPPFT+=7;
 +
 +		/* Get POST URL if available */
 +		if ((nlhr->szUrl = strstr(pszHTML, "urlPost:'")) && (pEnd=strchr(nlhr->szUrl+9, '\''))) {
 +			*pEnd=0;
 +			nlhr->szUrl += 9;
 +		} else nlhr->szUrl = POST_URL;
 +
 +		/* Create POST data */
 +		char szPassword[100];
 +		db_get_static(NULL, m_szModuleName, "Password", szPassword, sizeof(szPassword));
 +		szPassword[16] = 0;
 +		post->Format("PPFT=%s&login=%s&passwd=%s", ptrA(mir_urlEncode(pPPFT)), 
 +			ptrA(mir_urlEncode(MyOptions.szEmail)), ptrA(mir_urlEncode(szPassword)));
 +
 +		/* Do the login and get the required tokens */
 +		nlhr->dataLength = post->GetLength();
 +		nlhr->pData = (char*)post->GetString();
 +		return true;
 +	}
 +	return false;
 +}
 +
  // -1 - Error on login sequence 
  //  0 - Login failed (invalid username?)
  //  1 - Login via Skype login server succeeded
 @@ -724,12 +894,14 @@ void CMsnProto::SaveAuthTokensDB(void)  int CMsnProto::MSN_AuthOAuth(void)
  {
  	int retVal = -1;
 -	const char *pszPostParams = "client_id=00000000480BC46C&scope=service%3A%3Askype.com%3A%3AMBI_SSL&response_type=token&redirect_uri=https%3A%2F%2Flogin.live.com%2Foauth20_desktop.srf";
 +	bool bPassportAuth = true;
  	NETLIBHTTPREQUEST nlhr = { 0 };
  	NETLIBHTTPREQUEST *nlhrReply;
  	NETLIBHTTPHEADER headers[3];
  	time_t t;
 +	if (bAskingForAuth) return 0;
 +
  	// Load credentials from DB so that we don't have to do all this stuff if token isn't expired 
  	if (!authTokenExpiretime) LoadAuthTokensDB();
 @@ -747,9 +919,7 @@ int CMsnProto::MSN_AuthOAuth(void)  	nlhr.headers[0].szValue = (char*)MSN_USER_AGENT;
  	// Get oauth20 login data
 -	CMStringA url;
 -	url.Format("https://login.live.com/oauth20_authorize.srf?%s", pszPostParams);
 -	nlhr.szUrl = (char*)(const char*)url;
 +	nlhr.szUrl = AUTH_URL;
  	mHttpsTS = clock();
  	nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUserHttps, (LPARAM)&nlhr);
  	mHttpsTS = clock();
 @@ -758,35 +928,15 @@ int CMsnProto::MSN_AuthOAuth(void)  		hHttpsConnection = nlhrReply->nlc;
  		if (nlhrReply->resultCode == 200 && nlhrReply->pData) {
 -			char *pPPFT, *pEnd;
 -
 -			/* Get PPFT */
 -			if ((pPPFT = strstr(nlhrReply->pData, "name=\"PPFT\"")) && (pPPFT = strstr(pPPFT, "value=\"")) && (pEnd=strchr(pPPFT+7, '"'))) {
 -				*pEnd=0;
 -				pPPFT+=7;
 -
 -				/* Get POST URL if available */
 -				if ((nlhr.szUrl = strstr(nlhrReply->pData, "urlPost:'")) && (pEnd=strchr(nlhr.szUrl+9, '\''))) {
 -					*pEnd=0;
 -					nlhr.szUrl += 9;
 -				} else {
 -					url.Format("https://login.live.com/ppsecure/post.srf?%s", pszPostParams);
 -					nlhr.szUrl = (char*)(const char*)url;
 -				}
 +			CMStringA post;
 +			/* Get POST-Data and URL */
 +			if (parseLoginPage(nlhrReply->pData, &nlhr, &post)) {
  				/* Get Cookies */
  				nlhr.headers[1].szValue = (char*)alloca(CopyCookies(nlhrReply, NULL));
  				CopyCookies(nlhrReply, &nlhr.headers[1]);
  				if (*nlhr.headers[1].szValue) nlhr.headersCount++;
 -				/* Create POST data */
 -				CMStringA post;
 -				char szPassword[100];
 -				db_get_static(NULL, m_szModuleName, "Password", szPassword, sizeof(szPassword));
 -				szPassword[16] = 0;
 -				post.Format("PPFT=%s&login=%s&passwd=%s", ptrA(mir_urlEncode(pPPFT)), 
 -					ptrA(mir_urlEncode(MyOptions.szEmail)), ptrA(mir_urlEncode(szPassword)));
 -
  				/* Setup headers */
  				nlhr.headers[nlhr.headersCount].szName = "Content-Type";
  				nlhr.headers[nlhr.headersCount++].szValue = "application/x-www-form-urlencoded";
 @@ -795,126 +945,159 @@ int CMsnProto::MSN_AuthOAuth(void)  				nlhr.requestType = REQUEST_POST;
  				nlhr.flags &= (~NLHRF_REDIRECT);
  				mHttpsTS = clock();
 -				nlhr.dataLength = (int)mir_strlen(post);
 -				nlhr.pData = (char*)(const char*)post;
  				nlhr.nlc = hHttpsConnection;
  				NETLIBHTTPREQUEST *nlhrReply2 = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUserHttps, (LPARAM)&nlhr);
 -				CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
 -				nlhrReply = nlhrReply2;
  				mHttpsTS = clock();
 -				if (nlhrReply) {
 -					hHttpsConnection = nlhrReply->nlc;
 -
 -					if (nlhrReply->resultCode == 302) {
 -						char *pAccessToken;
 +				if (nlhrReply2) {
 +					char *pszURL=NULL, *pAccessToken, *pEnd;
 +					hHttpsConnection = nlhrReply2->nlc;
 +					if (nlhrReply2->resultCode == 302) {
  						/* Extract access_token from Location can be found */
 -						for (int i = 0; i < nlhrReply->headersCount; i++) {
 -							if (!mir_strcmpi(nlhrReply->headers[i].szName, "Location") &&
 -								(pAccessToken = strstr(nlhrReply->headers[i].szValue, "access_token=")) &&
 -								(pEnd = strchr(pAccessToken + 13, '&'))) {
 -								char *pRefreshToken, *pExpires, szToken[1024];
 -								bool bLogin = false;
 -
 -								*pEnd = 0;
 -								pAccessToken += 13;
 -								UrlDecode(pAccessToken);
 -								replaceStr(authAccessToken, pAccessToken);
 -
 -								/* Extract refresh token */
 -								if ((pRefreshToken = strstr(pEnd + 1, "refresh_token=")) && (pEnd = strchr(pRefreshToken + 14, '&'))) {
 -									*pEnd = 0;
 -									pRefreshToken += 14;
 -								}
 -								replaceStr(authRefreshToken, pRefreshToken);
 -
 -								/* Extract expire time */
 -								time(&authTokenExpiretime);
 -								if ((pExpires = strstr(pEnd + 1, "expires_in=")) && (pEnd = strchr(pExpires + 11, '&'))) {
 -									*pEnd = 0;
 -									pExpires += 11;
 -									authTokenExpiretime += atoi(pExpires);
 -								}
 -								else authTokenExpiretime += 86400;
 +						for (int i = 0; i < nlhrReply2->headersCount; i++) {
 +							if (!mir_strcmpi(nlhrReply2->headers[i].szName, "Location")) {
 +								pszURL = nlhrReply2->headers[i].szValue;
 +								break;
 +							}
 +						}
 +					}
 +					else {
 +						/* There may be a problem with login, i.e. M$ security measures. Open up browser
 +						 * window in order to let user login there. May also be used for 2-factor auth */
 +						if (nlhrReply2->resultCode == 200 && nlhrReply2->pData) {
 +							UINT uThreadId;
 +							IEAUTH_PARAM param = {this, &nlhr, nlhrReply2, NULL, NULL, NULL};
 +
 +							bAskingForAuth = true;
 +							WaitForSingleObject(ForkThreadEx(&CMsnProto::msn_IEAuthThread, ¶m, &uThreadId), INFINITE);
 +							pszURL = param.pszURL;
 +							mir_free(authCookies);
 +							authCookies = nlhr.headers[1].szValue = param.pszCookies;
 +							CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply2);
 +							nlhrReply2 = NULL;
 +							bAskingForAuth = false;
 +							bPassportAuth = false;
 +						}
 +					}
 +					CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
 +					nlhrReply = nlhrReply2;
 +
 +					if (pszURL &&
 +						(pAccessToken = strstr(pszURL, "access_token=")) &&
 +						(pEnd = strchr(pAccessToken + 13, '&'))) {
 +						char *pRefreshToken, *pExpires, szToken[1024];
 +						bool bLogin = false;
 +
 +						*pEnd = 0;
 +						pAccessToken += 13;
 +						UrlDecode(pAccessToken);
 +						replaceStr(authAccessToken, pAccessToken);
 +
 +						/* Extract refresh token */
 +						if ((pRefreshToken = strstr(pEnd + 1, "refresh_token=")) && (pEnd = strchr(pRefreshToken + 14, '&'))) {
 +							*pEnd = 0;
 +							pRefreshToken += 14;
 +						}
 +						replaceStr(authRefreshToken, pRefreshToken);
 +
 +						/* Extract expire time */
 +						time(&authTokenExpiretime);
 +						if ((pExpires = strstr(pEnd + 1, "expires_in=")) && (pEnd = strchr(pExpires + 11, '&'))) {
 +							*pEnd = 0;
 +							pExpires += 11;
 +							authTokenExpiretime += atoi(pExpires);
 +						}
 +						else authTokenExpiretime += 86400;
 -								/* Copy auth Cookies to class for other web requests like contact list fetching to avoid ActiveSync */
 -								mir_free(authCookies);
 -								authCookies = nlhr.headers[1].szValue = (char*)mir_alloc(CopyCookies(nlhrReply, NULL));
 -								CopyCookies(nlhrReply, &nlhr.headers[1]);
 +						/* Copy auth Cookies to class for other web requests like contact list fetching to avoid ActiveSync */
 +						if (nlhrReply) {
 +							mir_free(authCookies);
 +							authCookies = nlhr.headers[1].szValue = (char*)mir_alloc(CopyCookies(nlhrReply, NULL));
 +							CopyCookies(nlhrReply, &nlhr.headers[1]);
 +						}
 -								int loginRet;
 -								/* Do Login via Skype login server, if not possible switch to SkypeWebExperience login */
 -								if ((loginRet = LoginSkypeOAuth(pRefreshToken)) < 1) {
 -									if (loginRet < 0) bLogin = true; else retVal = 0;
 -								}
 -								else {
 -									/* SkyLogin succeeded, request required tokens */
 -									if (RefreshOAuth(pRefreshToken, "service::ssl.live.com::MBI_SSL", szToken)) {
 -										replaceStr(authSSLToken, szToken);
 +						int loginRet;
 +						/* Do Login via Skype login server, if not possible switch to SkypeWebExperience login */
 +						if ((loginRet = LoginSkypeOAuth(pRefreshToken)) < 1) {
 +							if (loginRet < 0) bLogin = true; else retVal = 0;
 +						}
 +						else {
 +							/* SkyLogin succeeded, request required tokens */
 +							if (RefreshOAuth(pRefreshToken, "service::ssl.live.com::MBI_SSL", szToken)) {
 +								replaceStr(authSSLToken, szToken);
 +								replaceStr(authUser, MyOptions.szEmail);
 +								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 */
 +						if (bLogin) {
 +							/* Prepare headers*/
 +							nlhr.headers[2].szValue = "application/json";
 +							nlhr.pData = "{\"trouterurl\":\"https://\",\"connectionid\":\"a\"}";
 +							nlhr.dataLength = (int)mir_strlen(nlhr.pData);
 +							nlhr.szUrl = "https://skypewebexperience.live.com/v1/User/Initialization";
 +							nlhr.nlc = hHttpsConnection;
 +
 +							/* Request MappingContainer */
 +							mHttpsTS = clock();
 +							if (nlhrReply) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
 +							nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUserHttps, (LPARAM)&nlhr);
 +							mHttpsTS = clock();
 +							if (nlhrReply) {
 +								hHttpsConnection = nlhrReply->nlc;
 +
 +								if (nlhrReply->resultCode == 200 && nlhrReply->pData) {
 +									/* Parse JSON stuff for MappingContainer */
 +									char *pMappingContainer;
 +
 +									if ((pMappingContainer = strstr(nlhrReply->pData, "\"MappingContainer\":\"")) &&
 +										(pEnd = strchr(pMappingContainer + 20, '"'))) {
 +										*pEnd = 0;
 +										pMappingContainer += 20;
 +										UrlDecode(pMappingContainer);
 +										replaceStr(authUIC, pMappingContainer);
  										replaceStr(authUser, MyOptions.szEmail);
 -										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 */
 -								if (bLogin) {
 -									/* Prepare headers*/
 -									nlhr.headers[2].szValue = "application/json";
 -									nlhr.pData = "{\"trouterurl\":\"https://\",\"connectionid\":\"a\"}";
 -									nlhr.dataLength = (int)mir_strlen(nlhr.pData);
 -									nlhr.szUrl = "https://skypewebexperience.live.com/v1/User/Initialization";
 -									nlhr.nlc = hHttpsConnection;
 -
 -									/* Request MappingContainer */
 -									mHttpsTS = clock();
 -									CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
 -									nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUserHttps, (LPARAM)&nlhr);
 -									mHttpsTS = clock();
 -									if (nlhrReply) {
 -										hHttpsConnection = nlhrReply->nlc;
 -
 -										if (nlhrReply->resultCode == 200 && nlhrReply->pData) {
 -											/* Parse JSON stuff for MappingContainer */
 -											char *pMappingContainer;
 -
 -											if ((pMappingContainer = strstr(nlhrReply->pData, "\"MappingContainer\":\"")) &&
 -												(pEnd = strchr(pMappingContainer + 20, '"'))) {
 -												*pEnd = 0;
 -												pMappingContainer += 20;
 -												UrlDecode(pMappingContainer);
 -												replaceStr(authUIC, pMappingContainer);
 -												replaceStr(authUser, MyOptions.szEmail);
 -												authMethod = retVal = 2;
 -											}
 -											else retVal = 0;
 -										}
 -										else retVal = 0;
 +										authMethod = retVal = 2;
  									}
 -									else hHttpsConnection = NULL;
 +									else retVal = 0;
  								}
 +								else retVal = 0;
  							}
 +							else hHttpsConnection = NULL;
  						}
  					}
 -					else {
 -						/* There may be a problem with login, i.e. M$ security measures. Open up browser
 -						 * window with same URL in order to let user correct this */
 -						if (nlhrReply->resultCode == 200 && nlhrReply->pData) {
 -							url.Format("https://login.live.com/oauth20_authorize.srf?%s", pszPostParams);
 -							MSN_ShowPopup(TranslateT("MSN Protocol"),TranslateT(MSN_LOGIN_OAUTH),MSN_ALLOW_MSGBOX,url);
 -						}
 -						hHttpsConnection = NULL;
 -					}
  				}
 +				else hHttpsConnection = NULL;
  			}
  		}
  		if (nlhrReply) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
  	} else hHttpsConnection = NULL;
  	if (retVal<=0) authTokenExpiretime=0; else {
 -		MSN_GetPassportAuth();
 +		if (bPassportAuth) {
 +			// Fast authentication with just 1 SOAP call supported :)
 +			MSN_GetPassportAuth();
 +		} else {
 +			// 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);
 +			}
 +			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);
 +			}
 +		}
  		SaveAuthTokensDB();
  	}
  	return retVal;
 diff --git a/protocols/MSN/src/msn_errors.cpp b/protocols/MSN/src/msn_errors.cpp index 64a79fb45a..2f1e321c0f 100644 --- a/protocols/MSN/src/msn_errors.cpp +++ b/protocols/MSN/src/msn_errors.cpp @@ -71,6 +71,7 @@ int CMsnProto::MSN_HandleErrors(ThreadData* info, char* cmdString)  	case ERR_SERVER_BUSY:
  	case ERR_SERVER_UNAVAILABLE:
 +	case ERR_TIMEDOUT:
  		MSN_ShowError("MSN Services are too busy, please try to connect later");
  		ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_NOSERVER);
  		return 1;
 diff --git a/protocols/MSN/src/msn_ieembed.cpp b/protocols/MSN/src/msn_ieembed.cpp new file mode 100644 index 0000000000..ef9ce64285 --- /dev/null +++ b/protocols/MSN/src/msn_ieembed.cpp @@ -0,0 +1,365 @@ +/*
 +Plugin of Miranda IM for communicating with users of the MSN Messenger protocol.
 +
 +Copyright (c) 2012-2014 Miranda NG Team
 +Copyright (c) 2007-2012 Boris Krasnovskiy.
 +
 +This program is free software; you can redistribute it and/or
 +modify it under the terms of the GNU General Public License
 +as published by the Free Software Foundation; either version 2
 +of the License, or (at your option) any later version.
 +
 +This program is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +GNU General Public License for more details.
 +
 +You should have received a copy of the GNU General Public License
 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
 +*/
 +
 +#include "stdafx.h"
 +#include <exdispid.h>
 +#include "msn_proto.h"
 +#include "msn_ieembed.h"
 +
 +IEEmbedSink::IEEmbedSink(IEEmbed *smptr)
 +{
 +	ieWindow = smptr;
 +}
 +
 +IEEmbedSink::~IEEmbedSink() {}
 +
 +STDMETHODIMP IEEmbedSink::QueryInterface(REFIID riid, PVOID *ppv)
 +{
 +	*ppv = NULL;
 +	if (IID_IUnknown == riid)
 +		*ppv = (IUnknown *)this;
 +
 +	if (IID_IDispatch == riid)
 +		*ppv = (IDispatch *)this;
 +
 +	if (DIID_DWebBrowserEvents2 == riid)
 +		*ppv = (DWebBrowserEvents2*)this;
 +
 +	if (NULL != *ppv) {
 +		((LPUNKNOWN)*ppv)->AddRef();
 +		return NOERROR;
 +	}
 +	return E_NOINTERFACE;
 +}
 +
 +STDMETHODIMP_(ULONG) IEEmbedSink::AddRef(void)
 +{
 +	++m_cRef;
 +	return m_cRef;
 +}
 +
 +STDMETHODIMP_(ULONG) IEEmbedSink::Release(void)
 +{
 +	--m_cRef;
 +	return m_cRef;
 +}
 +
 +STDMETHODIMP IEEmbedSink::GetTypeInfoCount(UINT *) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbedSink::GetTypeInfo(UINT, LCID, LPTYPEINFO*) { return S_OK; }
 +STDMETHODIMP IEEmbedSink::GetIDsOfNames(REFIID, LPOLESTR*, UINT, LCID, DISPID*) { return S_OK; }
 +
 +STDMETHODIMP IEEmbedSink::Invoke(DISPID dispIdMember, REFIID, LCID, WORD, DISPPARAMS* pDispParams, VARIANT*, EXCEPINFO*, UINT*)
 +{
 +	if (!pDispParams) return E_INVALIDARG;
 +	switch (dispIdMember) {
 +	case DISPID_DOCUMENTCOMPLETE:
 +		DocumentComplete(
 +			pDispParams->rgvarg[1].pdispVal,
 +			pDispParams->rgvarg[0].pvarVal);
 +		return S_OK;
 +	}
 +
 +	return DISP_E_MEMBERNOTFOUND;
 +}
 +// DWebBrowserEvents2
 +
 +void IEEmbedSink::StatusTextChange(BSTR) {}
 +void IEEmbedSink::ProgressChange(long, long) {}
 +void IEEmbedSink::CommandStateChange(long, VARIANT_BOOL) {}
 +void IEEmbedSink::DownloadBegin() {}
 +void IEEmbedSink::DownloadComplete() {}
 +void IEEmbedSink::TitleChange(BSTR) {}
 +void IEEmbedSink::PropertyChange(BSTR) {}
 +void IEEmbedSink::BeforeNavigate2(IDispatch*, VARIANT* , VARIANT*, VARIANT*, VARIANT*, VARIANT*, VARIANT_BOOL*) { }
 +void IEEmbedSink::NewWindow2(IDispatch**, VARIANT_BOOL*) {}
 +void IEEmbedSink::NavigateComplete(IDispatch*, VARIANT*) {}
 +void IEEmbedSink::DocumentComplete(IDispatch* , VARIANT* url) 
 +{
 +	HWND hWnd;
 +	ieWindow->GetWindow(&hWnd);
 +	SendMessage(hWnd, UM_DOCCOMPLETE, 0, (LPARAM)url->bstrVal);
 +}
 +void IEEmbedSink::OnQuit() {}
 +void IEEmbedSink::OnVisible(VARIANT_BOOL) {}
 +void IEEmbedSink::OnToolBar(VARIANT_BOOL) {}
 +void IEEmbedSink::OnMenuBar(VARIANT_BOOL) {}
 +void IEEmbedSink::OnStatusBar(VARIANT_BOOL) {}
 +void IEEmbedSink::OnFullScreen(VARIANT_BOOL) {}
 +void IEEmbedSink::OnTheaterMode(VARIANT_BOOL) {}
 +void IEEmbedSink::WindowSetResizable(VARIANT_BOOL) {}
 +void IEEmbedSink::WindowSetLeft(long) {}
 +void IEEmbedSink::WindowSetTop(long) {}
 +void IEEmbedSink::WindowSetWidth(long) {}
 +void IEEmbedSink::WindowSetHeight(long) {}
 +void IEEmbedSink::WindowClosing(VARIANT_BOOL, VARIANT_BOOL*) {}
 +void IEEmbedSink::ClientToHostWindow(long *, long *) {}
 +void IEEmbedSink::SetSecureLockIcon(long) {}
 +void IEEmbedSink::FileDownload(VARIANT_BOOL*) {}
 +
 +
 +IEEmbed::IEEmbed(HWND _parent)
 +{
 +	MSG msg;
 +	parent = _parent;
 +	GetClientRect(_parent, &rcClient);
 +	if (SUCCEEDED(pWebBrowser.CoCreateInstance(CLSID_WebBrowser, NULL, CLSCTX_INPROC))) {
 +		CComPtr<IOleObject> pOleObject;
 +		if (SUCCEEDED(pWebBrowser.QueryInterface(&pOleObject))) {
 +			pOleObject->SetClientSite(this);
 +			pOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, &msg, this, 0, this->parent, &rcClient);
 +		}
 +		else MessageBox(NULL, TranslateT("IID_IOleObject failed."), TranslateT("RESULT"), MB_OK);
 +
 +		CComPtr<IOleInPlaceObject> pOleInPlace;
 +		if (SUCCEEDED(pWebBrowser.QueryInterface(&pOleInPlace)))
 +			pOleInPlace->GetWindow(&hwnd);
 +		else
 +			MessageBox(NULL, TranslateT("IID_IOleInPlaceObject failed."), TranslateT("RESULT"), MB_OK);
 +
 +		//setBorder();
 +		CComPtr<IConnectionPointContainer> pCPContainer;
 +		// Step 1: Get a pointer to the connection point container.
 +		if (SUCCEEDED(pWebBrowser.QueryInterface(&pCPContainer))) {
 +			// m_pConnectionPoint is defined like this:
 +			// Step 2: Find the connection point.
 +			if (SUCCEEDED(pCPContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &m_pConnectionPoint))) {
 +				// Step 3: Advise the connection point that you
 +				// want to sink its events.
 +				sink = new IEEmbedSink(this);
 +				if (FAILED(m_pConnectionPoint->Advise(sink, &m_dwCookie)))
 +					MessageBox(NULL, TranslateT("Failed to Advise"), TranslateT("C++ Event Sink"), MB_OK);
 +			}
 +		}
 +	}
 +
 +	pWebBrowser->put_RegisterAsDropTarget(VARIANT_FALSE);
 +}
 +
 +IEEmbed::~IEEmbed()
 +{
 +	CComPtr<IOleObject> pOleObject;
 +	if (SUCCEEDED(pWebBrowser.QueryInterface(&pOleObject)))
 +		pOleObject->SetClientSite(NULL);
 +	else
 +		MessageBox(NULL, TranslateT("IID_IOleObject failed."), TranslateT("RESULT"), MB_OK);
 +
 +	if (m_pConnectionPoint != NULL)
 +		m_pConnectionPoint->Unadvise(m_dwCookie);
 +
 +	if (sink != NULL)
 +		delete sink;
 +	DestroyWindow(hwnd);
 +}
 +
 +void IEEmbed::ResizeBrowser()
 +{
 +	CComPtr<IOleInPlaceObject> pOleInPlace;
 +
 +	GetClientRect(parent, &rcClient);
 +	if (SUCCEEDED(pWebBrowser.QueryInterface(&pOleInPlace)))
 +		pOleInPlace->SetObjectRects(&rcClient, &rcClient);
 +}
 +
 +
 +// IUnknown
 +STDMETHODIMP IEEmbed::QueryInterface(REFIID riid, PVOID *ppv)
 +{
 +	*ppv = NULL;
 +	if (IID_IUnknown == riid)
 +		*ppv = this;
 +	if (IID_IOleClientSite == riid)
 +		*ppv = (IOleClientSite*)this;//Unknown)m_pIOleClientSite;
 +	if (IID_IOleWindow == riid || IID_IOleInPlaceSite == riid)
 +		*ppv = (IOleInPlaceSite*)this;//m_pIOleIPSite;
 +
 +	if (NULL != *ppv) {
 +		((LPUNKNOWN)*ppv)->AddRef();
 +		return NOERROR;
 +	}
 +	return E_NOINTERFACE;
 +}
 +
 +STDMETHODIMP_(ULONG) IEEmbed::AddRef(void)
 +{
 +	++m_cRef;
 +	return m_cRef;
 +}
 +
 +STDMETHODIMP_(ULONG) IEEmbed::Release(void)
 +{
 +	--m_cRef;
 +	return m_cRef;
 +}
 +
 +// IDispatch
 +STDMETHODIMP IEEmbed::GetTypeInfoCount(UINT *) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::GetTypeInfo(UINT, LCID, LPTYPEINFO*) { return S_OK; }
 +STDMETHODIMP IEEmbed::GetIDsOfNames(REFIID, LPOLESTR*, UINT, LCID, DISPID*) { return S_OK; }
 +STDMETHODIMP IEEmbed::Invoke(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*) { return DISP_E_MEMBERNOTFOUND; }
 +
 +// IOleWindow
 +STDMETHODIMP IEEmbed::GetWindow(HWND *phwnd)
 +{
 +	*phwnd = parent;
 +	return S_OK;
 +}
 +
 +STDMETHODIMP IEEmbed::ContextSensitiveHelp(BOOL) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::CanInPlaceActivate(void) { return S_OK; }
 +STDMETHODIMP IEEmbed::OnInPlaceActivate(void) {	return S_OK; }
 +STDMETHODIMP IEEmbed::OnUIActivate(void) { return E_NOTIMPL; }
 +
 +STDMETHODIMP IEEmbed::GetWindowContext(IOleInPlaceFrame **, IOleInPlaceUIWindow **, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO)
 +{
 +	lprcPosRect->left = rcClient.left;
 +	lprcPosRect->top = rcClient.top;
 +	lprcPosRect->right = rcClient.right;
 +	lprcPosRect->bottom = rcClient.bottom;
 +	lprcClipRect->left = rcClient.left;
 +	lprcClipRect->top = rcClient.top;
 +	lprcClipRect->right = rcClient.right;
 +	lprcClipRect->bottom = rcClient.bottom;
 +	return S_OK;
 +}
 +
 +STDMETHODIMP IEEmbed::Scroll(SIZE) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::OnUIDeactivate(BOOL) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::OnInPlaceDeactivate(void) { return S_OK; }
 +STDMETHODIMP IEEmbed::DiscardUndoState(void) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::DeactivateAndUndo(void) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::OnPosRectChange(LPCRECT) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::SaveObject(void) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::GetMoniker(DWORD, DWORD, IMoniker **) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::GetContainer(IOleContainer **) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::ShowObject(void) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::OnShowWindow(BOOL) { return E_NOTIMPL; }
 +STDMETHODIMP IEEmbed::RequestNewObjectLayout(void) { return E_NOTIMPL; }
 +
 +
 +void IEEmbed::write(const wchar_t *text)
 +{
 +	CComPtr<IHTMLDocument2> document = getDocument();
 +	if (!document) return;
 +
 +	SAFEARRAY *safe_array = ::SafeArrayCreateVector(VT_VARIANT, 0, 1);
 +	if (safe_array != NULL) {
 +		VARIANT *variant;
 +		::SafeArrayAccessData(safe_array, (LPVOID *)&variant);
 +		variant->vt = VT_BSTR;
 +		variant->bstrVal = ::SysAllocString(text);
 +		::SafeArrayUnaccessData(safe_array);
 +		document->write(safe_array);
 +		// ::SysFreeString(bstr); // don't free it !!!!!!!
 +		::SafeArrayDestroy(safe_array);
 +		document->close();
 +	}
 +}
 +
 +void IEEmbed::addCookie(const wchar_t *cookieString)
 +{
 +	CComPtr<IHTMLDocument2> document = getDocument();
 +	if (!document) return;
 +	BSTR cookie = SysAllocString(cookieString);
 +
 +	document->put_cookie(cookie);
 +
 +	SysFreeString(cookie);
 +}
 +
 +BSTR IEEmbed::getCookies()
 +{
 +	CComPtr<IHTMLDocument2> document = getDocument();
 +	BSTR cookie = NULL;
 +
 +	if (!document) return NULL;
 +	document->get_cookie(&cookie);
 +	return cookie;
 +}
 +
 +IHTMLDocument2* IEEmbed::getDocument()
 +{
 +	CComPtr<IDispatch> dispatch;
 +	if (SUCCEEDED(pWebBrowser->get_Document(&dispatch)) && dispatch != NULL) {
 +		CComPtr<IHTMLDocument2> document;
 +		dispatch.QueryInterface(&document);
 +		return document.Detach();
 +	}
 +
 +	return NULL;
 +}
 +
 +void IEEmbed::navigate(const wchar_t *url)
 +{
 +	pWebBrowser->Navigate((WCHAR *)url, NULL, NULL, NULL, NULL);
 +}
 +
 +void IEEmbed::navigate(char *url)
 +{
 +	wchar_t *pwszUrl = mir_a2u(url);
 +	navigate(pwszUrl);
 +	mir_free(pwszUrl);
 +}
 +
 +void IEEmbed::navigate(NETLIBHTTPREQUEST *nlhr)
 +{
 +	WCHAR *szUrl = mir_a2u(nlhr->szUrl);
 +	BSTR bstrHeaders;
 +    LPSAFEARRAY psa;
 +	LPSTR pPostData;
 +    VARIANT vPostData = {0}, vHeaders = {0};
 +
 +	bstrHeaders = SysAllocString(L"Content-Type: application/x-www-form-urlencoded\r\n");
 +    V_VT(&vHeaders) = VT_BSTR;
 +    V_BSTR(&vHeaders) = bstrHeaders;
 +    VariantInit(&vPostData);
 +    psa = SafeArrayCreateVector(VT_UI1, 0, nlhr->dataLength);
 +    SafeArrayAccessData(psa, (LPVOID*)&pPostData);
 +	memcpy(pPostData, nlhr->pData, nlhr->dataLength);
 +    SafeArrayUnaccessData(psa);
 +    V_VT(&vPostData) = VT_ARRAY | VT_UI1;
 +    V_ARRAY(&vPostData) = psa;
 +	pWebBrowser->Navigate(szUrl, NULL, NULL, &vPostData, &vHeaders);
 +	SysFreeString(bstrHeaders);
 +	VariantClear(&vPostData);
 +	mir_free(szUrl);
 +}
 +
 +char *IEEmbed::GetHTMLDoc() {
 +	CComPtr<IDispatch> spDispDoc;
 +	char *pszRet = NULL;
 +
 +	if (SUCCEEDED(pWebBrowser->get_Document(&spDispDoc))) {
 +		CComPtr<IHTMLDocument3> spDoc;
 +
 +        if (SUCCEEDED(spDispDoc->QueryInterface(IID_IHTMLDocument3, (void**)&spDoc))) {
 +			CComPtr<IHTMLElement> spRootElement;
 +			if (SUCCEEDED(spDoc->get_documentElement(&spRootElement)))
 +			{
 +				BSTR bstrDoc;
 +				if (SUCCEEDED(spRootElement->get_outerHTML(&bstrDoc)))
 +				{
 +					pszRet = mir_u2a(bstrDoc);
 +					SysFreeString(bstrDoc);
 +				}
 +			}
 +		}
 +	}
 +	return pszRet;
 +}
 diff --git a/protocols/MSN/src/msn_ieembed.h b/protocols/MSN/src/msn_ieembed.h new file mode 100644 index 0000000000..76442b691d --- /dev/null +++ b/protocols/MSN/src/msn_ieembed.h @@ -0,0 +1,140 @@ +/*
 +Plugin of Miranda IM for communicating with users of the MSN Messenger protocol.
 +
 +Copyright (c) 2012-2014 Miranda NG Team
 +Copyright (c) 2007-2012 Boris Krasnovskiy.
 +
 +This program is free software; you can redistribute it and/or
 +modify it under the terms of the GNU General Public License
 +as published by the Free Software Foundation; either version 2
 +of the License, or (at your option) any later version.
 +
 +This program is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +GNU General Public License for more details.
 +
 +You should have received a copy of the GNU General Public License
 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
 +*/
 +
 +class IEEmbed;
 +
 +#include <mshtmhst.h>
 +#include <mshtml.h>
 +#include <exdisp.h>
 +
 +#include <atlbase.h>	// CComPtr
 +
 +#ifndef IEEMBED_INCLUDED
 +#define IEEMBED_INCLUDED
 +
 +#define UM_DOCCOMPLETE (WM_USER+600)
 +
 +class IEEmbedSink :public  DWebBrowserEvents2 {
 +private:
 +	int		m_cRef;
 +	IEEmbed *ieWindow;
 +public:
 +	IEEmbedSink(IEEmbed *);
 +	virtual ~IEEmbedSink();
 +	// IDispatch
 +	STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv);
 +	STDMETHODIMP_(ULONG) AddRef(void);
 +	STDMETHODIMP_(ULONG) Release(void);
 +
 +	STDMETHOD(GetTypeInfoCount)(UINT*);
 +	STDMETHOD(GetTypeInfo)(UINT, LCID, LPTYPEINFO*);
 +	STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR*, UINT, LCID, DISPID*);
 +	STDMETHOD(Invoke)(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);
 +	// DWebBrowserEvents2
 +	STDMETHODIMP_(void)StatusTextChange(BSTR);
 +	STDMETHODIMP_(void)ProgressChange(long, long);
 +	STDMETHODIMP_(void)CommandStateChange(long, VARIANT_BOOL);
 +	STDMETHODIMP_(void)DownloadBegin();
 +	STDMETHODIMP_(void)DownloadComplete();
 +	STDMETHODIMP_(void)TitleChange(BSTR Text);
 +	STDMETHODIMP_(void)PropertyChange(BSTR Text);
 +	STDMETHODIMP_(void)BeforeNavigate2(IDispatch*, VARIANT*, VARIANT*, VARIANT*, VARIANT*, VARIANT*, VARIANT_BOOL*);
 +	STDMETHODIMP_(void)NewWindow2(IDispatch**, VARIANT_BOOL*);
 +	STDMETHODIMP_(void)NavigateComplete(IDispatch*, VARIANT*);
 +	STDMETHODIMP_(void)DocumentComplete(IDispatch*, VARIANT*);
 +	STDMETHODIMP_(void)OnQuit();
 +	STDMETHODIMP_(void)OnVisible(VARIANT_BOOL);
 +	STDMETHODIMP_(void)OnToolBar(VARIANT_BOOL);
 +	STDMETHODIMP_(void)OnMenuBar(VARIANT_BOOL);
 +	STDMETHODIMP_(void)OnStatusBar(VARIANT_BOOL);
 +	STDMETHODIMP_(void)OnFullScreen(VARIANT_BOOL);
 +	STDMETHODIMP_(void)OnTheaterMode(VARIANT_BOOL);
 +	STDMETHODIMP_(void)WindowSetResizable(VARIANT_BOOL);
 +	STDMETHODIMP_(void)WindowSetLeft(long);
 +	STDMETHODIMP_(void)WindowSetTop(long);
 +	STDMETHODIMP_(void)WindowSetWidth(long);
 +	STDMETHODIMP_(void)WindowSetHeight(long);
 +	STDMETHODIMP_(void)WindowClosing(VARIANT_BOOL, VARIANT_BOOL*);
 +	STDMETHODIMP_(void)ClientToHostWindow(long*, long*);
 +	STDMETHODIMP_(void)SetSecureLockIcon(long);
 +	STDMETHODIMP_(void)FileDownload(VARIANT_BOOL*);
 +};
 +
 +class IEEmbed :public IDispatch, public IOleClientSite, public IOleInPlaceSite //, public IDocHostUIHandler
 +{
 +public:
 +	HWND parent;
 +	HWND hwnd;
 +	int m_cRef;
 +	RECT rcClient;
 +	DWORD m_dwCookie;
 +	CComPtr<IConnectionPoint> m_pConnectionPoint;
 +	CComPtr<IWebBrowser2> pWebBrowser;
 +	IEEmbedSink *sink;
 +
 +	// IUnknown
 +	STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv);
 +	STDMETHODIMP_(ULONG) AddRef(void);
 +	STDMETHODIMP_(ULONG) Release(void);
 +
 +	// IDispatch
 +	STDMETHOD(GetTypeInfoCount)(UINT*);
 +	STDMETHOD(GetTypeInfo)(UINT, LCID, LPTYPEINFO*);
 +	STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR*, UINT, LCID, DISPID*);
 +	STDMETHOD(Invoke)(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);
 +	// IOleWindow
 +	STDMETHOD(GetWindow)(HWND *phwnd);
 +	STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode);
 +	// IOleInPlace
 +	STDMETHOD(CanInPlaceActivate)(void);
 +	STDMETHOD(OnInPlaceActivate)(void);
 +	STDMETHOD(OnUIActivate)(void);
 +	STDMETHOD(GetWindowContext)(IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc,
 +		LPRECT lprcPosRect, LPRECT lprcClipRect,
 +		LPOLEINPLACEFRAMEINFO lpFrameInfo);
 +	STDMETHOD(Scroll)(SIZE scrollExtant);
 +
 +	STDMETHOD(OnUIDeactivate)(BOOL fUndoable);
 +	STDMETHOD(OnInPlaceDeactivate)(void);
 +	STDMETHOD(DiscardUndoState)(void);
 +	STDMETHOD(DeactivateAndUndo)(void);
 +	STDMETHOD(OnPosRectChange)(LPCRECT lprcPosRect);
 +	// IOleClientSite
 +	STDMETHOD(SaveObject)(void);
 +	STDMETHOD(GetMoniker)(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk);
 +	STDMETHOD(GetContainer)(IOleContainer **ppContainer);
 +	STDMETHOD(ShowObject)(void);
 +	STDMETHOD(OnShowWindow)(BOOL fShow);
 +	STDMETHOD(RequestNewObjectLayout)(void);
 +
 +	IHTMLDocument2 *getDocument();
 +	IEEmbed(HWND _parent);
 +	virtual ~IEEmbed();
 +
 +	void	ResizeBrowser();
 +	void    navigate(const wchar_t *);
 +	void	navigate(char *url);
 +	void	navigate(NETLIBHTTPREQUEST *nlhr);
 +	void    write(const wchar_t *text);
 +	void    addCookie(const wchar_t *cookieString);
 +	BSTR    getCookies();
 +	char*	GetHTMLDoc();
 +};
 +#endif
 diff --git a/protocols/MSN/src/msn_proto.h b/protocols/MSN/src/msn_proto.h index 952c32db05..f5a4fa8358 100644 --- a/protocols/MSN/src/msn_proto.h +++ b/protocols/MSN/src/msn_proto.h @@ -118,6 +118,7 @@ struct CMsnProto : public PROTO<CMsnProto>  	char *authStorageToken;
  	char *hotSecretToken, *hotAuthToken;
  	char *authUser, *authUIC, *authCookies, *authSSLToken, *authAccessToken, *authRefreshToken, *authSkypeComToken, *authSkypeToken;
 +	bool bAskingForAuth;
  	int  authMethod;
  	time_t authTokenExpiretime;
  	bool bSentBND;
 @@ -275,6 +276,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 MSNServerThread(void* arg);
  	void __cdecl MsnFileAckThread(void* arg);
 @@ -492,6 +494,7 @@ struct CMsnProto : public PROTO<CMsnProto>  	char*     GenerateLoginBlob(char* challenge);
  	void      LoadAuthTokensDB(void);
  	void      SaveAuthTokensDB(void);
 +	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);
  	int       MSN_AuthOAuth(void);
 diff --git a/protocols/MSN/src/stdafx.h b/protocols/MSN/src/stdafx.h index eedae789e9..1f34366308 100644 --- a/protocols/MSN/src/stdafx.h +++ b/protocols/MSN/src/stdafx.h @@ -193,12 +193,6 @@ const char MSN_USER_AGENT[] =           NETLIB_USER_AGENT;  extern const char sttVoidUid[];
 -#define MSN_LOGIN_OAUTH LPGEN("Automatic authentication to MSN failed, possibly due to Captcha-Authentication. \
 -Do you want to open a browser window to do a manual login?\n\n\
 -This will not log you in to MSN in Miranda, but it allows you to fix potential problems like entering a captcha \
 -that gets asked due to location change or to accept new TOS, which are required only once.\n\n\
 -Also please note that MSN protocol doesn't support two-factor authentication.")
 -
  /////////////////////////////////////////////////////////////////////////////////////////
  //	MSN plugin functions
 | 
