diff options
Diffstat (limited to 'miranda-wine/protocols/MSN/msn_ssl.cpp')
-rw-r--r-- | miranda-wine/protocols/MSN/msn_ssl.cpp | 667 |
1 files changed, 667 insertions, 0 deletions
diff --git a/miranda-wine/protocols/MSN/msn_ssl.cpp b/miranda-wine/protocols/MSN/msn_ssl.cpp new file mode 100644 index 0000000..7ad28ed --- /dev/null +++ b/miranda-wine/protocols/MSN/msn_ssl.cpp @@ -0,0 +1,667 @@ +/*
+Plugin of Miranda IM for communicating with users of the MSN Messenger protocol.
+Copyright (c) 2003-5 George Hazan.
+Copyright (c) 2002-3 Richard Hughes (original version).
+
+Miranda IM: the free icq client for MS Windows
+Copyright (C) 2000-2002 Richard Hughes, Roland Rabien & Tristan Van de Vreede
+
+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, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "msn_global.h"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Basic SSL operation class
+
+struct SSL_Base
+{
+ char* m_szEmail;
+
+ virtual ~SSL_Base() {}
+
+ virtual int init() = 0;
+ virtual char* getSslResult( char* parUrl, char* parAuthInfo ) = 0;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// WinInet class
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#define ERROR_FLAGS (FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS )
+
+#include "wininet.h"
+
+#define SSL_BUF_SIZE 8192
+
+typedef BOOL ( WINAPI *ft_HttpQueryInfo )( HINTERNET, DWORD, LPVOID, LPDWORD, LPDWORD );
+typedef BOOL ( WINAPI *ft_HttpSendRequest )( HINTERNET, LPCSTR, DWORD, LPVOID, DWORD );
+typedef BOOL ( WINAPI *ft_InternetCloseHandle )( HINTERNET );
+typedef DWORD ( WINAPI *ft_InternetErrorDlg )( HWND, HINTERNET, DWORD, DWORD, LPVOID* );
+typedef BOOL ( WINAPI *ft_InternetSetOption )( HINTERNET, DWORD, LPVOID, DWORD );
+typedef BOOL ( WINAPI *ft_InternetReadFile )( HINTERNET, LPVOID, DWORD, LPDWORD );
+typedef BOOL ( WINAPI *ft_HttpAddRequestHeaders )( HINTERNET, LPCSTR, DWORD, DWORD );
+
+typedef HINTERNET ( WINAPI *ft_HttpOpenRequest )( HINTERNET, LPCSTR, LPCSTR, LPCSTR, LPCSTR, LPCSTR*, DWORD, DWORD );
+typedef HINTERNET ( WINAPI *ft_InternetConnect )( HINTERNET, LPCSTR, INTERNET_PORT, LPCSTR, LPCSTR, DWORD, DWORD, DWORD );
+typedef HINTERNET ( WINAPI *ft_InternetOpen )( LPCSTR, DWORD, LPCSTR, LPCSTR, DWORD );
+
+struct SSL_WinInet : public SSL_Base
+{
+ virtual ~SSL_WinInet();
+
+ virtual char* getSslResult( char* parUrl, char* parAuthInfo );
+ virtual int init();
+
+ void applyProxy( HINTERNET );
+ void readInput( HINTERNET );
+
+ //-----------------------------------------------------------------------------------
+ HMODULE m_dll;
+
+ ft_InternetCloseHandle f_InternetCloseHandle;
+ ft_InternetConnect f_InternetConnect;
+ ft_InternetErrorDlg f_InternetErrorDlg;
+ ft_InternetOpen f_InternetOpen;
+ ft_InternetReadFile f_InternetReadFile;
+ ft_InternetSetOption f_InternetSetOption;
+ ft_HttpOpenRequest f_HttpOpenRequest;
+ ft_HttpQueryInfo f_HttpQueryInfo;
+ ft_HttpSendRequest f_HttpSendRequest;
+ ft_HttpAddRequestHeaders f_HttpAddRequestHeaders;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int SSL_WinInet::init()
+{
+ if (( m_dll = LoadLibraryA( "WinInet.dll" )) == NULL )
+ return 10;
+
+ f_InternetCloseHandle = (ft_InternetCloseHandle)GetProcAddress( m_dll, "InternetCloseHandle" );
+ f_InternetConnect = (ft_InternetConnect)GetProcAddress( m_dll, "InternetConnectA" );
+ f_InternetErrorDlg = (ft_InternetErrorDlg)GetProcAddress( m_dll, "InternetErrorDlg" );
+ f_InternetOpen = (ft_InternetOpen)GetProcAddress( m_dll, "InternetOpenA" );
+ f_InternetReadFile = (ft_InternetReadFile)GetProcAddress( m_dll, "InternetReadFile" );
+ f_InternetSetOption = (ft_InternetSetOption)GetProcAddress( m_dll, "InternetSetOptionA" );
+ f_HttpOpenRequest = (ft_HttpOpenRequest)GetProcAddress( m_dll, "HttpOpenRequestA" );
+ f_HttpQueryInfo = (ft_HttpQueryInfo)GetProcAddress( m_dll, "HttpQueryInfoA" );
+ f_HttpSendRequest = (ft_HttpSendRequest)GetProcAddress( m_dll, "HttpSendRequestA" );
+ f_HttpAddRequestHeaders = (ft_HttpAddRequestHeaders)GetProcAddress( m_dll, "HttpAddRequestHeadersA" );
+ return 0;
+}
+
+SSL_WinInet::~SSL_WinInet()
+{
+ #if defined( _UNICODE )
+ FreeLibrary( m_dll ); // we free WININET.DLL only if we're under NT
+ #endif
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void SSL_WinInet::applyProxy( HINTERNET parHandle )
+{
+ char tBuffer[ 100 ];
+
+ MSN_DebugLog( "Applying proxy parameters..." );
+
+ if ( !MSN_GetStaticString( "NLProxyAuthUser", NULL, tBuffer, SSL_BUF_SIZE ))
+ f_InternetSetOption( parHandle, INTERNET_OPTION_PROXY_USERNAME, tBuffer, strlen( tBuffer )+1);
+ else
+ MSN_DebugLog( "Warning: proxy user name is required but missing" );
+
+ if ( !MSN_GetStaticString( "NLProxyAuthPassword", NULL, tBuffer, SSL_BUF_SIZE )) {
+ MSN_CallService( MS_DB_CRYPT_DECODESTRING, strlen( tBuffer ), ( LPARAM )tBuffer );
+ f_InternetSetOption( parHandle, INTERNET_OPTION_PROXY_PASSWORD, tBuffer, strlen( tBuffer )+1);
+ }
+ else MSN_DebugLog( "Warning: proxy user password is required but missing" );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void SSL_WinInet::readInput( HINTERNET hRequest )
+{
+ DWORD dwSize;
+
+ do {
+ char tmpbuf[100];
+ f_InternetReadFile( hRequest, tmpbuf, 50, &dwSize);
+ }
+ while (dwSize != 0);
+}
+
+char* SSL_WinInet::getSslResult( char* parUrl, char* parAuthInfo )
+{
+ DWORD tFlags =
+ INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS |
+ INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
+ INTERNET_FLAG_IGNORE_CERT_CN_INVALID |
+ INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
+ INTERNET_FLAG_KEEP_CONNECTION |
+ INTERNET_FLAG_NO_AUTO_REDIRECT |
+ INTERNET_FLAG_NO_CACHE_WRITE |
+ INTERNET_FLAG_NO_COOKIES |
+ INTERNET_FLAG_RELOAD |
+ INTERNET_FLAG_SECURE;
+
+ HINTERNET tNetHandle;
+ char* tBuffer = ( char* )alloca( SSL_BUF_SIZE );
+
+ int tUsesProxy = MSN_GetByte( "NLUseProxy", 0 );
+ if ( tUsesProxy ) {
+ DWORD ptype = MSN_GetByte( "NLProxyType", 0 );
+ if ( !MSN_GetByte( "UseIeProxy", 0 ) && ( ptype == PROXYTYPE_HTTP || ptype == PROXYTYPE_HTTPS )) {
+ char szProxy[ 100 ];
+ if ( MSN_GetStaticString( "NLProxyServer", NULL, szProxy, sizeof szProxy )) {
+ MSN_DebugLog( "Proxy server name should be set if proxy is used" );
+ return NULL;
+ }
+
+ int tPortNumber = MSN_GetWord( NULL, "NLProxyPort", -1 );
+ if ( tPortNumber == -1 ) {
+ MSN_DebugLog( "Proxy server port should be set if proxy is used" );
+ return NULL;
+ }
+
+ mir_snprintf( tBuffer, SSL_BUF_SIZE, "https=http://%s:%d http=http://%s:%d",
+ szProxy, tPortNumber, szProxy, tPortNumber );
+
+ tNetHandle = f_InternetOpen( "MSMSGS", INTERNET_OPEN_TYPE_PROXY, tBuffer, NULL, 0 );
+ }
+ else tNetHandle = f_InternetOpen( "MSMSGS", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
+ }
+ else tNetHandle = f_InternetOpen( "MSMSGS", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+
+ if ( tNetHandle == NULL ) {
+ MSN_DebugLog( "InternetOpen() failed" );
+ return NULL;
+ }
+
+ MSN_DebugLog( "SSL request (%s): '%s'", ( tUsesProxy ) ? "using proxy": "direct connection", parUrl );
+
+ char* urlStart = strstr( parUrl, "://" );
+ if ( urlStart == NULL )
+ urlStart = parUrl;
+ else
+ urlStart += 3;
+
+ { int tLen = strlen( urlStart )+1;
+ parUrl = ( char* )alloca( tLen );
+ memcpy( parUrl, urlStart, tLen );
+ }
+
+ char* tObjectName = ( char* )strchr( parUrl, '/' );
+ if ( tObjectName != NULL ) {
+ int tLen = strlen( tObjectName )+1;
+ char* newBuf = ( char* )alloca( tLen );
+ memcpy( newBuf, tObjectName, tLen );
+
+ *tObjectName = 0;
+ tObjectName = newBuf;
+ }
+ else tObjectName = "/";
+
+ char* tSslAnswer = NULL;
+
+ HINTERNET tUrlHandle = f_InternetConnect( tNetHandle, parUrl, INTERNET_DEFAULT_HTTPS_PORT, "", "", INTERNET_SERVICE_HTTP, 0, 0 );
+ if ( tUrlHandle != NULL )
+ {
+ HINTERNET tRequest = f_HttpOpenRequest( tUrlHandle, "GET", tObjectName,
+ parAuthInfo ? NULL: HTTP_VERSIONA, NULL, NULL, tFlags, NULL );
+ if ( tRequest != NULL ) {
+ DWORD tBufSize;
+
+ unsigned tm = 3000;
+ f_InternetSetOption( tRequest, INTERNET_OPTION_CONNECT_TIMEOUT, &tm, sizeof(tm));
+ f_InternetSetOption( tRequest, INTERNET_OPTION_SEND_TIMEOUT, &tm, sizeof(tm));
+ f_InternetSetOption( tRequest, INTERNET_OPTION_RECEIVE_TIMEOUT, &tm, sizeof(tm));
+
+ if ( tUsesProxy && MSN_GetByte( "NLUseProxyAuth", 0 ))
+ applyProxy( tRequest );
+
+ char cclose[] = "Connection: close";
+ f_HttpAddRequestHeaders(tRequest, cclose, strlen(cclose), HTTP_ADDREQ_FLAG_ADD );
+LBL_Restart:
+ MSN_DebugLog( "Sending request..." );
+ DWORD tErrorCode = f_HttpSendRequest( tRequest, parAuthInfo, DWORD(-1), NULL, 0 );
+ if ( tErrorCode == 0 ) {
+ TWinErrorCode errCode;
+ MSN_DebugLog( "HttpSendRequest() failed with error %ld", errCode.mErrorCode );
+
+ if ( errCode.mErrorCode == 2 )
+ MSN_ShowError( "Internet Explorer is in the 'Offline' mode. Switch IE to the 'Online' mode and then try to relogin" );
+ else
+ MSN_ShowError( "MSN Passport verification failed with error %d: %s",
+ errCode.mErrorCode, errCode.getText());
+ }
+ else {
+ DWORD dwCode;
+ tBufSize = sizeof( dwCode );
+ f_HttpQueryInfo( tRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &tBufSize, 0 );
+
+ switch( dwCode ) {
+ case HTTP_STATUS_REDIRECT:
+ tBufSize = SSL_BUF_SIZE;
+ f_HttpQueryInfo( tRequest, HTTP_QUERY_LOCATION, tBuffer, &tBufSize, NULL );
+ MSN_DebugLog( "Redirected to '%s'", tBuffer );
+ tSslAnswer = getSslResult( tBuffer, parAuthInfo );
+ break;
+
+ case HTTP_STATUS_OK:
+ LBL_PrintHeaders:
+ tBufSize = SSL_BUF_SIZE;
+ f_HttpQueryInfo( tRequest, HTTP_QUERY_RAW_HEADERS_CRLF, tBuffer, &tBufSize, NULL );
+ MSN_DebugLog( "SSL response: '%s'", tBuffer );
+ tSslAnswer = dwCode == HTTP_STATUS_OK ? strdup( tBuffer ) : NULL;
+ break;
+
+ case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
+ case ERROR_INTERNET_INCORRECT_PASSWORD:
+ case ERROR_INTERNET_INVALID_CA:
+ case ERROR_INTERNET_POST_IS_NON_SECURE:
+ case ERROR_INTERNET_SEC_CERT_CN_INVALID:
+ case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
+ case ERROR_INTERNET_SEC_CERT_ERRORS:
+ case ERROR_INTERNET_SEC_CERT_NO_REV:
+ case ERROR_INTERNET_SEC_CERT_REV_FAILED:
+ MSN_DebugLog( "HttpSendRequest returned error code %d", tErrorCode );
+ if ( ERROR_INTERNET_FORCE_RETRY == f_InternetErrorDlg( GetDesktopWindow(), tRequest, tErrorCode, ERROR_FLAGS, NULL )) {
+ readInput( tRequest );
+ goto LBL_Restart;
+ }
+
+ // else fall into the general error handling routine
+
+ default:
+ tBufSize = SSL_BUF_SIZE;
+ if ( !f_HttpQueryInfo( tRequest, HTTP_QUERY_STATUS_TEXT, tBuffer, &tBufSize, NULL ))
+ strcpy( tBuffer, "unknown error" );
+
+ MSN_ShowError( "Internet secure connection (SSL) failed with error %d: %s", dwCode, tBuffer );
+ MSN_DebugLog( "SSL error %d: '%s'", dwCode, tBuffer );
+ goto LBL_PrintHeaders;
+ } }
+
+ f_InternetCloseHandle( tRequest );
+ }
+
+ f_InternetCloseHandle( tUrlHandle );
+ }
+ else MSN_DebugLog( "InternetOpenUrl() failed" );
+
+ f_InternetCloseHandle( tNetHandle );
+ return tSslAnswer;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Performs the MSN Passport login via SSL3 using the OpenSSL library
+
+typedef int ( *PFN_SSL_int_void ) ( void );
+typedef PVOID ( *PFN_SSL_pvoid_void ) ( void );
+typedef PVOID ( *PFN_SSL_pvoid_pvoid ) ( PVOID );
+typedef void ( *PFN_SSL_void_pvoid ) ( PVOID );
+typedef int ( *PFN_SSL_int_pvoid_int ) ( PVOID, int );
+typedef int ( *PFN_SSL_int_pvoid ) ( PVOID );
+typedef int ( *PFN_SSL_int_pvoid_pvoid_int ) ( PVOID, PVOID, int );
+
+struct SSL_OpenSsl : public SSL_Base
+{
+ virtual char* getSslResult( char* parUrl, char* parAuthInfo );
+ virtual int init();
+
+ static PVOID sslCtx;
+
+ static HMODULE hLibSSL, hLibEAY;
+ static PFN_SSL_int_void pfn_SSL_library_init;
+ static PFN_SSL_pvoid_void pfn_SSLv23_client_method;
+ static PFN_SSL_pvoid_pvoid pfn_SSL_CTX_new;
+ static PFN_SSL_void_pvoid pfn_SSL_CTX_free;
+ static PFN_SSL_pvoid_pvoid pfn_SSL_new;
+ static PFN_SSL_void_pvoid pfn_SSL_free;
+ static PFN_SSL_int_pvoid_int pfn_SSL_set_fd;
+ static PFN_SSL_int_pvoid pfn_SSL_connect;
+ static PFN_SSL_int_pvoid_pvoid_int pfn_SSL_read;
+ static PFN_SSL_int_pvoid_pvoid_int pfn_SSL_write;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+PVOID SSL_OpenSsl::sslCtx = NULL;
+
+HMODULE SSL_OpenSsl::hLibSSL = NULL,
+ SSL_OpenSsl::hLibEAY = NULL;
+
+PFN_SSL_int_void SSL_OpenSsl::pfn_SSL_library_init;
+PFN_SSL_pvoid_void SSL_OpenSsl::pfn_SSLv23_client_method;
+PFN_SSL_pvoid_pvoid SSL_OpenSsl::pfn_SSL_CTX_new;
+PFN_SSL_void_pvoid SSL_OpenSsl::pfn_SSL_CTX_free;
+PFN_SSL_pvoid_pvoid SSL_OpenSsl::pfn_SSL_new;
+PFN_SSL_void_pvoid SSL_OpenSsl::pfn_SSL_free;
+PFN_SSL_int_pvoid_int SSL_OpenSsl::pfn_SSL_set_fd;
+PFN_SSL_int_pvoid SSL_OpenSsl::pfn_SSL_connect;
+PFN_SSL_int_pvoid_pvoid_int SSL_OpenSsl::pfn_SSL_read;
+PFN_SSL_int_pvoid_pvoid_int SSL_OpenSsl::pfn_SSL_write;
+
+int SSL_OpenSsl::init()
+{
+ if ( sslCtx != NULL )
+ return 0;
+
+ if ( hLibSSL == NULL ) {
+ if (( hLibEAY = LoadLibraryA( "LIBEAY32.DLL" )) == NULL ) {
+ MSN_ShowError( "Valid %s must be installed to perform the SSL login", "LIBEAY32.DLL" );
+ return 1;
+ }
+
+ if (( hLibSSL = LoadLibraryA( "LIBSSL32.DLL" )) == NULL ) {
+ MSN_ShowError( "Valid %s must be installed to perform the SSL login", "LIBSSL32.DLL" );
+ return 1;
+ } }
+
+ int retVal = 0;
+ if (( pfn_SSL_library_init = ( PFN_SSL_int_void )GetProcAddress( hLibSSL, "SSL_library_init" )) == NULL )
+ retVal = TRUE;
+ if (( pfn_SSLv23_client_method = ( PFN_SSL_pvoid_void )GetProcAddress( hLibSSL, "SSLv23_client_method" )) == NULL )
+ retVal = TRUE;
+ if (( pfn_SSL_CTX_new = ( PFN_SSL_pvoid_pvoid )GetProcAddress( hLibSSL, "SSL_CTX_new" )) == NULL )
+ retVal = TRUE;
+ if (( pfn_SSL_CTX_free = ( PFN_SSL_void_pvoid )GetProcAddress( hLibSSL, "SSL_CTX_free" )) == NULL )
+ retVal = TRUE;
+ if (( pfn_SSL_new = ( PFN_SSL_pvoid_pvoid )GetProcAddress( hLibSSL, "SSL_new" )) == NULL )
+ retVal = TRUE;
+ if (( pfn_SSL_free = ( PFN_SSL_void_pvoid )GetProcAddress( hLibSSL, "SSL_free" )) == NULL )
+ retVal = TRUE;
+ if (( pfn_SSL_set_fd = ( PFN_SSL_int_pvoid_int )GetProcAddress( hLibSSL, "SSL_set_fd" )) == NULL )
+ retVal = TRUE;
+ if (( pfn_SSL_connect = ( PFN_SSL_int_pvoid )GetProcAddress( hLibSSL, "SSL_connect" )) == NULL )
+ retVal = TRUE;
+ if (( pfn_SSL_read = ( PFN_SSL_int_pvoid_pvoid_int )GetProcAddress( hLibSSL, "SSL_read" )) == NULL )
+ retVal = TRUE;
+ if (( pfn_SSL_write = ( PFN_SSL_int_pvoid_pvoid_int )GetProcAddress( hLibSSL, "SSL_write" )) == NULL )
+ retVal = TRUE;
+
+ if ( retVal ) {
+ FreeLibrary( hLibSSL );
+ MSN_ShowError( "Valid %s must be installed to perform the SSL login", "LIBSSL32.DLL" );
+ return 1;
+ }
+
+ pfn_SSL_library_init();
+ sslCtx = pfn_SSL_CTX_new( pfn_SSLv23_client_method());
+ MSN_DebugLog( "OpenSSL context successully allocated" );
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+char* SSL_OpenSsl::getSslResult( char* parUrl, char* parAuthInfo )
+{
+ if ( strnicmp( parUrl, "https://", 8 ) != 0 )
+ return NULL;
+
+ char* url = NEWSTR_ALLOCA( parUrl );
+ char* path = strchr( url+9, '//' );
+ if ( path == NULL ) {
+ MSN_DebugLog( "Invalid URL passed: '%s'", parUrl );
+ return NULL;
+ }
+ *path++ = 0;
+
+ NETLIBUSERSETTINGS nls = { 0 };
+ nls.cbSize = sizeof( nls );
+ MSN_CallService(MS_NETLIB_GETUSERSETTINGS,WPARAM(hNetlibUser),LPARAM(&nls));
+ int cpType = nls.proxyType;
+
+ if (cpType == PROXYTYPE_HTTP)
+ {
+ nls.proxyType = PROXYTYPE_HTTPS;
+ nls.szProxyServer = NEWSTR_ALLOCA(nls.szProxyServer);
+ nls.szIncomingPorts = NEWSTR_ALLOCA(nls.szIncomingPorts);
+ nls.szOutgoingPorts = NEWSTR_ALLOCA(nls.szOutgoingPorts);
+ nls.szProxyAuthPassword = NEWSTR_ALLOCA(nls.szProxyAuthPassword);
+ nls.szProxyAuthUser = NEWSTR_ALLOCA(nls.szProxyAuthUser);
+ MSN_CallService(MS_NETLIB_SETUSERSETTINGS,WPARAM(hNetlibUser),LPARAM(&nls));
+ }
+
+ NETLIBOPENCONNECTION tConn = { 0 };
+ tConn.cbSize = sizeof( tConn );
+ tConn.szHost = url+8;
+ tConn.wPort = 443;
+ HANDLE h = ( HANDLE )MSN_CallService( MS_NETLIB_OPENCONNECTION, ( WPARAM )hNetlibUser, ( LPARAM )&tConn );
+
+ if (cpType == PROXYTYPE_HTTP)
+ {
+ nls.proxyType = PROXYTYPE_HTTP;
+ nls.szProxyServer = NEWSTR_ALLOCA(nls.szProxyServer);
+ nls.szIncomingPorts = NEWSTR_ALLOCA(nls.szIncomingPorts);
+ nls.szOutgoingPorts = NEWSTR_ALLOCA(nls.szOutgoingPorts);
+ nls.szProxyAuthPassword = NEWSTR_ALLOCA(nls.szProxyAuthPassword);
+ nls.szProxyAuthUser = NEWSTR_ALLOCA(nls.szProxyAuthUser);
+ MSN_CallService(MS_NETLIB_SETUSERSETTINGS,WPARAM(hNetlibUser),LPARAM(&nls));
+ }
+
+ if ( h == NULL )
+ return NULL;
+
+ char* result = NULL;
+ PVOID ssl = pfn_SSL_new( sslCtx );
+ if ( ssl != NULL ) {
+ SOCKET s = MSN_CallService( MS_NETLIB_GETSOCKET, ( WPARAM )h, 0 );
+ if ( s != INVALID_SOCKET ) {
+ pfn_SSL_set_fd( ssl, s );
+ if ( pfn_SSL_connect( ssl ) > 0 ) {
+ MSN_DebugLog( "SSL connection succeeded" );
+
+ char *buf = ( char* )alloca( SSL_BUF_SIZE );
+
+ int nBytes = mir_snprintf( buf, SSL_BUF_SIZE,
+ "GET /%s HTTP/1.1\r\n"
+ "Accept: */*\r\n"
+ "Accept-Language: en;q=0.5\r\n"
+ "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\r\n"
+ "Host: %s\r\n"
+ "Connection: Keep-Alive\r\n", path, url+8 );
+
+ if ( parAuthInfo != NULL ) {
+ strcat( buf+nBytes, parAuthInfo );
+ strcat( buf+nBytes, "\r\n" );
+ }
+
+ strcat( buf+nBytes, "\r\n" );
+
+// MSN_DebugLog( "Sending SSL query:\n%s", buf );
+ pfn_SSL_write( ssl, buf, strlen( buf ));
+
+ nBytes = pfn_SSL_read( ssl, buf, SSL_BUF_SIZE );
+ if ( nBytes > 0 ) {
+ result = ( char* )malloc( nBytes+1 );
+ memcpy( result, buf, nBytes+1 );
+ result[ nBytes ] = 0;
+
+ MSN_DebugLog( "SSL read successfully read %d bytes:\n%s", nBytes, result );
+ }
+ else MSN_DebugLog( "SSL read failed" );
+ }
+ else MSN_DebugLog( "SSL connection failed" );
+ }
+ else MSN_DebugLog( "pfn_SSL_connect failed" );
+
+ pfn_SSL_free( ssl );
+ }
+ else MSN_DebugLog( "pfn_SSL_new failed" );
+
+ MSN_CallService( MS_NETLIB_CLOSEHANDLE, ( WPARAM )h, 0 );
+ return result;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Checks the MSN Passport redirector site
+
+int MSN_CheckRedirector()
+{
+ int retVal = 0;
+ SSL_Base* pAgent;
+ if ( MSN_GetByte( "UseOpenSSL", 0 ))
+ pAgent = new SSL_OpenSsl();
+ else
+ pAgent = new SSL_WinInet();
+ if ( pAgent == NULL )
+ return 1;
+
+ if ( pAgent->init() ) {
+ delete pAgent;
+ return 2;
+ }
+
+ char* msnLoginHost = pAgent->getSslResult( "https://nexus.passport.com/rdr/pprdr.asp", NULL );
+ if ( msnLoginHost == NULL ) {
+ retVal = 1;
+LBL_Exit:
+ delete pAgent;
+ MSN_DebugLog( "MSN_CheckRedirector exited with errorCode = %d", retVal );
+ return retVal;
+ }
+
+ char* p = strstr( msnLoginHost, "DALogin=" );
+ if ( p == NULL ) {
+ free( msnLoginHost ); msnLoginHost = NULL;
+ retVal = 2;
+ goto LBL_Exit;
+ }
+
+ strcpy( msnLoginHost, "https://" );
+ strdel( msnLoginHost+8, int( p-msnLoginHost ));
+ if (( p = strchr( msnLoginHost, ',' )) != 0 )
+ *p = 0;
+
+ MSN_SetString( NULL, "MsnPassportHost", msnLoginHost );
+ MSN_DebugLog( "MSN Passport login host is set to '%s'", msnLoginHost );
+ free( msnLoginHost );
+ goto LBL_Exit;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Performs the MSN Passport login via SSL3
+
+int MSN_GetPassportAuth( char* authChallengeInfo, char*& parResult )
+{
+ int retVal = 0;
+ parResult = NULL;
+ SSL_Base* pAgent;
+ if ( MSN_GetByte( "UseOpenSSL", 0 ))
+ pAgent = new SSL_OpenSsl();
+ else
+ pAgent = new SSL_WinInet();
+ if ( pAgent == NULL )
+ return 1;
+
+ if ( pAgent->init() ) {
+ delete pAgent;
+ return 2;
+ }
+
+ char szEmail[ MSN_MAX_EMAIL_LEN ];
+ MSN_GetStaticString( "e-mail", NULL, szEmail, MSN_MAX_EMAIL_LEN );
+ char* p = strchr( szEmail, '@' );
+ if ( p != NULL ) {
+ memmove( p+3, p+1, strlen( p ));
+ memcpy( p, "%40", 3 );
+ }
+
+ char szPassword[ 100 ];
+ MSN_GetStaticString( "Password", NULL, szPassword, sizeof szPassword );
+ MSN_CallService( MS_DB_CRYPT_DECODESTRING, strlen( szPassword )+1, ( LPARAM )szPassword );
+ szPassword[ 16 ] = 0;
+
+ char* szAuthInfo = ( char* )alloca( 1024 );
+ int nBytes = mir_snprintf( szAuthInfo, 1024,
+ "Authorization: Passport1.4 OrgVerb=GET,OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom,sign-in=%s,pwd=",
+ szEmail );
+ UrlEncode( szPassword, szAuthInfo+nBytes, 1024-nBytes );
+ strcat( szAuthInfo+nBytes, "," );
+ strcat( szAuthInfo+nBytes, authChallengeInfo );
+
+ char szPassportHost[ 256 ];
+ if ( MSN_GetStaticString( "MsnPassportHost", NULL, szPassportHost, sizeof( szPassportHost ))) {
+ retVal = 3;
+LBL_Exit:
+ delete pAgent;
+ MSN_DebugLog( "MSN_CheckRedirector exited with errorCode = %d", retVal );
+ return retVal;
+ }
+
+ char* tResult;
+
+ for (;;)
+ {
+ tResult = pAgent->getSslResult( szPassportHost, szAuthInfo );
+ if ( tResult == NULL ) {
+ retVal = 4;
+ goto LBL_Exit;
+ }
+
+ int status = 0;
+ sscanf( tResult, "HTTP/1.1 %d", &status );
+ if ( status == 302 ) // Handle redirect
+ {
+ if (( p = strstr( tResult, "Location:" )) == NULL ) {
+ free( tResult );
+ retVal = 7;
+ goto LBL_Exit;
+ }
+ strdel( tResult, int( p-tResult )+10 );
+ if (( p = strchr( tResult, '\r' )) != NULL )
+ *p = 0;
+ strcpy(szPassportHost, tResult);
+ MSN_DebugLog( "Redirected to '%s'", tResult );
+ free( tResult );
+ }
+ else if (status != 200)
+ {
+ retVal = 6;
+ free( tResult );
+ goto LBL_Exit;
+ }
+ else break;
+ }
+
+ if (( p = strstr( tResult, "from-PP=" )) == NULL ) {
+ free( tResult );
+ retVal = 5;
+ goto LBL_Exit;
+ }
+
+ strdel( tResult, int( p-tResult )+9 );
+
+ if (( p = strchr( tResult, '\'' )) != NULL )
+ *p = 0;
+
+ parResult = tResult;
+ goto LBL_Exit;
+}
+
+void UninitSsl( void )
+{
+ if ( SSL_OpenSsl::hLibEAY )
+ FreeLibrary( SSL_OpenSsl::hLibEAY );
+
+ if ( SSL_OpenSsl::hLibSSL ) {
+ SSL_OpenSsl::pfn_SSL_CTX_free( SSL_OpenSsl::sslCtx );
+
+ MSN_DebugLog( "Free SSL library" );
+ FreeLibrary( SSL_OpenSsl::hLibSSL );
+} }
|