4398 lines
134 KiB
C++
4398 lines
134 KiB
C++
// Manager.cpp : Implementation of CManager
|
|
#include "stdafx.h"
|
|
#include <httpext.h>
|
|
#include "Manager.h"
|
|
#include <httpfilt.h>
|
|
#include <time.h>
|
|
#include <malloc.h>
|
|
#include <wininet.h>
|
|
|
|
#include <nsconst.h>
|
|
|
|
#include "VariantUtils.h"
|
|
#include "HelperFuncs.h"
|
|
#include "PassportService_i.c"
|
|
|
|
|
|
PWSTR GetVersionString();
|
|
|
|
|
|
// gmarks
|
|
#include "Monitoring.h"
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CManager
|
|
|
|
#include "passporttypes.h"
|
|
|
|
// static utility func
|
|
static VOID GetTicketAndProfileFromHeader(PWSTR pszAuthHeader,
|
|
PWSTR& tix,
|
|
PWSTR& prof,
|
|
PWSTR& F);
|
|
|
|
// Used for cookie expiration.
|
|
const DATE g_dtExpire = 365*137;
|
|
const DATE g_dtExpired = 365*81;
|
|
|
|
|
|
CManager::CManager() :
|
|
m_fromQueryString(false), m_ticketValid(VARIANT_FALSE), m_profileValid(VARIANT_FALSE), m_lNetworkError(0),
|
|
m_pRegistryConfig(NULL), m_pECB(NULL), m_pFC(NULL),
|
|
m_bIsTweenerCapable(FALSE),
|
|
m_bSecureTransported(false)
|
|
{
|
|
m_pUnkMarshaler = NULL;
|
|
m_piTicket = new CComObject<CTicket>();
|
|
m_piTicket->AddRef();
|
|
m_piProfile = new CComObject<CProfile>();
|
|
m_piProfile->AddRef();
|
|
|
|
m_bOnStartPageCalled = false;
|
|
|
|
m_valid = true;
|
|
}
|
|
|
|
|
|
CManager::~CManager()
|
|
{
|
|
if(m_pRegistryConfig)
|
|
m_pRegistryConfig->Release();
|
|
m_piTicket->Release();
|
|
m_piProfile->Release();
|
|
}
|
|
|
|
// return S_OK -- altered, should use two returned output params for MSPAuth and MSPSecAuth as cookies
|
|
// S_FALSE -- not altered
|
|
// if MSPSecAuth != NULL, write the cookie
|
|
|
|
|
|
HRESULT CManager::IfConsentCookie(BSTR* pMSPConsent)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
LPCSTR domain = m_pRegistryConfig->getTicketDomain();
|
|
LPCSTR path = m_pRegistryConfig->getTicketPath();
|
|
LPCSTR tertiaryDomain = m_pRegistryConfig->getProfileDomain();
|
|
LPCSTR tertiaryPath = m_pRegistryConfig->getProfilePath();
|
|
|
|
if (!tertiaryPath) tertiaryPath = "/";
|
|
|
|
if(!domain) domain = "";
|
|
if(!path) path = "";
|
|
|
|
if(!tertiaryDomain) tertiaryDomain = "";
|
|
if(!tertiaryPath) tertiaryPath = "";
|
|
|
|
if((lstrcmpiA(domain, tertiaryDomain) || lstrcmpiA(path, tertiaryPath)) &&
|
|
(m_piTicket->GetPassportFlags() & k_ulFlagsConsentCookieNeeded) &&
|
|
!m_pRegistryConfig->bInDA() )
|
|
{
|
|
if (pMSPConsent == NULL) // only to test, no output
|
|
hr = S_OK;
|
|
else
|
|
{
|
|
*pMSPConsent = NULL;
|
|
|
|
CComBSTR bstrRawConsent;
|
|
|
|
CCoCrypt* crypt = m_pRegistryConfig->getCurrentCrypt();
|
|
if (!crypt)
|
|
{
|
|
hr = E_FAIL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = m_piTicket->get_unencryptedCookie(CTicket::MSPConsent, 0, &bstrRawConsent);
|
|
if (FAILED(hr)) goto Cleanup;
|
|
|
|
crypt->Encrypt(m_pRegistryConfig->getCurrentCryptVersion(),
|
|
(LPSTR)(BSTR)bstrRawConsent,
|
|
SysStringByteLen(bstrRawConsent),
|
|
pMSPConsent);
|
|
}
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
// return S_OK -- altered, should use two returned output params for MSPAuth and MSPSecAuth as cookies
|
|
// S_FALSE -- not altered
|
|
// if MSPSecAuth != NULL, write the cookie
|
|
HRESULT CManager::IfAlterAuthCookie(BSTR* pMSPAuth, BSTR* pMSPSecAuth)
|
|
{
|
|
_ASSERT(pMSPAuth && pMSPSecAuth);
|
|
|
|
*pMSPAuth = NULL;
|
|
*pMSPSecAuth = NULL;
|
|
|
|
HRESULT hr = S_FALSE;
|
|
|
|
if (!(m_piTicket->GetPassportFlags() & k_ulFlagsSecuredTransportedTicket) || !m_bSecureTransported)
|
|
return hr;
|
|
|
|
CComBSTR bstrRawAuth;
|
|
CComBSTR bstrRawSecAuth;
|
|
|
|
CCoCrypt* crypt = m_pRegistryConfig->getCurrentCrypt();
|
|
if (!crypt)
|
|
{
|
|
hr = PM_CANT_DECRYPT_CONFIG;
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = m_piTicket->get_unencryptedCookie(CTicket::MSPAuth, 0, &bstrRawAuth);
|
|
if (FAILED(hr)) goto Cleanup;
|
|
|
|
crypt->Encrypt(m_pRegistryConfig->getCurrentCryptVersion(),
|
|
(LPSTR)(BSTR)bstrRawAuth,
|
|
SysStringByteLen(bstrRawAuth),
|
|
pMSPAuth);
|
|
|
|
hr = m_piTicket->get_unencryptedCookie(CTicket::MSPSecAuth, 0, &bstrRawSecAuth);
|
|
if (FAILED(hr)) goto Cleanup;
|
|
|
|
crypt->Encrypt(m_pRegistryConfig->getCurrentCryptVersion(),
|
|
(LPSTR)(BSTR)bstrRawSecAuth,
|
|
SysStringByteLen(bstrRawSecAuth),
|
|
pMSPSecAuth);
|
|
|
|
Cleanup:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
void
|
|
CManager::wipeState()
|
|
{
|
|
m_pECB = NULL;
|
|
m_pFC = NULL;
|
|
m_bIsTweenerCapable = FALSE;
|
|
m_bOnStartPageCalled = false;
|
|
m_fromQueryString = false;
|
|
m_lNetworkError = 0;
|
|
m_ticketValid = VARIANT_FALSE;
|
|
m_profileValid = VARIANT_FALSE;
|
|
m_piRequest = NULL;
|
|
m_piResponse = NULL;
|
|
|
|
m_piTicket->put_unencryptedTicket(NULL);
|
|
m_piProfile->put_unencryptedProfile(NULL);
|
|
|
|
if(m_pRegistryConfig)
|
|
{
|
|
m_pRegistryConfig->Release();
|
|
m_pRegistryConfig = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
STDMETHODIMP CManager::InterfaceSupportsErrorInfo(REFIID riid)
|
|
{
|
|
static const IID* arr[] =
|
|
{
|
|
&IID_IPassportManager,
|
|
};
|
|
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
|
{
|
|
if (InlineIsEqualGUID(*arr[i],riid))
|
|
return S_OK;
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP CManager::OnStartPage (IUnknown* pUnk)
|
|
{
|
|
IScriptingContextPtr spContext;
|
|
IRequestDictionaryPtr piServerVariables;
|
|
_variant_t vtItemName;
|
|
_variant_t vtServerName;
|
|
_variant_t vtServerPort;
|
|
_variant_t vtHTTPS;
|
|
BOOL bHasPort;
|
|
DWORD dwServerNameLen;
|
|
|
|
USES_CONVERSION;
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
char szLogString[LOG_STRING_LEN] = "CManager::OnStartPage, Enter";
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
if(!pUnk)
|
|
return E_POINTER;
|
|
|
|
if (!m_valid || !g_config->isValid()) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
wipeState();
|
|
|
|
try
|
|
{
|
|
// Get the IScriptingContext Interface
|
|
spContext = pUnk;
|
|
// Get Request Object Pointer
|
|
m_piRequest = spContext->Request;
|
|
// Get Response Object Pointer
|
|
m_piResponse = spContext->Response;
|
|
|
|
//
|
|
// Get the server variables collection.
|
|
//
|
|
|
|
m_piRequest->get_ServerVariables(&piServerVariables);
|
|
|
|
//
|
|
// now see if that's a special redirect
|
|
// requiring challenge generation
|
|
// if so processing stops here ....
|
|
//
|
|
if (checkForPassportChallenge(piServerVariables))
|
|
return S_OK;
|
|
|
|
//
|
|
// Might need this for multi-site, or secure ticket/profile
|
|
//
|
|
|
|
vtItemName = L"HTTPS";
|
|
|
|
piServerVariables->get_Item(vtItemName, &vtHTTPS);
|
|
if(vtHTTPS.vt != VT_BSTR)
|
|
vtHTTPS.ChangeType(VT_BSTR);
|
|
|
|
if(lstrcmpiW(L"on", vtHTTPS.bstrVal) == 0)
|
|
m_bSecureTransported = true;
|
|
else
|
|
m_bSecureTransported = false;
|
|
|
|
//
|
|
// Use the request object to get the server name being requested
|
|
// so we can get the correct registry config. But only do this
|
|
// if we have some configured sites.
|
|
//
|
|
|
|
if(g_config->HasSites())
|
|
{
|
|
LPWSTR szServerName;
|
|
|
|
vtItemName.Clear();
|
|
vtItemName = L"SERVER_NAME";
|
|
|
|
piServerVariables->get_Item(vtItemName, &vtServerName);
|
|
if(vtServerName.vt != VT_BSTR)
|
|
vtServerName.ChangeType(VT_BSTR);
|
|
|
|
vtItemName.Clear();
|
|
vtItemName = L"SERVER_PORT";
|
|
|
|
piServerVariables->get_Item(vtItemName, &vtServerPort);
|
|
if(vtServerPort.vt != VT_BSTR)
|
|
vtServerPort.ChangeType(VT_BSTR);
|
|
|
|
// If not default port, append ":port" to server name.
|
|
bHasPort = (!m_bSecureTransported && lstrcmpW(L"80", vtServerPort.bstrVal) != 0
|
|
|| m_bSecureTransported && lstrcmpW(L"443", vtServerPort.bstrVal) != 0);
|
|
dwServerNameLen = bHasPort ?
|
|
lstrlenW(vtServerName.bstrVal) + lstrlenW(vtServerPort.bstrVal) + 2 :
|
|
lstrlenW(vtServerName.bstrVal) + 1;
|
|
|
|
szServerName = new WCHAR[dwServerNameLen];
|
|
if(szServerName)
|
|
{
|
|
lstrcpyW(szServerName, vtServerName.bstrVal);
|
|
if(bHasPort)
|
|
{
|
|
lstrcatW(szServerName, L":");
|
|
lstrcatW(szServerName, vtServerPort.bstrVal);
|
|
}
|
|
|
|
if(m_pRegistryConfig)
|
|
m_pRegistryConfig->Release();
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig(W2A(szServerName));
|
|
|
|
delete [] szServerName;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(m_pRegistryConfig)
|
|
m_pRegistryConfig->Release();
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
}
|
|
|
|
m_bOnStartPageCalled = true;
|
|
|
|
// check if client has accept-auth header
|
|
vtItemName.Clear();
|
|
vtItemName = L"HTTP_Accept-Auth";
|
|
{
|
|
_variant_t vtAccept;
|
|
piServerVariables->get_Item(vtItemName, &vtAccept);
|
|
if(vtAccept.vt != VT_BSTR)
|
|
vtAccept.ChangeType(VT_BSTR);
|
|
if (vtAccept.vt == VT_BSTR && vtAccept.bstrVal &&
|
|
wcsstr(vtAccept.bstrVal, PASSPORT_PROT14))
|
|
{
|
|
m_bIsTweenerCapable = TRUE;
|
|
}
|
|
}
|
|
|
|
// BUGBUG I think this might not always return a single value
|
|
// Variables to hold ticket and profile
|
|
_bstr_t bstrAuth;
|
|
_bstr_t bstrProf;
|
|
|
|
// first check the auth header!!!
|
|
BOOL fFromAuthHeader = FALSE;
|
|
vtItemName.Clear();
|
|
vtItemName = L"HTTP_Authorization";
|
|
|
|
_variant_t vtAuth;
|
|
piServerVariables->get_Item(vtItemName, &vtAuth);
|
|
if(vtAuth.vt != VT_BSTR)
|
|
vtAuth.ChangeType(VT_BSTR);
|
|
|
|
BOOL fQueryStringLogon = FALSE;
|
|
if (vtAuth.vt == VT_BSTR && vtAuth.bstrVal &&
|
|
wcsstr(vtAuth.bstrVal, PASSPORT_PROT14))
|
|
{
|
|
fFromAuthHeader = TRUE;
|
|
// ticket and profile from the header
|
|
PWSTR pwszTicket = NULL, pwszProfile = NULL, pwszF = NULL;
|
|
GetTicketAndProfileFromHeader(vtAuth.bstrVal, pwszTicket, pwszProfile, pwszF);
|
|
if(pwszF != 0)
|
|
m_lNetworkError = _wtol(pwszF);
|
|
// init for more use
|
|
bstrAuth = pwszTicket;
|
|
bstrProf = pwszProfile;
|
|
}
|
|
else
|
|
{
|
|
// if not, check the query string
|
|
IRequestDictionaryPtr piQueryStr = m_piRequest->QueryString;
|
|
bstrAuth = piQueryStr->Item[L"t"];
|
|
bstrProf = piQueryStr->Item[L"p"];
|
|
_bstr_t bstrError = piQueryStr->Item[L"f"];
|
|
|
|
if(bstrError.length() != 0)
|
|
m_lNetworkError = _wtol(bstrError);
|
|
}
|
|
|
|
|
|
if (handleQueryStringData(bstrAuth, bstrProf))
|
|
{
|
|
VARIANT_BOOL persist;
|
|
_bstr_t domain;
|
|
_bstr_t path;
|
|
|
|
if (m_pRegistryConfig->getTicketPath())
|
|
path = m_pRegistryConfig->getTicketPath();
|
|
else
|
|
path = L"/";
|
|
|
|
m_piTicket->get_HasSavedPassword(&persist);
|
|
IRequestDictionaryPtr piCookies = m_piResponse->Cookies;
|
|
|
|
VARIANT vtNoParam;
|
|
VariantInit(&vtNoParam);
|
|
vtNoParam.vt = VT_ERROR;
|
|
vtNoParam.scode = DISP_E_PARAMNOTFOUND;
|
|
|
|
CComBSTR bstrNewAuth;
|
|
CComBSTR bstrNewSecAuth;
|
|
|
|
BSTR auth, secAuth; // do not call SysFreeString on them, they are skin level copy
|
|
|
|
if (S_OK == IfAlterAuthCookie(&bstrNewAuth, &bstrNewSecAuth))
|
|
{
|
|
auth = bstrNewAuth;
|
|
secAuth = bstrNewSecAuth;
|
|
}
|
|
else
|
|
{
|
|
auth = bstrAuth;
|
|
secAuth = NULL;
|
|
}
|
|
|
|
// ==
|
|
// write auth cookies
|
|
|
|
// MSPAuth
|
|
IWriteCookiePtr piCookie = piCookies->Item[L"MSPAuth"];
|
|
piCookie->Item[vtNoParam] = auth;
|
|
|
|
domain = m_pRegistryConfig->getTicketDomain();
|
|
if (domain.length())
|
|
piCookie->put_Domain(domain);
|
|
if (persist)
|
|
piCookie->put_Expires(g_dtExpire);
|
|
piCookie->put_Path(path);
|
|
|
|
// MSPSecAuth
|
|
if (m_bSecureTransported)
|
|
{
|
|
piCookie = piCookies->Item[L"MSPSecAuth"];
|
|
piCookie->Item[vtNoParam] = secAuth;
|
|
|
|
domain = m_pRegistryConfig->getTicketDomain();
|
|
if (domain.length())
|
|
piCookie->put_Domain(domain);
|
|
if (persist)
|
|
piCookie->put_Expires(g_dtExpire);
|
|
piCookie->put_Path(path);
|
|
piCookie->put_Secure(VARIANT_TRUE);
|
|
}
|
|
|
|
// write profile cookies
|
|
if((LPWSTR)bstrProf && bstrProf.length() != 0)
|
|
{
|
|
piCookie = piCookies->Item[L"MSPProf"];
|
|
piCookie->Item[vtNoParam] = bstrProf;
|
|
|
|
if (domain.length())
|
|
piCookie->put_Domain(domain);
|
|
if (persist)
|
|
piCookie->put_Expires(g_dtExpire);
|
|
piCookie->put_Path(path);
|
|
|
|
}
|
|
|
|
// if New client, put the auth Info in header
|
|
// move out of the profile condition
|
|
if (fFromAuthHeader)
|
|
{
|
|
// ticket and profile came in a header ...
|
|
WCHAR wszAuthHeader[100];
|
|
wsprintf(wszAuthHeader, L"%ws %ws", PASSPORT_PROT14, PPCOOKIE_NAMES);
|
|
m_piResponse->AddHeader(PPAUTH_INFO_HEADER, wszAuthHeader);
|
|
}
|
|
|
|
//
|
|
// MSPConsent Cookie
|
|
_bstr_t bstrConsentCookie;
|
|
CComBSTR bstrtemp;
|
|
HRESULT hr = IfConsentCookie(&bstrtemp);
|
|
bstrConsentCookie = bstrtemp;
|
|
|
|
piCookie = piCookies->Item[L"MSPConsent"];
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
piCookie->Item[vtNoParam] = bstrConsentCookie;
|
|
if (persist) piCookie->put_Expires(g_dtExpire);
|
|
}
|
|
// need delete
|
|
else
|
|
{
|
|
piCookie->Item[vtNoParam] = L"";
|
|
piCookie->put_Expires(g_dtExpired);
|
|
}
|
|
|
|
|
|
if (m_pRegistryConfig->getProfilePath())
|
|
path = m_pRegistryConfig->getProfilePath();
|
|
else
|
|
path = L"/";
|
|
|
|
domain = m_pRegistryConfig->getProfileDomain();
|
|
if (domain.length()) piCookie->put_Domain(domain);
|
|
piCookie->put_Path(path);
|
|
// end of consent cookie
|
|
//
|
|
|
|
if(g_pPerf)
|
|
{
|
|
g_pPerf->incrementCounter(PM_NEWCOOKIES_SEC);
|
|
g_pPerf->incrementCounter(PM_NEWCOOKIES_TOTAL);
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(g_pPerf);
|
|
}
|
|
}
|
|
|
|
// Now, check the cookies
|
|
if (!m_fromQueryString)
|
|
{
|
|
IRequestDictionaryPtr piCookies = m_piRequest->Cookies;
|
|
bstrAuth = piCookies->Item[L"MSPAuth"];
|
|
|
|
bstrProf = piCookies->Item[L"MSPProf"];
|
|
_bstr_t bstrSec = piCookies->Item[L"MSPSecAuth"];
|
|
|
|
_bstr_t bstrConsent = piCookies->Item[L"MSPConsent"];
|
|
|
|
handleCookieData(bstrAuth, bstrProf, bstrConsent, bstrSec);
|
|
}
|
|
|
|
}
|
|
catch (...)
|
|
{
|
|
if (m_piRequest.GetInterfacePtr() != NULL)
|
|
m_piRequest.Release();
|
|
if (m_piResponse.GetInterfacePtr() != NULL)
|
|
m_piResponse.Release();
|
|
m_bOnStartPageCalled = false;
|
|
return S_OK;
|
|
}
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::OnStartPage, Exit");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CManager::OnStartPageASP(
|
|
IDispatch* piRequest,
|
|
IDispatch* piResponse
|
|
)
|
|
{
|
|
IRequestDictionaryPtr piServerVariables;
|
|
_variant_t vtItemName;
|
|
_variant_t vtServerName;
|
|
_variant_t vtServerPort;
|
|
_variant_t vtHTTPS;
|
|
BOOL bHasPort;
|
|
DWORD dwServerNameLen;
|
|
|
|
USES_CONVERSION;
|
|
|
|
if(!piRequest || !piResponse)
|
|
return E_POINTER;
|
|
|
|
if (!m_valid || !g_config->isValid()) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
wipeState();
|
|
|
|
m_piRequest = piRequest;
|
|
m_piResponse = piResponse;
|
|
|
|
//
|
|
// Get the server variables collection.
|
|
//
|
|
|
|
m_piRequest->get_ServerVariables(&piServerVariables);
|
|
|
|
//
|
|
// Might need this for multi-site, or secure ticket/profile
|
|
//
|
|
|
|
vtItemName = L"HTTPS";
|
|
|
|
piServerVariables->get_Item(vtItemName, &vtHTTPS);
|
|
if(vtHTTPS.vt != VT_BSTR)
|
|
vtHTTPS.ChangeType(VT_BSTR);
|
|
|
|
if(lstrcmpiW(L"on", vtHTTPS.bstrVal) == 0)
|
|
m_bSecureTransported = true;
|
|
else
|
|
m_bSecureTransported = false;
|
|
|
|
|
|
try
|
|
{
|
|
//
|
|
// Use the request object to get the server name being requested
|
|
// so we can get the correct registry config. But only do this
|
|
// if we have some configured sites.
|
|
//
|
|
|
|
if(g_config->HasSites())
|
|
{
|
|
LPWSTR szServerName;
|
|
|
|
vtItemName.Clear();
|
|
vtItemName = L"SERVER_NAME";
|
|
|
|
piServerVariables->get_Item(vtItemName, &vtServerName);
|
|
if(vtServerName.vt != VT_BSTR)
|
|
vtServerName.ChangeType(VT_BSTR);
|
|
|
|
VariantClear(&vtItemName);
|
|
vtItemName = L"SERVER_PORT";
|
|
|
|
piServerVariables->get_Item(vtItemName, &vtServerPort);
|
|
if(vtServerPort.vt != VT_BSTR)
|
|
vtServerPort.ChangeType(VT_BSTR);
|
|
|
|
// If not default port, append ":port" to server name.
|
|
bHasPort = (!m_bSecureTransported && lstrcmpW(L"80", vtServerPort.bstrVal) != 0
|
|
|| m_bSecureTransported && lstrcmpW(L"443", vtServerPort.bstrVal) != 0);
|
|
dwServerNameLen = bHasPort ?
|
|
lstrlenW(vtServerName.bstrVal) + lstrlenW(vtServerPort.bstrVal) + 2 :
|
|
lstrlenW(vtServerName.bstrVal) + 1;
|
|
|
|
szServerName = new WCHAR[dwServerNameLen];
|
|
if(szServerName)
|
|
{
|
|
lstrcpyW(szServerName, vtServerName.bstrVal);
|
|
if(bHasPort)
|
|
{
|
|
lstrcatW(szServerName, L":");
|
|
lstrcatW(szServerName, vtServerPort.bstrVal);
|
|
}
|
|
|
|
if(m_pRegistryConfig)
|
|
m_pRegistryConfig->Release();
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig(W2A(szServerName));
|
|
|
|
delete [] szServerName;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(m_pRegistryConfig)
|
|
m_pRegistryConfig->Release();
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
}
|
|
|
|
|
|
m_bOnStartPageCalled = true;
|
|
|
|
// BUGBUG I think this might not always return a single value
|
|
_bstr_t bstrAuth;
|
|
_bstr_t bstrProf;
|
|
// _bstr_t bstrSec;
|
|
// check for Auth header
|
|
vtItemName.Clear();
|
|
vtItemName = L"HTTP_Authorization";
|
|
|
|
_variant_t vtAuth;
|
|
BOOL fFromAuthHeader = FALSE;
|
|
piServerVariables->get_Item(vtItemName, &vtAuth);
|
|
if(vtAuth.vt != VT_BSTR)
|
|
vtAuth.ChangeType(VT_BSTR);
|
|
|
|
if (vtAuth.vt == VT_BSTR && vtAuth.bstrVal &&
|
|
wcsstr(vtAuth.bstrVal, PASSPORT_PROT14))
|
|
{
|
|
// ticket and profile from the header
|
|
PWSTR pwszTicket = NULL, pwszProfile = NULL, pwszF = NULL;
|
|
// handle the auth header
|
|
GetTicketAndProfileFromHeader(vtAuth.bstrVal, pwszTicket, pwszProfile, pwszF);
|
|
// initialize for later use.
|
|
bstrAuth = pwszTicket;
|
|
bstrProf = pwszProfile;
|
|
if (pwszF)
|
|
m_lNetworkError = _wtol(pwszF);
|
|
fFromAuthHeader = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// old client - handle query string
|
|
IRequestDictionaryPtr piQueryStr = m_piRequest->QueryString;
|
|
// BUGBUG I think this might not always return a single value
|
|
bstrAuth = piQueryStr->Item[L"t"];
|
|
bstrProf = piQueryStr->Item[L"p"];
|
|
_bstr_t bstrError = piQueryStr->Item[L"f"];
|
|
if(bstrError.length() != 0)
|
|
m_lNetworkError = _wtol(bstrError);
|
|
}
|
|
|
|
|
|
if (handleQueryStringData(bstrAuth, bstrProf))
|
|
{
|
|
VARIANT_BOOL persist;
|
|
_bstr_t domain;
|
|
_bstr_t path;
|
|
|
|
if (m_pRegistryConfig->getTicketPath())
|
|
path = m_pRegistryConfig->getTicketPath();
|
|
else
|
|
path = L"/";
|
|
|
|
m_piTicket->get_HasSavedPassword(&persist);
|
|
IRequestDictionaryPtr piCookies = m_piResponse->Cookies;
|
|
|
|
VARIANT vtNoParam;
|
|
VariantInit(&vtNoParam);
|
|
vtNoParam.vt = VT_ERROR;
|
|
vtNoParam.scode = DISP_E_PARAMNOTFOUND;
|
|
|
|
// write Auth cookies
|
|
CComBSTR bstrNewAuth;
|
|
CComBSTR bstrNewSecAuth;
|
|
|
|
BSTR auth, secAuth; // do not call SysFreeString on them, they are skin level copy
|
|
|
|
if (S_OK == IfAlterAuthCookie(&bstrNewAuth, &bstrNewSecAuth))
|
|
{
|
|
auth = bstrNewAuth;
|
|
secAuth = bstrNewSecAuth;
|
|
}
|
|
else
|
|
{
|
|
auth = bstrAuth;
|
|
secAuth = NULL;
|
|
}
|
|
|
|
// ==
|
|
// write auth cookies
|
|
|
|
// MSPAuth
|
|
IWriteCookiePtr piCookie = piCookies->Item[L"MSPAuth"];
|
|
piCookie->Item[vtNoParam] = auth;
|
|
|
|
domain = m_pRegistryConfig->getTicketDomain();
|
|
if (domain.length())
|
|
piCookie->put_Domain(domain);
|
|
if (persist)
|
|
piCookie->put_Expires(g_dtExpire);
|
|
piCookie->put_Path(path);
|
|
|
|
// MSPSecAuth
|
|
if (m_bSecureTransported)
|
|
{
|
|
piCookie = piCookies->Item[L"MSPSecAuth"];
|
|
piCookie->Item[vtNoParam] = secAuth;
|
|
|
|
domain = m_pRegistryConfig->getTicketDomain();
|
|
if (domain.length())
|
|
piCookie->put_Domain(domain);
|
|
if (persist)
|
|
piCookie->put_Expires(g_dtExpire);
|
|
piCookie->put_Path(path);
|
|
piCookie->put_Secure(VARIANT_TRUE);
|
|
}
|
|
|
|
|
|
// profile cookie
|
|
if((LPWSTR)bstrProf)
|
|
{
|
|
piCookie = piCookies->Item[L"MSPProf"];
|
|
piCookie->Item[vtNoParam] = bstrProf;
|
|
|
|
if (domain.length())
|
|
piCookie->put_Domain(domain);
|
|
if (persist)
|
|
piCookie->put_Expires(g_dtExpire);
|
|
piCookie->put_Path(path);
|
|
|
|
}
|
|
|
|
if (fFromAuthHeader)
|
|
{
|
|
// insert auth info header ...
|
|
// ticket and profile came in a header ...
|
|
WCHAR wszAuthHeader[100];
|
|
wsprintf(wszAuthHeader, L"%ws %ws", PASSPORT_PROT14, PPCOOKIE_NAMES);
|
|
m_piResponse->AddHeader(PPAUTH_INFO_HEADER, wszAuthHeader);
|
|
}
|
|
|
|
//
|
|
// MSPConsent Cookie
|
|
_bstr_t bstrConsentCookie;
|
|
CComBSTR bstrtemp;
|
|
HRESULT hr = IfConsentCookie(&bstrtemp);
|
|
bstrConsentCookie = bstrtemp;
|
|
|
|
piCookie = piCookies->Item[L"MSPConsent"];
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
piCookie->Item[vtNoParam] = bstrConsentCookie;
|
|
if (persist) piCookie->put_Expires(g_dtExpire);
|
|
}
|
|
else
|
|
{
|
|
piCookie->Item[vtNoParam] = L"";
|
|
piCookie->put_Expires(g_dtExpired);
|
|
}
|
|
|
|
|
|
if (m_pRegistryConfig->getProfilePath())
|
|
path = m_pRegistryConfig->getProfilePath();
|
|
else
|
|
path = L"/";
|
|
|
|
domain = m_pRegistryConfig->getProfileDomain();
|
|
if (domain.length()) piCookie->put_Domain(domain);
|
|
piCookie->put_Path(path);
|
|
// end of consent cookie
|
|
//
|
|
|
|
|
|
if(g_pPerf)
|
|
{
|
|
g_pPerf->incrementCounter(PM_NEWCOOKIES_SEC);
|
|
g_pPerf->incrementCounter(PM_NEWCOOKIES_TOTAL);
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(g_pPerf);
|
|
}
|
|
|
|
}
|
|
|
|
// Now, check the cookies
|
|
if (!m_fromQueryString)
|
|
{
|
|
IRequestDictionaryPtr piCookies = m_piRequest->Cookies;
|
|
bstrAuth = piCookies->Item[L"MSPAuth"];
|
|
bstrProf = piCookies->Item[L"MSPProf"];
|
|
|
|
// secure cookie
|
|
_bstr_t bstrSec = piCookies->Item[L"MSPSecAuth"];
|
|
|
|
_bstr_t bstrConsent = piCookies->Item[L"MSPConsent"];
|
|
|
|
handleCookieData(bstrAuth, bstrProf, bstrConsent, bstrSec);
|
|
}
|
|
|
|
}
|
|
catch (...)
|
|
{
|
|
if (m_piRequest.GetInterfacePtr() != NULL)
|
|
m_piRequest.Release();
|
|
if (m_piResponse.GetInterfacePtr() != NULL)
|
|
m_piResponse.Release();
|
|
m_bOnStartPageCalled = false;
|
|
return S_OK;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CManager::OnStartPageManual(
|
|
BSTR qsT,
|
|
BSTR qsP,
|
|
BSTR mspauth,
|
|
BSTR mspprof,
|
|
BSTR mspconsent,
|
|
VARIANT mspsec,
|
|
VARIANT* pCookies
|
|
)
|
|
{
|
|
int hasSec;
|
|
BSTR bstrSec;
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
char szLogString[LOG_STRING_LEN] = "CManager::OnStartPageManual, Enter";
|
|
AddBSTRAsString(qsT, szLogString, sizeof(szLogString));
|
|
AddBSTRAsString(qsP, szLogString, sizeof(szLogString));
|
|
AddBSTRAsString(mspauth, szLogString, sizeof(szLogString));
|
|
AddBSTRAsString(mspprof, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
if (!m_valid || !g_config->isValid()) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
wipeState();
|
|
|
|
if(m_pRegistryConfig)
|
|
m_pRegistryConfig->Release();
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
|
|
if (handleQueryStringData(qsT, qsP))
|
|
{
|
|
VARIANT_BOOL persist;
|
|
_bstr_t domain;
|
|
_bstr_t path;
|
|
_bstr_t bstrAuth;
|
|
_bstr_t bstrProf;
|
|
CComBSTR bstrConsent;
|
|
|
|
|
|
bstrAuth.Assign(qsT);
|
|
|
|
bstrProf.Assign(qsP);
|
|
|
|
|
|
if (pCookies)
|
|
{
|
|
VariantInit(pCookies);
|
|
|
|
if (m_pRegistryConfig->getTicketPath())
|
|
path = m_pRegistryConfig->getTicketPath();
|
|
else
|
|
path = L"/";
|
|
|
|
m_piTicket->get_HasSavedPassword(&persist);
|
|
|
|
BOOL bSetConsent = (S_OK == IfConsentCookie(&bstrConsent));
|
|
|
|
SAFEARRAYBOUND rgsabound;
|
|
rgsabound.lLbound = 0;
|
|
rgsabound.cElements = 2;
|
|
|
|
// secure cookie
|
|
if (m_bSecureTransported)
|
|
rgsabound.cElements++;
|
|
|
|
if(bSetConsent)
|
|
rgsabound.cElements++;
|
|
SAFEARRAY *sa = SafeArrayCreate(VT_VARIANT, 1, &rgsabound);
|
|
|
|
if (!sa)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
pCookies->vt = VT_ARRAY | VT_VARIANT;
|
|
pCookies->parray = sa;
|
|
|
|
WCHAR buf[4096];
|
|
DWORD bufSize;
|
|
long spot = 0;
|
|
|
|
VARIANT *vArray;
|
|
SafeArrayAccessData(sa, (void**)&vArray);
|
|
|
|
// write Auth cookies
|
|
CComBSTR bstrNewAuth;
|
|
CComBSTR bstrNewSecAuth;
|
|
|
|
BSTR auth, secAuth; // do not call SysFreeString on them, they are skin level copy
|
|
|
|
if (S_OK == IfAlterAuthCookie(&bstrNewAuth, &bstrNewSecAuth))
|
|
{
|
|
auth = bstrNewAuth;
|
|
secAuth = bstrNewSecAuth;
|
|
}
|
|
else
|
|
{
|
|
auth = bstrAuth;
|
|
secAuth = NULL;
|
|
}
|
|
|
|
|
|
domain = m_pRegistryConfig->getTicketDomain();
|
|
|
|
// add MSPAuth
|
|
if (domain.length())
|
|
{
|
|
bufSize = _snwprintf(buf, 4096,
|
|
L"Set-Cookie: MSPAuth=%s; path=%s; domain=%s; %s\r\n",
|
|
(LPWSTR)auth, (LPWSTR)path, (LPWSTR)domain,
|
|
persist ? L"expires=Mon 1-Jan-2035 12:00:00 GMT;" : L"");
|
|
}
|
|
else
|
|
{
|
|
bufSize = _snwprintf(buf, 4096,
|
|
L"Set-Cookie: MSPAuth=%s; path=%s; %s\r\n",
|
|
(LPWSTR)auth, (LPWSTR)path,
|
|
persist ? L"expires=Mon 1-Jan-2035 12:00:00 GMT;" : L"");
|
|
}
|
|
vArray[spot].vt = VT_BSTR;
|
|
vArray[spot].bstrVal = ALLOC_AND_GIVEAWAY_BSTR_LEN(buf, bufSize);
|
|
spot++;
|
|
|
|
// add MSPSecAuth
|
|
if (m_bSecureTransported)
|
|
{
|
|
if (domain.length())
|
|
{
|
|
bufSize = _snwprintf(buf, 4096,
|
|
L"Set-Cookie: MSPSecAuth=%s; path=%s; domain=%s; %s; secure\r\n",
|
|
(LPWSTR)secAuth, (LPWSTR)path, (LPWSTR)domain,
|
|
persist ? L"expires=Mon 1-Jan-2035 12:00:00 GMT;" : L"");
|
|
}
|
|
else
|
|
{
|
|
bufSize = _snwprintf(buf, 4096,
|
|
L"Set-Cookie: MSPSecAuth=%s; path=%s; %s; secure\r\n",
|
|
(LPWSTR)secAuth, (LPWSTR)path,
|
|
persist ? L"expires=Mon 1-Jan-2035 12:00:00 GMT;" : L"");
|
|
}
|
|
vArray[spot].vt = VT_BSTR;
|
|
vArray[spot].bstrVal = ALLOC_AND_GIVEAWAY_BSTR_LEN(buf, bufSize);
|
|
spot++;
|
|
}
|
|
|
|
|
|
if (domain.length())
|
|
{
|
|
bufSize = _snwprintf(buf, 4096,
|
|
L"Set-Cookie: MSPProf=%s; path=%s; domain=%s; %s\r\n",
|
|
(LPWSTR)bstrProf, (LPWSTR)path, (LPWSTR)domain,
|
|
persist ? L"expires=Mon 1-Jan-2035 12:00:00 GMT;" : L"");
|
|
}
|
|
else
|
|
{
|
|
bufSize = _snwprintf(buf, 4096,
|
|
L"Set-Cookie: MSPProf=%s; path=%s; %s\r\n",
|
|
(LPWSTR)bstrProf, (LPWSTR)path,
|
|
persist ? L"expires=Mon 1-Jan-2035 12:00:00 GMT;" : L"");
|
|
}
|
|
vArray[spot].vt = VT_BSTR;
|
|
vArray[spot].bstrVal = ALLOC_AND_GIVEAWAY_BSTR_LEN(buf, bufSize);
|
|
spot++;
|
|
|
|
if(bSetConsent)
|
|
{
|
|
if (m_pRegistryConfig->getProfilePath())
|
|
path = m_pRegistryConfig->getProfilePath();
|
|
else
|
|
path = L"/";
|
|
domain = m_pRegistryConfig->getProfileDomain();
|
|
|
|
if (domain.length())
|
|
{
|
|
bufSize = _snwprintf(buf, 4096,
|
|
L"Set-Cookie: MSPConsent=%s; path=%s; domain=%s; %s\r\n",
|
|
bSetConsent ? (LPWSTR)bstrConsent : L"", (LPWSTR)path, (LPWSTR)domain,
|
|
bSetConsent ? (persist ? L"expires=Mon 1-Jan-2035 12:00:00 GMT;" : L"")
|
|
: L"expires=Tue 1-Jan-1980 12:00:00 GMT;");
|
|
}
|
|
else
|
|
{
|
|
bufSize = _snwprintf(buf, 4096,
|
|
L"Set-Cookie: MSPConsent=%s; path=%s; %s\r\n",
|
|
bSetConsent ? (LPWSTR)bstrConsent : L"", (LPWSTR)path,
|
|
bSetConsent ? (persist ? L"expires=Mon 1-Jan-2035 12:00:00 GMT;" : L"")
|
|
: L"expires=Tue 1-Jan-1980 12:00:00 GMT;");
|
|
}
|
|
vArray[spot].vt = VT_BSTR;
|
|
vArray[spot].bstrVal = ALLOC_AND_GIVEAWAY_BSTR_LEN(buf, bufSize);
|
|
spot++;
|
|
}
|
|
|
|
SafeArrayUnaccessData(sa);
|
|
}
|
|
}
|
|
|
|
// Now, check the cookies
|
|
if (!m_fromQueryString)
|
|
{
|
|
hasSec = GetBstrArg(mspsec, &bstrSec);
|
|
if(hasSec == CV_DEFAULT || hasSec == CV_BAD)
|
|
bstrSec = NULL;
|
|
|
|
handleCookieData(mspauth, mspprof, mspconsent, bstrSec);
|
|
|
|
if(hasSec == CV_FREE)
|
|
SysFreeString(bstrSec);
|
|
}
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::OnStartPageManual, Exit");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CManager::OnStartPageECB(
|
|
LPBYTE pvECB,
|
|
DWORD* bufSize,
|
|
LPSTR pCookieHeader
|
|
)
|
|
{
|
|
char buffer[2048];
|
|
DWORD dwSize;
|
|
EXTENSION_CONTROL_BLOCK* pECB = (EXTENSION_CONTROL_BLOCK*) pvECB;
|
|
LPSTR pBuffer;
|
|
LPSTR pHTTPS;
|
|
|
|
USES_CONVERSION;
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::OnStartPageECB, Enter");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
if (bufSize == NULL)
|
|
return E_POINTER;
|
|
|
|
if (!m_valid || !g_config->isValid()) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
wipeState();
|
|
m_pECB = pECB;
|
|
|
|
//
|
|
// Use the ECB to get the server name being requested
|
|
// so we can get the correct registry config. But only do this
|
|
// if we have some configured sites.
|
|
//
|
|
|
|
if(g_config->HasSites())
|
|
{
|
|
dwSize = sizeof(buffer);
|
|
GetSiteNameECB(pECB, buffer, &dwSize);
|
|
|
|
if(m_pRegistryConfig)
|
|
m_pRegistryConfig->Release();
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig(buffer);
|
|
}
|
|
else
|
|
{
|
|
if(m_pRegistryConfig)
|
|
m_pRegistryConfig->Release();
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
}
|
|
|
|
*pCookieHeader = '\0';
|
|
|
|
// see if client understands passport
|
|
pBuffer = GetServerVariableECB(pECB, "HTTP_Accept-Auth");
|
|
if (pBuffer)
|
|
{
|
|
if (strstr(pBuffer, PASSPORT_PROT14_A))
|
|
m_bIsTweenerCapable = TRUE;
|
|
|
|
delete pBuffer;
|
|
}
|
|
|
|
BSTR ret = NULL;
|
|
CCoCrypt* crypt = NULL;
|
|
|
|
BOOL fParseSuccess = FALSE;
|
|
pBuffer = GetServerVariableECB(pECB, "HTTP_Authorization");
|
|
PWSTR pwszTicket = NULL, pwszProfile = NULL, pwszF = NULL;
|
|
// use these when t&p come from qs
|
|
BSTR a = NULL, p = NULL, f = NULL;
|
|
if (pBuffer && !strstr(pBuffer, PASSPORT_PROT14_A))
|
|
{
|
|
// not our header. BUGBUG could there be multiple headers ???
|
|
delete pBuffer;
|
|
pBuffer = NULL;
|
|
|
|
}
|
|
if (!pBuffer)
|
|
{
|
|
// an old client, let's try the QS
|
|
pBuffer = GetServerVariableECB(pECB, "QUERY_STRING");
|
|
if (pBuffer)
|
|
{
|
|
// get ticket and profile ...
|
|
// BUGBUG This could be optimized to avoid wide/short conversions, but later...
|
|
GetQueryData(pBuffer, &a, &p, &f);
|
|
TAKEOVER_BSTR(a);
|
|
TAKEOVER_BSTR(p);
|
|
TAKEOVER_BSTR(f);
|
|
fParseSuccess = handleQueryStringData(a,p);
|
|
if(f != NULL)
|
|
m_lNetworkError = _wtol(f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// convert to wide ...
|
|
PWSTR pwBuf = new WCHAR[strlen(pBuffer) + 1];
|
|
if (pwBuf)
|
|
{
|
|
wsprintfW(pwBuf, L"%S", pBuffer);
|
|
delete pBuffer;
|
|
// transfer the ptr ...
|
|
pBuffer = (PSTR)pwBuf;
|
|
GetTicketAndProfileFromHeader(pwBuf, pwszTicket, pwszProfile, pwszF);
|
|
fParseSuccess = handleQueryStringData(pwszTicket,pwszProfile);
|
|
if (pwszF)
|
|
m_lNetworkError = _wtol(f);
|
|
}
|
|
}
|
|
if (pBuffer)
|
|
{
|
|
if (fParseSuccess)
|
|
{
|
|
//
|
|
// If we got secure ticket or profile, then
|
|
// we need to re-encrypt the insecure version
|
|
// before setting the cookie headers.
|
|
//
|
|
|
|
// Set the cookies
|
|
LPSTR ticketDomain = m_pRegistryConfig->getTicketDomain();
|
|
LPSTR profileDomain = m_pRegistryConfig->getProfileDomain();
|
|
LPSTR secureDomain = m_pRegistryConfig->getSecureDomain();
|
|
LPSTR ticketPath = m_pRegistryConfig->getTicketPath();
|
|
LPSTR profilePath = m_pRegistryConfig->getProfilePath();
|
|
LPSTR securePath = m_pRegistryConfig->getSecurePath();
|
|
VARIANT_BOOL persist;
|
|
m_piTicket->get_HasSavedPassword(&persist);
|
|
|
|
//
|
|
// If we have a secure ticket/profile and the url is SSL,
|
|
// then tack on the MSPPuid cookie.
|
|
//
|
|
|
|
BSTR s = NULL;
|
|
pHTTPS = GetServerVariableECB(pECB, "HTTPS");
|
|
|
|
if(pHTTPS && lstrcmpiA("on", pHTTPS) == 0)
|
|
m_bSecureTransported = true;
|
|
else
|
|
m_bSecureTransported = false;
|
|
|
|
if(pHTTPS != NULL)
|
|
{
|
|
delete [] pHTTPS;
|
|
}
|
|
|
|
// 5709: Get flags and check to see if the tertiary bit is
|
|
// on. If so, pass this fact into BuildCookieHeaders so that
|
|
// the MSPProfC cookie can be set.
|
|
|
|
CComBSTR bstrConsent;
|
|
BOOL bSetConsent = (S_OK == IfConsentCookie(&bstrConsent));
|
|
|
|
// Build the cookie headers.
|
|
|
|
// the authentication cookies
|
|
CComBSTR bstrNewAuth;
|
|
CComBSTR bstrNewSecAuth;
|
|
|
|
BSTR auth, secAuth; // do not call SysFreeString on them, they are skin level copy
|
|
|
|
if (S_OK == IfAlterAuthCookie(&bstrNewAuth, &bstrNewSecAuth))
|
|
{
|
|
auth = bstrNewAuth;
|
|
secAuth = bstrNewSecAuth;
|
|
}
|
|
else
|
|
{
|
|
auth = a;
|
|
secAuth = NULL;
|
|
}
|
|
|
|
BuildCookieHeaders((pwszTicket ? W2A(pwszTicket) : W2A(auth)),
|
|
(pwszProfile ? W2A(pwszProfile) : (p ? W2A(p) : NULL)),
|
|
(bSetConsent ? W2A(bstrConsent) : NULL),
|
|
(secAuth ? W2A(secAuth) : NULL),
|
|
ticketDomain,
|
|
ticketPath,
|
|
profileDomain,
|
|
profilePath,
|
|
secureDomain,
|
|
securePath,
|
|
persist,
|
|
pCookieHeader,
|
|
bufSize);
|
|
|
|
FREE_BSTR(s);
|
|
}
|
|
|
|
if (a) FREE_BSTR(a);
|
|
if (p) FREE_BSTR(p);
|
|
if (f) FREE_BSTR(f);
|
|
delete [] pBuffer;
|
|
}
|
|
|
|
// Now, check the cookies
|
|
if (!m_fromQueryString)
|
|
{
|
|
BSTR a = NULL, p = NULL, c = NULL, s = NULL;
|
|
if((pBuffer = GetServerVariableECB(pECB, "HTTP_COOKIE")) != NULL)
|
|
{
|
|
GetCookie(pBuffer, "MSPAuth", &a);
|
|
GetCookie(pBuffer, "MSPProf", &p);
|
|
GetCookie(pBuffer, "MSPConsent", &c);
|
|
GetCookie(pBuffer, "MSPSecAuth", &s);
|
|
|
|
TAKEOVER_BSTR(a);
|
|
if(p) { TAKEOVER_BSTR(p); }
|
|
if(c) { TAKEOVER_BSTR(c); }
|
|
if(s) { TAKEOVER_BSTR(s); }
|
|
|
|
handleCookieData(a,p,c,s);
|
|
|
|
if (a) FREE_BSTR(a);
|
|
if (p) FREE_BSTR(p);
|
|
if (c) FREE_BSTR(c);
|
|
if (s) FREE_BSTR(s);
|
|
|
|
delete [] pBuffer;
|
|
}
|
|
}
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::OnStartPageECB, Exit");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CManager::OnStartPageFilter(
|
|
LPBYTE pvPFC,
|
|
DWORD* bufSize,
|
|
LPSTR pCookieHeader
|
|
)
|
|
{
|
|
char buffer[2048];
|
|
DWORD dwSize;
|
|
PHTTP_FILTER_CONTEXT pfc = (PHTTP_FILTER_CONTEXT) pvPFC;
|
|
LPSTR pBuffer = NULL;
|
|
LPSTR pHTTPS;
|
|
|
|
// initialize
|
|
*bufSize = 0;
|
|
|
|
USES_CONVERSION;
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::OnStartPageFilter, Enter");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
if (!m_valid || !g_config->isValid()) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
|
|
wipeState();
|
|
|
|
//
|
|
// Use the ECB to get the server name being requested
|
|
// so we can get the correct registry config. But only do this
|
|
// if we have some configured sites.
|
|
//
|
|
|
|
if(g_config->HasSites())
|
|
{
|
|
dwSize = sizeof(buffer);
|
|
GetSiteNamePFC(pfc, buffer, &dwSize);
|
|
|
|
if(m_pRegistryConfig)
|
|
m_pRegistryConfig->Release();
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig(buffer);
|
|
}
|
|
else
|
|
{
|
|
if(m_pRegistryConfig)
|
|
m_pRegistryConfig->Release();
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
}
|
|
|
|
*pCookieHeader = '\0';
|
|
|
|
// store the filter context
|
|
m_pFC = pfc;
|
|
|
|
// see if the client "knows" tweener
|
|
PSTR pHeader = GetServerVariablePFC(pfc, "HTTP_Accept-Auth");
|
|
if (pHeader)
|
|
{
|
|
// does it know passport1.4?
|
|
if (strstr(pHeader, PASSPORT_PROT14_A))
|
|
{
|
|
m_bIsTweenerCapable = TRUE;
|
|
}
|
|
delete pHeader;
|
|
}
|
|
|
|
// check the auth header
|
|
BOOL fParseSuccess = FALSE;
|
|
PWSTR pwszTicket = NULL, pwszProfile = NULL, pwszF = NULL;
|
|
|
|
pHeader = GetServerVariablePFC(pfc, "HTTP_Authorization");
|
|
if (pHeader)
|
|
{
|
|
if (!strncmp(pHeader, PASSPORT_PROT14_A, strlen(PASSPORT_PROT14_A)))
|
|
{
|
|
// this is our header ....
|
|
// extract ticket and profile
|
|
PWSTR pwBuf = new WCHAR[strlen(pHeader) + 1];
|
|
if (pwBuf)
|
|
{
|
|
wsprintfW(pwBuf, L"%S", pHeader);
|
|
delete pHeader;
|
|
// transfer the ptr ...
|
|
pBuffer = (PSTR)pwBuf;
|
|
GetTicketAndProfileFromHeader(pwBuf, pwszTicket, pwszProfile, pwszF);
|
|
fParseSuccess = handleQueryStringData(pwszTicket,pwszProfile);
|
|
if (pwszF)
|
|
m_lNetworkError = _wtol(pwszF);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
delete pHeader;
|
|
pHeader = NULL;
|
|
}
|
|
}
|
|
|
|
BSTR a = NULL, p = NULL, f = NULL;
|
|
if (!pBuffer && (pBuffer = GetServerVariablePFC(pfc, "QUERY_STRING")) != NULL)
|
|
{
|
|
// Then, check the query string
|
|
// BUGBUG This could be optimized to avoid wide/short conversions, but later...
|
|
GetQueryData(pBuffer, &a, &p, &f);
|
|
TAKEOVER_BSTR(a);
|
|
TAKEOVER_BSTR(p);
|
|
TAKEOVER_BSTR(f);
|
|
fParseSuccess = handleQueryStringData(a,p);
|
|
if(f != NULL)
|
|
m_lNetworkError = _wtol(f);
|
|
}
|
|
BSTR ret = NULL;
|
|
CCoCrypt* crypt = NULL;
|
|
|
|
if (fParseSuccess)
|
|
{
|
|
// Set the cookies
|
|
LPSTR ticketDomain = m_pRegistryConfig->getTicketDomain();
|
|
LPSTR profileDomain = m_pRegistryConfig->getProfileDomain();
|
|
LPSTR secureDomain = m_pRegistryConfig->getSecureDomain();
|
|
LPSTR ticketPath = m_pRegistryConfig->getTicketPath();
|
|
LPSTR profilePath = m_pRegistryConfig->getProfilePath();
|
|
LPSTR securePath = m_pRegistryConfig->getSecurePath();
|
|
VARIANT_BOOL persist;
|
|
m_piTicket->get_HasSavedPassword(&persist);
|
|
|
|
//
|
|
// If we have a secure ticket/profile and the url is SSL,
|
|
// then tack on the MSPPuid cookie.
|
|
//
|
|
|
|
BSTR s = NULL;
|
|
pHTTPS = GetServerVariablePFC(pfc, "HTTPS");
|
|
|
|
if(pHTTPS && lstrcmpiA("on", pHTTPS) == 0)
|
|
m_bSecureTransported = true;
|
|
else
|
|
m_bSecureTransported = false;
|
|
|
|
if(pHTTPS != NULL)
|
|
{
|
|
delete [] pHTTPS;
|
|
}
|
|
|
|
// 5709: Get flags and check to see if the tertiary bit is
|
|
// on. If so, pass this fact into BuildCookieHeaders so that
|
|
// the MSPProfC cookie can be set.
|
|
|
|
CComBSTR bstrConsent;
|
|
BOOL bSetConsent = (S_OK == IfConsentCookie(&bstrConsent));
|
|
|
|
// Build the cookie headers.
|
|
|
|
// the authentication cookies
|
|
CComBSTR bstrNewAuth;
|
|
CComBSTR bstrNewSecAuth;
|
|
|
|
BSTR auth, secAuth; // do not call SysFreeString on them, they are skin level copy
|
|
|
|
if (S_OK == IfAlterAuthCookie(&bstrNewAuth, &bstrNewSecAuth))
|
|
{
|
|
auth = bstrNewAuth;
|
|
secAuth = bstrNewSecAuth;
|
|
}
|
|
else
|
|
{
|
|
auth = a;
|
|
secAuth = NULL;
|
|
}
|
|
|
|
|
|
BuildCookieHeaders(pwszTicket ? W2A(pwszTicket) : W2A(auth),
|
|
pwszProfile ? W2A(pwszProfile) : (p ? W2A(p) : NULL),
|
|
(bSetConsent ? W2A(bstrConsent) : NULL),
|
|
(secAuth ? W2A(secAuth) : NULL),
|
|
ticketDomain,
|
|
ticketPath,
|
|
profileDomain,
|
|
profilePath,
|
|
secureDomain,
|
|
securePath,
|
|
persist,
|
|
pCookieHeader,
|
|
bufSize);
|
|
|
|
FREE_BSTR(s);
|
|
}
|
|
if (a) FREE_BSTR(a);
|
|
if (p) FREE_BSTR(p);
|
|
if (f) FREE_BSTR(f);
|
|
|
|
if (pBuffer)
|
|
delete pBuffer;
|
|
|
|
// Now, check the cookies
|
|
if (!m_fromQueryString)
|
|
{
|
|
BSTR a = NULL, p = NULL, c = NULL, s = NULL;
|
|
if((pBuffer = GetServerVariablePFC(pfc, "HTTP_COOKIE")) != NULL)
|
|
{
|
|
GetCookie(pBuffer, "MSPAuth", &a);
|
|
GetCookie(pBuffer, "MSPProf", &p);
|
|
GetCookie(pBuffer, "MSPConsent", &c);
|
|
GetCookie(pBuffer, "MSPSecAuth", &s);
|
|
|
|
if(a) { TAKEOVER_BSTR(a); }
|
|
if(p) { TAKEOVER_BSTR(p); }
|
|
if(c) { TAKEOVER_BSTR(c); }
|
|
if(s) { TAKEOVER_BSTR(s); }
|
|
|
|
handleCookieData(a,p,c,s);
|
|
|
|
if (a) FREE_BSTR(a);
|
|
if (p) FREE_BSTR(p);
|
|
if (c) FREE_BSTR(c);
|
|
if (s) FREE_BSTR(s);
|
|
|
|
delete [] pBuffer;
|
|
}
|
|
|
|
}
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::OnStartPageFilter, Exit");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CManager::OnEndPage ()
|
|
{
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::OnEndPage, Enter");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
if (m_bOnStartPageCalled)
|
|
{
|
|
m_bOnStartPageCalled = false;
|
|
// Release all interfaces
|
|
m_piRequest.Release();
|
|
m_piResponse.Release();
|
|
}
|
|
|
|
// Just in case...
|
|
m_piTicket->put_unencryptedTicket(NULL);
|
|
m_piProfile->put_unencryptedProfile(NULL);
|
|
m_profileValid = m_ticketValid = VARIANT_FALSE;
|
|
m_fromQueryString = false;
|
|
|
|
if(m_pRegistryConfig)
|
|
{
|
|
m_pRegistryConfig->Release();
|
|
m_pRegistryConfig = NULL;
|
|
}
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::OnEndPage, Exit");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//
|
|
// Old API. Auth URL is pointing to the login server
|
|
//
|
|
STDMETHODIMP
|
|
CManager::AuthURL(
|
|
VARIANT vRU,
|
|
VARIANT vTimeWindow,
|
|
VARIANT vForceLogin,
|
|
VARIANT vCoBrand,
|
|
VARIANT vLCID,
|
|
VARIANT vNameSpace,
|
|
VARIANT vKPP,
|
|
VARIANT vUseSecureAuth,
|
|
BSTR *pAuthUrl)
|
|
{
|
|
CComVariant vEmpty("");
|
|
return CommonAuthURL(vRU, vTimeWindow, vForceLogin,
|
|
vCoBrand, vLCID, vNameSpace,
|
|
vKPP, vUseSecureAuth,
|
|
FALSE, vEmpty, pAuthUrl);
|
|
|
|
}
|
|
|
|
//
|
|
// new API. return URL is to the login server
|
|
//
|
|
STDMETHODIMP
|
|
CManager::AuthURL2(
|
|
VARIANT vRU,
|
|
VARIANT vTimeWindow,
|
|
VARIANT vForceLogin,
|
|
VARIANT vCoBrand,
|
|
VARIANT vLCID,
|
|
VARIANT vNameSpace,
|
|
VARIANT vKPP,
|
|
VARIANT vUseSecureAuth,
|
|
BSTR *pAuthUrl)
|
|
{
|
|
CComVariant vEmpty("");
|
|
return CommonAuthURL(vRU, vTimeWindow, vForceLogin,
|
|
vCoBrand, vLCID, vNameSpace,
|
|
vKPP, vUseSecureAuth,
|
|
TRUE, vEmpty, pAuthUrl);
|
|
|
|
}
|
|
|
|
//
|
|
// AuthURL implementation
|
|
//
|
|
STDMETHODIMP
|
|
CManager::CommonAuthURL(
|
|
VARIANT vRU,
|
|
VARIANT vTimeWindow,
|
|
VARIANT vForceLogin,
|
|
VARIANT vCoBrand,
|
|
VARIANT vLCID,
|
|
VARIANT vNameSpace,
|
|
VARIANT vKPP,
|
|
VARIANT vUseSecureAuth,
|
|
BOOL fRedirToSelf,
|
|
VARIANT vFunctionArea, // BSTR: e.g. Wireless
|
|
BSTR *pAuthUrl)
|
|
{
|
|
USES_CONVERSION;
|
|
time_t ct;
|
|
WCHAR url[MAX_URL_LENGTH] = L"";
|
|
VARIANT freeMe;
|
|
UINT TimeWindow;
|
|
int nKPP;
|
|
VARIANT_BOOL ForceLogin = VARIANT_FALSE;
|
|
ULONG ulSecureLevel = 0;
|
|
//!!! ? bstrNameSpace seems leaking memory, should we change all to CComBSTR ...
|
|
BSTR CBT = NULL, returnUrl = NULL, bstrNameSpace = NULL;
|
|
int hasCB, hasRU, hasLCID, hasTW, hasFL, hasNameSpace, hasKPP, hasUseSec;
|
|
USHORT Lang;
|
|
HRESULT hr = S_OK;
|
|
|
|
BSTR bstrFunctionArea = NULL;
|
|
int hasFunctionArea;
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
char szLogString[LOG_STRING_LEN] = "CManager::AuthURL, Enter";
|
|
AddVariantAsString(vRU, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(vTimeWindow, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(vForceLogin, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(vCoBrand, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(vLCID, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(vNameSpace, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
if (!m_pRegistryConfig)
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
|
|
if (!m_valid || !g_config->isValid() || !m_pRegistryConfig) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
// Make sure args are of the right type
|
|
if ((hasTW = GetIntArg(vTimeWindow, (int*) &TimeWindow)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if ((hasFL = GetBoolArg(vForceLogin, &ForceLogin)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if ((hasUseSec = GetIntArg(vUseSecureAuth, (int*)&ulSecureLevel)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if ((hasLCID = GetShortArg(vLCID,&Lang)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if ((hasKPP = GetIntArg(vKPP, &nKPP)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
hasCB = GetBstrArg(vCoBrand, &CBT);
|
|
if (hasCB == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if (hasCB == CV_FREE)
|
|
{
|
|
TAKEOVER_BSTR(CBT);
|
|
}
|
|
|
|
hasRU = GetBstrArg(vRU, &returnUrl);
|
|
if (hasRU == CV_BAD)
|
|
{
|
|
if (hasCB == CV_FREE && CBT) FREE_BSTR(CBT);
|
|
return E_INVALIDARG;
|
|
}
|
|
if (hasRU == CV_FREE)
|
|
{
|
|
TAKEOVER_BSTR(returnUrl);
|
|
}
|
|
|
|
hasNameSpace = GetBstrArg(vNameSpace, &bstrNameSpace);
|
|
if (hasNameSpace == CV_BAD)
|
|
{
|
|
if (hasCB == CV_FREE && CBT) SysFreeString(CBT);
|
|
if (hasRU == CV_FREE && returnUrl) SysFreeString(returnUrl);
|
|
return E_INVALIDARG;
|
|
}
|
|
if (hasNameSpace == CV_FREE)
|
|
{
|
|
TAKEOVER_BSTR(bstrNameSpace);
|
|
|
|
//!!! ? does it take care of memory leak? ...
|
|
}
|
|
|
|
hasFunctionArea = GetBstrArg(vFunctionArea, &bstrFunctionArea);
|
|
if (hasFunctionArea == CV_FREE)
|
|
{
|
|
TAKEOVER_BSTR(bstrFunctionArea);
|
|
}
|
|
|
|
WCHAR *szAUAttrName;
|
|
CComBSTR szAttrName_FuncArea = bstrFunctionArea;
|
|
if (hasUseSec == CV_OK && SECURELEVEL_USE_HTTPS(ulSecureLevel))
|
|
szAUAttrName = L"AuthSecure";
|
|
else
|
|
szAUAttrName = L"Auth";
|
|
|
|
if (bstrFunctionArea != NULL)
|
|
szAttrName_FuncArea+= szAUAttrName;
|
|
|
|
CNexusConfig* cnc = g_config->checkoutNexusConfig();
|
|
|
|
if (hasLCID == CV_DEFAULT)
|
|
Lang = m_pRegistryConfig->getDefaultLCID();
|
|
if (hasKPP == CV_DEFAULT)
|
|
nKPP = -1;
|
|
VariantInit(&freeMe);
|
|
|
|
if (!m_pRegistryConfig->DisasterModeP())
|
|
{
|
|
// If I'm authenticated, get my domain specific url
|
|
if (m_ticketValid && m_profileValid)
|
|
{
|
|
HRESULT hr = m_piProfile->get_ByIndex(MEMBERNAME_INDEX, &freeMe);
|
|
if (hr != S_OK || freeMe.vt != VT_BSTR)
|
|
{
|
|
if (bstrFunctionArea)
|
|
{
|
|
cnc->getDomainAttribute(L"Default",
|
|
szAttrName_FuncArea,
|
|
sizeof(url) / sizeof(WCHAR),
|
|
url,
|
|
Lang);
|
|
}
|
|
|
|
if (*url == 0) // nothing is in URL string
|
|
{
|
|
cnc->getDomainAttribute(L"Default",
|
|
szAUAttrName,
|
|
sizeof(url) / sizeof(WCHAR),
|
|
url,
|
|
Lang);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LPCWSTR psz = wcsrchr(freeMe.bstrVal, L'@');
|
|
if (bstrFunctionArea)
|
|
{
|
|
cnc->getDomainAttribute(psz ? psz+1 : L"Default",
|
|
szAttrName_FuncArea,
|
|
sizeof(url) / sizeof(WCHAR),
|
|
url,
|
|
Lang);
|
|
}
|
|
|
|
if (*url == 0) // nothing is in URL string
|
|
{
|
|
cnc->getDomainAttribute(psz ? psz+1 : L"Default",
|
|
szAUAttrName,
|
|
sizeof(url) / sizeof(WCHAR),
|
|
url,
|
|
Lang);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (bstrFunctionArea)
|
|
{
|
|
cnc->getDomainAttribute(L"Default",
|
|
szAttrName_FuncArea,
|
|
sizeof(url) / sizeof(WCHAR),
|
|
url,
|
|
Lang);
|
|
}
|
|
|
|
if(*url == 0) // nothing in URL string
|
|
{
|
|
cnc->getDomainAttribute(L"Default",
|
|
szAUAttrName,
|
|
sizeof(url) / sizeof(WCHAR),
|
|
url,
|
|
Lang);
|
|
|
|
}
|
|
}
|
|
}
|
|
else
|
|
lstrcpynW(url, A2W(m_pRegistryConfig->getDisasterUrl()), sizeof(url) / sizeof(WCHAR));
|
|
|
|
time(&ct);
|
|
|
|
if (*url == L'\0')
|
|
{
|
|
hr = S_OK;
|
|
goto Cleanup;
|
|
}
|
|
|
|
if (hasTW == CV_DEFAULT)
|
|
TimeWindow = m_pRegistryConfig->getDefaultTicketAge();
|
|
if (hasFL == CV_DEFAULT)
|
|
ForceLogin = m_pRegistryConfig->forceLoginP() ? VARIANT_TRUE : VARIANT_FALSE;
|
|
if (hasCB == CV_DEFAULT)
|
|
CBT = m_pRegistryConfig->getDefaultCoBrand();
|
|
if (hasRU == CV_DEFAULT)
|
|
returnUrl = m_pRegistryConfig->getDefaultRU();
|
|
if (returnUrl == NULL)
|
|
returnUrl = L"";
|
|
if(hasUseSec == CV_DEFAULT)
|
|
ulSecureLevel = m_pRegistryConfig->getSecureLevel();
|
|
|
|
if(ulSecureLevel == VARIANT_TRUE) // special case for backward compatible
|
|
ulSecureLevel = k_iSeclevelSecureChannel;
|
|
|
|
if ((TimeWindow != 0 && TimeWindow < PPM_TIMEWINDOW_MIN) || TimeWindow > PPM_TIMEWINDOW_MAX)
|
|
{
|
|
WCHAR buf[20];
|
|
_itow(TimeWindow,buf,10);
|
|
AtlReportError(CLSID_Manager, (LPCOLESTR) PP_E_INVALID_TIMEWINDOWSTR,
|
|
IID_IPassportManager, PP_E_INVALID_TIMEWINDOW);
|
|
hr = PP_E_INVALID_TIMEWINDOW;
|
|
goto Cleanup;
|
|
}
|
|
|
|
*pAuthUrl = FormatAuthURL(
|
|
url,
|
|
m_pRegistryConfig->getSiteId(),
|
|
returnUrl,
|
|
TimeWindow,
|
|
ForceLogin,
|
|
m_pRegistryConfig->getCurrentCryptVersion(),
|
|
ct,
|
|
CBT,
|
|
bstrNameSpace,
|
|
nKPP,
|
|
Lang,
|
|
ulSecureLevel,
|
|
m_pRegistryConfig,
|
|
fRedirToSelf
|
|
);
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
|
|
cnc->Release();
|
|
if (hasFunctionArea== CV_FREE && bstrFunctionArea)
|
|
FREE_BSTR(bstrFunctionArea);
|
|
|
|
if (hasRU == CV_FREE && returnUrl)
|
|
FREE_BSTR(returnUrl);
|
|
|
|
if (hasCB == CV_FREE && CBT)
|
|
FREE_BSTR(CBT);
|
|
|
|
// !!! need to confirmation
|
|
if (hasNameSpace == CV_FREE && bstrNameSpace)
|
|
FREE_BSTR(bstrNameSpace);
|
|
|
|
VariantClear(&freeMe);
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
strcpy(szLogString,"CManager::AuthURL, Exit");
|
|
AddLongAsString(hr, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// get AuthURL and AuthHeaders
|
|
//
|
|
STDMETHODIMP CManager::GetLoginChallenge(VARIANT vReturnUrl,
|
|
VARIANT vTimeWindow,
|
|
VARIANT vForceLogin,
|
|
VARIANT vCoBrandTemplate,
|
|
VARIANT vLCID,
|
|
VARIANT vNameSpace,
|
|
VARIANT vKPP,
|
|
VARIANT vUseSecureAuth,
|
|
VARIANT vExtraParams,
|
|
VARIANT *pAuthHeader,
|
|
BSTR* pAuthVal
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try{
|
|
// format qs and WWW-Authenticate header ....
|
|
_bstr_t strUrl, strRetUrl, strCBT, strNameSpace;
|
|
UINT TimeWindow;
|
|
int nKPP;
|
|
time_t ct;
|
|
VARIANT_BOOL ForceLogin;
|
|
ULONG ulSecureLevel;
|
|
WCHAR rgLCID[10];
|
|
HRESULT hr = GetLoginParams(vReturnUrl,
|
|
vTimeWindow,
|
|
vForceLogin,
|
|
vCoBrandTemplate,
|
|
vLCID,
|
|
vNameSpace,
|
|
vKPP,
|
|
vUseSecureAuth,
|
|
strUrl,
|
|
strRetUrl,
|
|
TimeWindow,
|
|
ForceLogin,
|
|
ct,
|
|
strCBT,
|
|
strNameSpace,
|
|
nKPP,
|
|
ulSecureLevel,
|
|
rgLCID);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
WCHAR szBuf[MAX_QS_LENGTH] = L"";
|
|
// prepare redirect URL to the login server for
|
|
// downlevel clients
|
|
FormatAuthURLParameters(strUrl,
|
|
m_pRegistryConfig->getSiteId(),
|
|
strRetUrl,
|
|
TimeWindow,
|
|
ForceLogin,
|
|
m_pRegistryConfig->getCurrentCryptVersion(),
|
|
ct,
|
|
strCBT,
|
|
strNameSpace,
|
|
nKPP,
|
|
szBuf,
|
|
sizeof(szBuf)/sizeof(WCHAR),
|
|
0, // lang does not matter ....
|
|
ulSecureLevel,
|
|
m_pRegistryConfig,
|
|
FALSE); // do not redirect to self!
|
|
// insert the WWW-Authenticate header ...
|
|
_bstr_t strAuthHeader;
|
|
FormatAuthHeaderFromParams(strUrl,
|
|
strRetUrl,
|
|
TimeWindow,
|
|
ForceLogin,
|
|
ct,
|
|
strCBT,
|
|
strNameSpace,
|
|
nKPP,
|
|
rgLCID,
|
|
ulSecureLevel,
|
|
strAuthHeader);
|
|
// and add the extra ....
|
|
BSTR strExtra = NULL;
|
|
int res = GetBstrArg(vExtraParams, &strExtra);
|
|
if (res != CV_BAD && res != CV_DEFAULT)
|
|
strAuthHeader += _bstr_t(L",") + strExtra;
|
|
|
|
if (res == CV_FREE)
|
|
::SysFreeString(strExtra);
|
|
|
|
|
|
// set return values
|
|
if (pAuthHeader && (WCHAR*)strAuthHeader != NULL)
|
|
{
|
|
V_VT(pAuthHeader) = VT_BSTR;
|
|
// TODO: should avoid this SysAllocString
|
|
V_BSTR(pAuthHeader) = ::SysAllocString((WCHAR*)strAuthHeader);
|
|
}
|
|
|
|
if (pAuthVal)
|
|
*pAuthVal = ::SysAllocString(szBuf);
|
|
|
|
}
|
|
}catch(...)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// client logon method
|
|
//
|
|
STDMETHODIMP CManager::LoginUser(VARIANT vReturnUrl,
|
|
VARIANT vTimeWindow,
|
|
VARIANT vForceLogin,
|
|
VARIANT vCoBrandTemplate,
|
|
VARIANT vLCID,
|
|
VARIANT vNameSpace,
|
|
VARIANT vKPP,
|
|
VARIANT vUseSecureAuth,
|
|
VARIANT vExtraParams)
|
|
{
|
|
// format qs and WWW-Authenticate header ....
|
|
CComBSTR authURL;
|
|
CComVariant authHeader;
|
|
|
|
HRESULT hr = GetLoginChallenge( vReturnUrl,
|
|
vTimeWindow,
|
|
vForceLogin,
|
|
vCoBrandTemplate,
|
|
vLCID,
|
|
vNameSpace,
|
|
vKPP,
|
|
vUseSecureAuth,
|
|
vExtraParams,
|
|
&authHeader,
|
|
&authURL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
_ASSERT(V_VT(&authHeader) == VT_BSTR);
|
|
_ASSERT(authURL);
|
|
_ASSERT(V_BSTR(&authHeader));
|
|
|
|
// TODO: _bstr_t should be removed globaly in ppm
|
|
if (m_piResponse)
|
|
{
|
|
m_piResponse->AddHeader(L"WWW-Authenticate", V_BSTR(&authHeader));
|
|
|
|
_bstr_t authURL1 = authURL;
|
|
|
|
// and redirect!
|
|
if (!m_bIsTweenerCapable)
|
|
m_piResponse->Redirect(authURL1);
|
|
else
|
|
{
|
|
// send a 401
|
|
m_piResponse->put_Status(L"401 Unauthorized");
|
|
m_piResponse->End();
|
|
}
|
|
}
|
|
else if (m_pECB || m_pFC)
|
|
{
|
|
// use ECB of Filter interfaces
|
|
// 4k whould be enough ....
|
|
char buffer[4096],
|
|
status[25] = "302 Object moved",
|
|
*psz=buffer,
|
|
rgszTemplate[] = "Content-Type: text/html\r\nLocation: %ws\r\n"
|
|
"Content-Length: 0\r\n"
|
|
"WWW-Authenticate: %ws\r\n\r\n";
|
|
DWORD cbTotalLength = strlen(rgszTemplate) +
|
|
wcslen(V_BSTR(&authHeader));
|
|
if (m_bIsTweenerCapable)
|
|
strcpy(status, "401 Unauthorized");
|
|
if (cbTotalLength >= sizeof(buffer))
|
|
{
|
|
// if not ...
|
|
// need to alloc
|
|
psz = new CHAR[cbTotalLength];
|
|
_ASSERT(psz);
|
|
}
|
|
|
|
if (psz)
|
|
{
|
|
sprintf(psz,
|
|
rgszTemplate,
|
|
authURL,
|
|
V_BSTR(&authHeader));
|
|
if (m_pECB)
|
|
{
|
|
// extension
|
|
HSE_SEND_HEADER_EX_INFO Headers =
|
|
{
|
|
status,
|
|
buffer,
|
|
strlen(status),
|
|
strlen(buffer),
|
|
TRUE
|
|
};
|
|
m_pECB->ServerSupportFunction(m_pECB->ConnID,
|
|
HSE_REQ_SEND_RESPONSE_HEADER_EX,
|
|
&Headers,
|
|
NULL,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
// filter
|
|
m_pFC->ServerSupportFunction(m_pFC,
|
|
SF_REQ_SEND_RESPONSE_HEADER,
|
|
status,
|
|
(ULONG_PTR) psz,
|
|
NULL);
|
|
}
|
|
|
|
if (psz != buffer)
|
|
// if we had to allocate
|
|
delete psz;
|
|
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP CManager::IsAuthenticated(
|
|
VARIANT vTimeWindow,
|
|
VARIANT vForceLogin,
|
|
VARIANT vCheckSecure,
|
|
VARIANT_BOOL *pVal)
|
|
{
|
|
HRESULT hr;
|
|
ULONG TimeWindow;
|
|
VARIANT_BOOL ForceLogin;
|
|
ATL::CComVariant vSecureLevel;
|
|
ULONG ulSecureLevel;
|
|
int hasTW, hasFL, hasSecureLevel;
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
char szLogString[LOG_STRING_LEN] = "CManager::IsAuthenticated, Enter";
|
|
AddVariantAsString(vTimeWindow, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(vForceLogin, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
if (!m_pRegistryConfig)
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
|
|
if (!g_config->isValid() || !m_pRegistryConfig) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
hr = PP_E_NOT_CONFIGURED;
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Both profile AND ticket must be valid to be authenticated
|
|
// DARRENAN - As of 1.3 no longer true!!!
|
|
/*if (!m_profileValid)
|
|
{
|
|
*pVal = VARIANT_FALSE;
|
|
hr = S_OK;
|
|
goto Cleanup;
|
|
}
|
|
*/
|
|
|
|
if ((hasTW = GetIntArg(vTimeWindow,(int*)&TimeWindow)) == CV_BAD)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto Cleanup;
|
|
}
|
|
if (hasTW == CV_DEFAULT)
|
|
TimeWindow = m_pRegistryConfig->getDefaultTicketAge();
|
|
|
|
if ((hasFL = GetBoolArg(vForceLogin, &ForceLogin)) == CV_BAD)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto Cleanup;
|
|
}
|
|
if (hasFL == CV_DEFAULT)
|
|
ForceLogin = m_pRegistryConfig->forceLoginP() ? VARIANT_TRUE : VARIANT_FALSE;
|
|
|
|
hasSecureLevel = GetIntArg(vCheckSecure, (int*)&ulSecureLevel);
|
|
if(hasSecureLevel == CV_BAD) // try the legacy type VT_BOOL, map VARIANT_TRUE to SecureChannel
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto Cleanup;
|
|
}
|
|
else if (hasSecureLevel == CV_DEFAULT)
|
|
{
|
|
ulSecureLevel = m_pRegistryConfig->getSecureLevel();
|
|
}
|
|
|
|
if(ulSecureLevel == VARIANT_TRUE)// backward compatible with 1.3X
|
|
{
|
|
ulSecureLevel = k_iSeclevelSecureChannel;
|
|
}
|
|
|
|
vSecureLevel = ulSecureLevel;
|
|
|
|
hr = m_piTicket->get_IsAuthenticated(TimeWindow, ForceLogin, vSecureLevel, pVal);
|
|
|
|
Cleanup:
|
|
|
|
if(g_pPerf)
|
|
{
|
|
if (*pVal)
|
|
{
|
|
g_pPerf->incrementCounter(PM_AUTHSUCCESS_TOTAL);
|
|
g_pPerf->incrementCounter(PM_AUTHSUCCESS_SEC);
|
|
}
|
|
else
|
|
{
|
|
g_pPerf->incrementCounter(PM_AUTHFAILURE_TOTAL);
|
|
g_pPerf->incrementCounter(PM_AUTHFAILURE_SEC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(g_pPerf);
|
|
}
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
strcpy(szLogString, "CManager::IsAuthenticated, Exit");
|
|
AddLongAsString(hr, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// old PM API. The URL is pointing to login server
|
|
//
|
|
STDMETHODIMP
|
|
CManager::LogoTag(
|
|
VARIANT vRU,
|
|
VARIANT vTimeWindow,
|
|
VARIANT vForceLogin,
|
|
VARIANT vCoBrand,
|
|
VARIANT vLCID,
|
|
VARIANT vSecure,
|
|
VARIANT vNameSpace,
|
|
VARIANT vKPP,
|
|
VARIANT vUseSecureAuth,
|
|
BSTR *pVal)
|
|
{
|
|
return CommonLogoTag(vRU, vTimeWindow, vForceLogin,
|
|
vCoBrand, vLCID, vSecure,
|
|
vNameSpace, vKPP, vUseSecureAuth,
|
|
FALSE, pVal);
|
|
}
|
|
|
|
//
|
|
// new PM API. The URL is pointing to the partner site
|
|
//
|
|
STDMETHODIMP
|
|
CManager::LogoTag2(
|
|
VARIANT vRU,
|
|
VARIANT vTimeWindow,
|
|
VARIANT vForceLogin,
|
|
VARIANT vCoBrand,
|
|
VARIANT vLCID,
|
|
VARIANT vSecure,
|
|
VARIANT vNameSpace,
|
|
VARIANT vKPP,
|
|
VARIANT vUseSecureAuth,
|
|
BSTR *pVal)
|
|
{
|
|
return CommonLogoTag(vRU, vTimeWindow, vForceLogin,
|
|
vCoBrand, vLCID, vSecure,
|
|
vNameSpace, vKPP, vUseSecureAuth,
|
|
TRUE, pVal);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CManager::CommonLogoTag(
|
|
VARIANT vRU,
|
|
VARIANT vTimeWindow,
|
|
VARIANT vForceLogin,
|
|
VARIANT vCoBrand,
|
|
VARIANT vLCID,
|
|
VARIANT vSecure,
|
|
VARIANT vNameSpace,
|
|
VARIANT vKPP,
|
|
VARIANT vUseSecureAuth,
|
|
BOOL fRedirToSelf,
|
|
BSTR *pVal)
|
|
{
|
|
time_t ct;
|
|
ULONG TimeWindow;
|
|
int nKPP;
|
|
VARIANT_BOOL ForceLogin, bSecure = VARIANT_FALSE;
|
|
ULONG ulSecureLevel = 0;
|
|
BSTR CBT = NULL, returnUrl = NULL, NameSpace = NULL;
|
|
int hasCB, hasRU, hasLCID, hasTW, hasFL, hasSec, hasUseSec, hasNameSpace, hasKPP;
|
|
USHORT Lang;
|
|
|
|
USES_CONVERSION;
|
|
|
|
time(&ct);
|
|
|
|
if (!m_pRegistryConfig)
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
|
|
if (!m_valid || !g_config->isValid() || !m_pRegistryConfig) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
// Make sure args are of the right type
|
|
if ((hasTW = GetIntArg(vTimeWindow, (int*) &TimeWindow)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if ((hasFL = GetBoolArg(vForceLogin, &ForceLogin)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if ((hasSec = GetBoolArg(vSecure,&bSecure)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
|
|
// FUTURE: should introduce a new func: GetLongArg ...
|
|
if ((hasUseSec = GetIntArg(vUseSecureAuth,(int*)&ulSecureLevel)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
|
|
if ((hasLCID = GetShortArg(vLCID,&Lang)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if ((hasKPP = GetIntArg(vKPP, &nKPP)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
hasCB = GetBstrArg(vCoBrand, &CBT);
|
|
if (hasCB == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if (hasCB == CV_FREE) { TAKEOVER_BSTR(CBT); }
|
|
hasRU = GetBstrArg(vRU, &returnUrl);
|
|
if (hasRU == CV_BAD)
|
|
{
|
|
if (hasCB == CV_FREE && CBT) SysFreeString(CBT);
|
|
return E_INVALIDARG;
|
|
}
|
|
if (hasRU == CV_FREE) { TAKEOVER_BSTR(returnUrl); }
|
|
|
|
hasNameSpace = GetBstrArg(vNameSpace, &NameSpace);
|
|
if (hasNameSpace == CV_BAD)
|
|
{
|
|
if (hasCB == CV_FREE && CBT) SysFreeString(CBT);
|
|
if (hasRU == CV_FREE && returnUrl) SysFreeString(returnUrl);
|
|
return E_INVALIDARG;
|
|
}
|
|
if (hasNameSpace == CV_FREE) { TAKEOVER_BSTR(NameSpace); }
|
|
|
|
|
|
WCHAR *szSIAttrName, *szSOAttrName;
|
|
if (hasSec == CV_OK && bSecure == VARIANT_TRUE)
|
|
{
|
|
szSIAttrName = L"SecureSigninLogo";
|
|
szSOAttrName = L"SecureSignoutLogo";
|
|
}
|
|
else
|
|
{
|
|
szSIAttrName = L"SigninLogo";
|
|
szSOAttrName = L"SignoutLogo";
|
|
}
|
|
|
|
WCHAR *szAUAttrName;
|
|
if (hasUseSec == CV_OK && SECURELEVEL_USE_HTTPS(ulSecureLevel))
|
|
szAUAttrName = L"AuthSecure";
|
|
else
|
|
szAUAttrName = L"Auth";
|
|
|
|
CNexusConfig* cnc = g_config->checkoutNexusConfig();
|
|
|
|
if (hasLCID == CV_DEFAULT)
|
|
Lang = m_pRegistryConfig->getDefaultLCID();
|
|
|
|
if (hasTW == CV_DEFAULT)
|
|
TimeWindow = m_pRegistryConfig->getDefaultTicketAge();
|
|
if (hasFL == CV_DEFAULT)
|
|
ForceLogin = m_pRegistryConfig->forceLoginP() ? VARIANT_TRUE : VARIANT_FALSE;
|
|
if (hasCB == CV_DEFAULT)
|
|
CBT = m_pRegistryConfig->getDefaultCoBrand();
|
|
if (hasRU == CV_DEFAULT)
|
|
returnUrl = m_pRegistryConfig->getDefaultRU();
|
|
if (hasKPP == CV_DEFAULT)
|
|
nKPP = -1;
|
|
if (returnUrl == NULL)
|
|
returnUrl = L"";
|
|
|
|
if ((TimeWindow != 0 && TimeWindow < PPM_TIMEWINDOW_MIN) || TimeWindow > PPM_TIMEWINDOW_MAX)
|
|
{
|
|
WCHAR buf[20];
|
|
_itow(TimeWindow,buf,10);
|
|
AtlReportError(CLSID_Manager, (LPCOLESTR) PP_E_INVALID_TIMEWINDOWSTR,
|
|
IID_IPassportManager, PP_E_INVALID_TIMEWINDOW);
|
|
return PP_E_INVALID_TIMEWINDOW;
|
|
}
|
|
|
|
if (m_ticketValid)
|
|
{
|
|
LPCWSTR domain = NULL;
|
|
WCHAR url[MAX_URL_LENGTH];
|
|
VARIANT freeMe;
|
|
VariantInit(&freeMe);
|
|
|
|
if (m_pRegistryConfig->DisasterModeP())
|
|
lstrcpynW(url, A2W(m_pRegistryConfig->getDisasterUrl()), sizeof(url)/sizeof(WCHAR));
|
|
else
|
|
{
|
|
if (m_profileValid &&
|
|
m_piProfile->get_ByIndex(MEMBERNAME_INDEX, &freeMe) == S_OK &&
|
|
freeMe.vt == VT_BSTR)
|
|
{
|
|
domain = wcsrchr(freeMe.bstrVal, L'@');
|
|
}
|
|
|
|
cnc->getDomainAttribute(L"Default",
|
|
L"Logout",
|
|
sizeof(url)/sizeof(WCHAR),
|
|
url,
|
|
Lang);
|
|
}
|
|
|
|
// find out if there are any updates
|
|
BSTR upd = NULL;
|
|
m_piProfile->get_updateString(&upd);
|
|
|
|
if (upd)
|
|
{
|
|
TAKEOVER_BSTR(upd);
|
|
// form the appropriate URL
|
|
CCoCrypt* crypt = NULL;
|
|
BSTR newCH = NULL;
|
|
crypt = m_pRegistryConfig->getCurrentCrypt(); // IsValid ensures this is non-null
|
|
// This should never fail... (famous last words)
|
|
crypt->Encrypt(m_pRegistryConfig->getCurrentCryptVersion(), (LPSTR)upd, SysStringByteLen(upd), &newCH);
|
|
FREE_BSTR(upd);
|
|
TAKEOVER_BSTR(newCH);
|
|
WCHAR iurlbuf[1024];
|
|
LPCWSTR iurl;
|
|
cnc->getDomainAttribute(domain ? domain+1 : L"Default",
|
|
L"Update",
|
|
sizeof(iurlbuf) >> 1,
|
|
iurlbuf,
|
|
Lang);
|
|
|
|
// convert this url to https as appropriate
|
|
if(!bSecure)
|
|
iurl = iurlbuf;
|
|
else
|
|
{
|
|
LPWSTR pszNewURL;
|
|
LPWSTR psz;
|
|
|
|
try
|
|
{
|
|
pszNewURL = (LPWSTR)alloca((lstrlenW(iurlbuf) + 2) * sizeof(WCHAR));
|
|
}
|
|
catch(...)
|
|
{
|
|
pszNewURL = NULL;
|
|
// do nothing, just continue to use http url in this case.
|
|
}
|
|
|
|
if(pszNewURL)
|
|
{
|
|
psz = wcsstr(iurlbuf, L"http:");
|
|
if(psz != NULL)
|
|
{
|
|
psz += 4;
|
|
|
|
lstrcpynW(pszNewURL, iurlbuf, (psz - iurlbuf + 1));
|
|
lstrcatW(pszNewURL, L"s");
|
|
lstrcatW(pszNewURL, psz);
|
|
|
|
iurl = pszNewURL;
|
|
}
|
|
}
|
|
}
|
|
|
|
// This is a bit gross... we need to find the $1 in the update url...
|
|
LPCWSTR ins = iurl ? (wcsstr(iurl, L"$1")) : NULL;
|
|
// We'll break if null, but won't crash...
|
|
if (ins && *url != L'\0')
|
|
*pVal = FormatUpdateLogoTag(
|
|
url,
|
|
m_pRegistryConfig->getSiteId(),
|
|
returnUrl,
|
|
TimeWindow,
|
|
ForceLogin,
|
|
m_pRegistryConfig->getCurrentCryptVersion(),
|
|
ct,
|
|
CBT,
|
|
nKPP,
|
|
iurl,
|
|
bSecure,
|
|
newCH,
|
|
PM_LOGOTYPE_SIGNOUT,
|
|
ulSecureLevel,
|
|
m_pRegistryConfig
|
|
);
|
|
FREE_BSTR(newCH);
|
|
}
|
|
else
|
|
{
|
|
WCHAR iurl[MAX_URL_LENGTH] = L"";
|
|
cnc->getDomainAttribute(L"Default",
|
|
szSOAttrName,
|
|
sizeof(iurl)/sizeof(WCHAR),
|
|
iurl,
|
|
Lang);
|
|
if (*iurl != L'\0')
|
|
*pVal = FormatNormalLogoTag(
|
|
url,
|
|
m_pRegistryConfig->getSiteId(),
|
|
returnUrl,
|
|
TimeWindow,
|
|
ForceLogin,
|
|
m_pRegistryConfig->getCurrentCryptVersion(),
|
|
ct,
|
|
CBT,
|
|
iurl,
|
|
NULL,
|
|
nKPP,
|
|
PM_LOGOTYPE_SIGNOUT,
|
|
Lang,
|
|
ulSecureLevel,
|
|
m_pRegistryConfig,
|
|
fRedirToSelf
|
|
);
|
|
}
|
|
VariantClear(&freeMe);
|
|
}
|
|
else
|
|
{
|
|
WCHAR url[MAX_URL_LENGTH];
|
|
if (!(m_pRegistryConfig->DisasterModeP()))
|
|
cnc->getDomainAttribute(L"Default",
|
|
szAUAttrName,
|
|
sizeof(url)/sizeof(WCHAR),
|
|
url,
|
|
Lang);
|
|
else
|
|
lstrcpynW(url, A2W(m_pRegistryConfig->getDisasterUrl()), sizeof(url)/sizeof(WCHAR));
|
|
|
|
WCHAR iurl[MAX_URL_LENGTH];
|
|
cnc->getDomainAttribute(L"Default",
|
|
szSIAttrName,
|
|
sizeof(iurl)/sizeof(WCHAR),
|
|
iurl,
|
|
Lang);
|
|
if (*iurl != L'\0')
|
|
*pVal = FormatNormalLogoTag(
|
|
url,
|
|
m_pRegistryConfig->getSiteId(),
|
|
returnUrl,
|
|
TimeWindow,
|
|
ForceLogin,
|
|
m_pRegistryConfig->getCurrentCryptVersion(),
|
|
ct,
|
|
CBT,
|
|
iurl,
|
|
NameSpace,
|
|
nKPP,
|
|
PM_LOGOTYPE_SIGNIN,
|
|
Lang,
|
|
ulSecureLevel,
|
|
m_pRegistryConfig,
|
|
fRedirToSelf
|
|
);
|
|
|
|
}
|
|
|
|
cnc->Release();
|
|
|
|
if (hasRU == CV_FREE && returnUrl)
|
|
FREE_BSTR(returnUrl);
|
|
if (hasCB == CV_FREE && CBT)
|
|
FREE_BSTR(CBT);
|
|
if (hasNameSpace == CV_FREE && NameSpace)
|
|
FREE_BSTR(NameSpace);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CManager::HasProfile(VARIANT var, VARIANT_BOOL *pVal)
|
|
{
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
char szLogString[LOG_STRING_LEN] = "CManager::HasProfile, Enter";
|
|
AddVariantAsString(var, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
LPWSTR profileName;
|
|
if (var.vt == (VT_BSTR | VT_BYREF))
|
|
profileName = *var.pbstrVal;
|
|
else if (var.vt == VT_BSTR)
|
|
profileName = var.bstrVal;
|
|
else if (var.vt == (VT_VARIANT | VT_BYREF))
|
|
{
|
|
return HasProfile(*(var.pvarVal), pVal);
|
|
}
|
|
else
|
|
profileName = NULL;
|
|
|
|
if ((!profileName) || (!_wcsicmp(profileName, L"core")))
|
|
{
|
|
HRESULT ok = m_piProfile->get_IsValid(pVal);
|
|
if (ok != S_OK)
|
|
*pVal = VARIANT_FALSE;
|
|
}
|
|
else
|
|
{
|
|
VARIANT vAtt;
|
|
VariantInit(&vAtt);
|
|
HRESULT ok = m_piProfile->get_Attribute(profileName, &vAtt);
|
|
if (ok != S_OK)
|
|
{
|
|
if (g_pAlert)
|
|
g_pAlert->report(PassportAlertInterface::ERROR_TYPE, PM_INVALID_PROFILETYPE);
|
|
*pVal = VARIANT_FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (vAtt.vt == VT_I4)
|
|
*pVal = vAtt.lVal > 0 ? VARIANT_TRUE : VARIANT_FALSE;
|
|
else if (vAtt.vt == VT_I2)
|
|
*pVal = vAtt.iVal > 0 ? VARIANT_TRUE : VARIANT_FALSE;
|
|
else
|
|
{
|
|
if (g_pAlert)
|
|
g_pAlert->report(PassportAlertInterface::ERROR_TYPE, PM_INVALID_PROFILETYPE);
|
|
}
|
|
VariantClear(&vAtt);
|
|
}
|
|
}
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
strcpy(szLogString, "CManager::HasProfile, Exit");
|
|
AddVariantBoolAsString(*pVal, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
return(S_OK);
|
|
}
|
|
|
|
STDMETHODIMP CManager::get_HasTicket(VARIANT_BOOL *pVal)
|
|
{
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::get_HasTicket, Calling m_piTicket->get_IsAuthenticated");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
if(!pVal) return E_POINTER;
|
|
|
|
*pVal = m_ticketValid ? VARIANT_TRUE : VARIANT_FALSE;
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CManager::get_FromNetworkServer(VARIANT_BOOL *pVal)
|
|
{
|
|
*pVal = (m_fromQueryString &&
|
|
m_valid &&
|
|
m_ticketValid) ? VARIANT_TRUE : VARIANT_FALSE;
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
char szLogString[LOG_STRING_LEN] = "CManager::get_FromNetworkServer";
|
|
AddVariantBoolAsString(*pVal, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CManager::HasFlag(VARIANT var, VARIANT_BOOL *pVal)
|
|
{
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::HasFlag, E_NOTIMPL");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
|
|
AtlReportError(CLSID_Manager, PP_E_GETFLAGS_OBSOLETESTR,
|
|
IID_IPassportManager, E_NOTIMPL);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CManager::get_TicketAge(int *pVal)
|
|
{
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::get_TicketAge, Calling m_piTicket->get_TicketAge");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return m_piTicket->get_TicketAge(pVal);
|
|
}
|
|
|
|
STDMETHODIMP CManager::get_TicketTime(long *pVal)
|
|
{
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::get_TicketTime, Calling m_piTicket->get_TicketTime");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
return m_piTicket->get_TicketTime(pVal);
|
|
}
|
|
|
|
STDMETHODIMP CManager::get_SignInTime(long *pVal)
|
|
{
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::get_SignInTime, Calling m_piTicket->get_SignInTime");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return m_piTicket->get_SignInTime(pVal);
|
|
}
|
|
|
|
STDMETHODIMP CManager::get_TimeSinceSignIn(int *pVal)
|
|
{
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::get_TimeSinceSignIn, Calling m_piTicket->get_TimeSinceSignIn");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return m_piTicket->get_TimeSinceSignIn(pVal);
|
|
}
|
|
|
|
STDMETHODIMP CManager::GetDomainAttribute(BSTR attributeName, VARIANT lcid, VARIANT domain, BSTR *pAttrVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
char szLogString[LOG_STRING_LEN] = "CManager::GetDomainAttribute, Enter";
|
|
AddBSTRAsString(attributeName, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(lcid, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(domain, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
if (!m_valid || !g_config->isValid()) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
if (!m_pRegistryConfig)
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
|
|
if (!m_pRegistryConfig) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
LPWSTR d;
|
|
BSTR dn = NULL;
|
|
if (domain.vt == (VT_BSTR | VT_BYREF))
|
|
d = *domain.pbstrVal;
|
|
else if (domain.vt == VT_BSTR)
|
|
d = domain.bstrVal;
|
|
else if (domain.vt == (VT_VARIANT | VT_BYREF))
|
|
{
|
|
return GetDomainAttribute(attributeName, lcid, *(domain.pvarVal), pAttrVal);
|
|
}
|
|
else
|
|
{
|
|
// domain best be not filled in this case, that's why we reuse it here
|
|
// if not, let dfmn generate the error
|
|
HRESULT hr = DomainFromMemberName(domain, &dn);
|
|
if (hr != S_OK)
|
|
return hr;
|
|
TAKEOVER_BSTR(dn);
|
|
d = dn;
|
|
}
|
|
|
|
CNexusConfig* cnc = g_config->checkoutNexusConfig();
|
|
USHORT sLcid = 0;
|
|
VARIANT innerLC;
|
|
VariantInit(&innerLC);
|
|
|
|
if (lcid.vt != VT_ERROR && VariantChangeType(&innerLC, &lcid, 0, VT_I2) == S_OK)
|
|
sLcid = innerLC.iVal;
|
|
else
|
|
{
|
|
sLcid = m_pRegistryConfig->getDefaultLCID();
|
|
|
|
// Check user profile
|
|
if (!sLcid && m_profileValid)
|
|
{
|
|
m_piProfile->get_ByIndex(LANGPREF_INDEX, &innerLC);
|
|
if (innerLC.vt == VT_I2)
|
|
sLcid = innerLC.iVal;
|
|
VariantClear(&innerLC);
|
|
}
|
|
}
|
|
|
|
WCHAR data[PP_MAX_ATTRIBUTE_LENGTH] = L"";
|
|
cnc->getDomainAttribute(d,
|
|
attributeName,
|
|
sizeof(data)/sizeof(WCHAR),
|
|
data,
|
|
sLcid);
|
|
if (*data)
|
|
{
|
|
*pAttrVal = ALLOC_AND_GIVEAWAY_BSTR(data);
|
|
}
|
|
else
|
|
{
|
|
// TODO: should change cnc->getDomainAttribute to return the right hr
|
|
hr = E_INVALIDARG;
|
|
*pAttrVal = NULL;
|
|
}
|
|
cnc->Release();
|
|
if (dn) FREE_BSTR(dn);
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
strcpy(szLogString, "CManager::GetDomainAttribute, Exit");
|
|
AddBSTRAsString(*pAttrVal, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CManager::DomainFromMemberName(VARIANT var, BSTR *pDomainName)
|
|
{
|
|
HRESULT hr;
|
|
LPWSTR psz, memberName;
|
|
VARIANT intoVar;
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
char szLogString[LOG_STRING_LEN] = "CManager::DomainFromMemberName, Enter";
|
|
AddVariantAsString(var, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
VariantInit(&intoVar);
|
|
|
|
if (var.vt == (VT_BSTR | VT_BYREF))
|
|
memberName = *var.pbstrVal;
|
|
else if (var.vt == VT_BSTR)
|
|
memberName = var.bstrVal;
|
|
else if (var.vt == (VT_VARIANT | VT_BYREF))
|
|
{
|
|
return DomainFromMemberName(*(var.pvarVal), pDomainName);
|
|
}
|
|
else
|
|
{
|
|
// Try to get it from the profile
|
|
if (!m_profileValid)
|
|
{
|
|
*pDomainName = ALLOC_AND_GIVEAWAY_BSTR(L"Default");
|
|
return S_OK;
|
|
}
|
|
HRESULT hr = m_piProfile->get_Attribute(L"internalmembername", &intoVar);
|
|
if (hr != S_OK)
|
|
{
|
|
*pDomainName = NULL;
|
|
return hr;
|
|
}
|
|
if (VariantChangeType(&intoVar,&intoVar, 0, VT_BSTR) != S_OK)
|
|
{
|
|
AtlReportError(CLSID_Manager, L"PassportManager: Couldn't convert memberName to string. Call partner support.",
|
|
IID_IPassportManager, E_FAIL);
|
|
return E_FAIL;
|
|
}
|
|
memberName = intoVar.bstrVal;
|
|
}
|
|
|
|
|
|
if(memberName == NULL)
|
|
{
|
|
hr = E_POINTER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
psz = wcsrchr(memberName, L'@');
|
|
if(psz == NULL)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto Cleanup;
|
|
}
|
|
|
|
psz++;
|
|
|
|
*pDomainName = ALLOC_AND_GIVEAWAY_BSTR(psz);
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
VariantClear(&intoVar);
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
strcpy(szLogString, "CManager::DomainFromMemberName, Exit");
|
|
AddLongAsString(hr, szLogString, sizeof(szLogString));
|
|
AddBSTRAsString(*pDomainName, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CManager::get_Profile(BSTR attributeName, VARIANT *pVal)
|
|
{
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::get_Profile, Calling m_piProfile->get_Attribute");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
HRESULT hr = m_piProfile->get_Attribute(attributeName,pVal);
|
|
|
|
if(hr == S_OK && pVal->vt != VT_EMPTY)
|
|
{
|
|
if(g_pPerf)
|
|
{
|
|
g_pPerf->incrementCounter(PM_VALIDPROFILEREQ_SEC);
|
|
g_pPerf->incrementCounter(PM_VALIDPROFILEREQ_TOTAL);
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(g_pPerf);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CManager::put_Profile(BSTR attributeName, VARIANT newVal)
|
|
{
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::put_Profile, Calling m_piProfile->put_Attribute");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return m_piProfile->put_Attribute(attributeName,newVal);
|
|
}
|
|
|
|
|
|
STDMETHODIMP CManager::get_HexPUID(BSTR *pVal)
|
|
{
|
|
if(!pVal) return E_INVALIDARG;
|
|
|
|
if(m_piTicket)
|
|
return m_piTicket->get_MemberId(pVal);
|
|
else
|
|
return PP_E_INVALID_TICKET;
|
|
}
|
|
|
|
STDMETHODIMP CManager::get_PUID(BSTR *pVal)
|
|
{
|
|
if(!pVal) return E_INVALIDARG;
|
|
|
|
if(m_piTicket)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WCHAR id[64] = L"0";
|
|
int l = 0;
|
|
int h = 0;
|
|
LARGE_INTEGER ui64;
|
|
|
|
|
|
hr = m_piTicket->get_MemberIdLow(&l);
|
|
if (S_OK != hr) return hr;
|
|
hr = m_piTicket->get_MemberIdHigh(&h);
|
|
if (S_OK != hr) return hr;
|
|
|
|
ui64.HighPart = h;
|
|
ui64.LowPart = l;
|
|
|
|
_ui64tow(ui64.QuadPart, id, 10);
|
|
|
|
*pVal = SysAllocString(id);
|
|
|
|
if(*pVal == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
else
|
|
return PP_E_INVALID_TICKET;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CManager::get_Ticket(BSTR attributeName, VARIANT *pVal)
|
|
{
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::get_Ticket, Calling m_piTicket->get_Attribute");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
HRESULT hr = m_piTicket->GetProperty(attributeName,pVal);
|
|
|
|
#if 0 // we don't not need this
|
|
if(hr == S_OK && pVal->vt != VT_EMPTY)
|
|
{
|
|
if(g_pPerf)
|
|
{
|
|
// TODO -- shoud change -- we may not need this, visit back later
|
|
// g_pPerf->incrementCounter(PM_VALIDREQUESTS_SEC);
|
|
// g_pPerf->incrementCounter(PM_VALIDREQUESTS_TOTAL);
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(g_pPerf);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return hr;
|
|
}
|
|
|
|
#if 0 // removed -- wireless uses the same set of urls
|
|
STDMETHODIMP CManager::AuthURL3(
|
|
VARIANT vRU,
|
|
VARIANT vTimeWindow,
|
|
VARIANT vForceLogin,
|
|
VARIANT vCoBrand,
|
|
VARIANT vLCID,
|
|
VARIANT vNameSpace,
|
|
VARIANT vKPP,
|
|
VARIANT vUseSecureAuth,
|
|
VARIANT functionArea,
|
|
BSTR *pAuthUrl)
|
|
{
|
|
return CommonAuthURL(vRU, vTimeWindow, vForceLogin,
|
|
vCoBrand, vLCID, vNameSpace,
|
|
vKPP, vUseSecureAuth,
|
|
FALSE, functionArea, pAuthUrl);
|
|
|
|
}
|
|
#endif
|
|
|
|
STDMETHODIMP CManager::LogoutURL(
|
|
/* [optional][in] */ VARIANT vRU,
|
|
/* [optional][in] */ VARIANT vCoBrand,
|
|
/* [optional][in] */ VARIANT lang_id,
|
|
/* [optional][in] */ VARIANT Namespace,
|
|
/* [optional][in] */ VARIANT bSecure,
|
|
/* [retval][out] */ BSTR __RPC_FAR *pVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
VARIANT_BOOL bUseSecure = VARIANT_FALSE;
|
|
BSTR CBT = NULL, returnUrl = NULL, bstrNameSpace = NULL;
|
|
int hasCB, hasRU, hasLCID, hasNameSpace, hasUseSec;
|
|
USHORT Lang;
|
|
WCHAR nameSpace[MAX_PATH] = L"";
|
|
bool bUrlFromSecureKey = false;
|
|
WCHAR UrlBuf[MAX_URL_LENGTH] = L"";
|
|
WCHAR retUrlBuf[MAX_URL_LENGTH] = L"";
|
|
DWORD bufLen = MAX_URL_LENGTH;
|
|
WCHAR qsLeadCh = L'?';
|
|
int iRet = 0;
|
|
|
|
if (!pVal) return E_INVALIDARG;
|
|
|
|
CNexusConfig* cnc = g_config->checkoutNexusConfig();
|
|
|
|
if (!m_pRegistryConfig)
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
|
|
|
|
if ((hasUseSec = GetBoolArg(bSecure, &bUseSecure)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
|
|
if ((hasLCID = GetShortArg(lang_id,&Lang)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
|
|
hasCB = GetBstrArg(vCoBrand, &CBT);
|
|
if (hasCB == CV_BAD)
|
|
return E_INVALIDARG;
|
|
|
|
hasRU = GetBstrArg(vRU, &returnUrl);
|
|
if (hasRU == CV_BAD)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto Cleanup;
|
|
}
|
|
|
|
hasNameSpace = GetBstrArg(Namespace, &bstrNameSpace);
|
|
if (hasNameSpace == CV_BAD)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto Cleanup;
|
|
}
|
|
// get the right URL -- namespace, secure
|
|
|
|
// namespace
|
|
if (!IsEmptyString(bstrNameSpace))
|
|
{
|
|
if(0 == _snwprintf(nameSpace, sizeof(nameSpace) / sizeof(WCHAR), L"%s", bstrNameSpace))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
if FAILED(hr)
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
if (hasCB == CV_DEFAULT)
|
|
CBT = m_pRegistryConfig->getDefaultCoBrand();
|
|
if (hasRU == CV_DEFAULT)
|
|
returnUrl = m_pRegistryConfig->getDefaultRU();
|
|
if (returnUrl == NULL)
|
|
returnUrl = L"";
|
|
|
|
|
|
|
|
if (*nameSpace == 0) // 0 length string
|
|
wcscpy(nameSpace, L"Default");
|
|
|
|
// secure
|
|
if(bUseSecure == VARIANT_TRUE)
|
|
{
|
|
cnc->getDomainAttribute(nameSpace,
|
|
L"LogoutSecure",
|
|
sizeof(UrlBuf)/sizeof(WCHAR),
|
|
UrlBuf,
|
|
Lang);
|
|
if (*UrlBuf != 0)
|
|
{
|
|
bUrlFromSecureKey = true;
|
|
}
|
|
}
|
|
|
|
// insecure
|
|
if (*UrlBuf == 0)
|
|
{
|
|
cnc->getDomainAttribute(nameSpace,
|
|
L"Logout",
|
|
sizeof(UrlBuf)/sizeof(WCHAR),
|
|
UrlBuf,
|
|
Lang);
|
|
}
|
|
// error case
|
|
if(*UrlBuf == 0)
|
|
{
|
|
AtlReportError(CLSID_Profile, PP_E_LOGOUTURL_NOTDEFINEDSTR,
|
|
IID_IPassportProfile, PP_E_LOGOUTURL_NOTDEFINED);
|
|
hr = PP_E_LOGOUTURL_NOTDEFINED;
|
|
goto Cleanup;
|
|
}
|
|
|
|
if(bUseSecure == VARIANT_TRUE && !bUrlFromSecureKey) // translate from http to https
|
|
{
|
|
if (_wcsnicmp(UrlBuf, L"http:", 5) == 0) // replace with HTTPS
|
|
{
|
|
memmove(UrlBuf + 5, UrlBuf + 4, sizeof(UrlBuf) - 5 * sizeof(WCHAR));
|
|
memcpy(UrlBuf, L"https", 5 * sizeof(WCHAR));
|
|
}
|
|
}
|
|
|
|
// us common function to append the thing one by one ...
|
|
if (wcsstr(UrlBuf, L"?")) // ? already exists in the URL, use & to start
|
|
qsLeadCh = L'&';
|
|
if (CBT)
|
|
_snwprintf(retUrlBuf, sizeof(retUrlBuf) / sizeof(WCHAR), L"%s%cid=%-d&ru=%s&lcid=%-d&cb=%s",
|
|
UrlBuf, qsLeadCh, m_pRegistryConfig->getSiteId(), returnUrl, Lang, CBT);
|
|
else
|
|
_snwprintf(retUrlBuf, sizeof(retUrlBuf) / sizeof(WCHAR), L"%s%cid=%-d&ru=%s&lcid=%-d",
|
|
UrlBuf, qsLeadCh, m_pRegistryConfig->getSiteId(), returnUrl, Lang);
|
|
|
|
|
|
*pVal = ALLOC_AND_GIVEAWAY_BSTR(retUrlBuf);
|
|
Cleanup:
|
|
cnc->Release();
|
|
|
|
return hr;
|
|
}
|
|
|
|
#if 0 // this is not necessary, use should use 1. isAuthenticated, 2. prop bag to get secure level
|
|
STDMETHODIMP CManager::IsSecure(/*[in]*/ VARIANT secureLevel, /*[out, retval]*/ VARIANT_BOOL *pVal)
|
|
{
|
|
if(!pVal) return E_INVALIDARG;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
_variant_t vFlags, vLevel;
|
|
VARIANT v;
|
|
|
|
if(S_OK != VariantChangeType(&v, &secureLevel, 0, VT_I4))
|
|
return E_INVALIDARG;;
|
|
|
|
long requiredLevel = v.lVal;
|
|
|
|
*pVal = VARIANT_FALSE;
|
|
|
|
if(!m_bSecureTransported)
|
|
return S_OK;
|
|
|
|
if (S_OK != m_piTicket->GetProperty(ATTR_PASSPORTFLAGS, &vFlags)
|
|
|| S_OK != m_piTicket->GetProperty(ATTR_SECURELEVEL, &vLevel))
|
|
return S_OK;
|
|
|
|
if ( vFlags.vt != VT_I4 || vLevel.vt != VT_I4)
|
|
return S_OK;
|
|
|
|
if ( (vFlags.lVal & k_ulFlagsSecuredTransportedTicket) && vLevel.lVal >= requiredLevel)
|
|
*pVal = VARIANT_TRUE;
|
|
|
|
return S_OK;
|
|
}
|
|
#endif
|
|
|
|
STDMETHODIMP CManager::get_ProfileByIndex(int index, VARIANT *pVal)
|
|
{
|
|
HRESULT hr = m_piProfile->get_ByIndex(index,pVal);
|
|
|
|
if(hr == S_OK && pVal->vt != VT_EMPTY)
|
|
{
|
|
if(g_pPerf)
|
|
{
|
|
g_pPerf->incrementCounter(PM_VALIDPROFILEREQ_SEC);
|
|
g_pPerf->incrementCounter(PM_VALIDPROFILEREQ_TOTAL);
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(g_pPerf);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CManager::put_ProfileByIndex(int index, VARIANT newVal)
|
|
{
|
|
return m_piProfile->put_ByIndex(index,newVal);
|
|
}
|
|
|
|
BOOL CManager::handleQueryStringData(BSTR a, BSTR p)
|
|
{
|
|
BOOL retVal; //whither to set cookies
|
|
HRESULT hr;
|
|
VARIANT vFalse;
|
|
_variant_t vFlags;
|
|
|
|
hr = DecryptTicketAndProfile(a, p, FALSE, NULL, m_pRegistryConfig, m_piTicket, m_piProfile);
|
|
|
|
if(hr != S_OK)
|
|
{
|
|
m_ticketValid = VARIANT_FALSE;
|
|
m_profileValid = VARIANT_FALSE;
|
|
retVal = FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
VariantInit(&vFalse);
|
|
vFalse.vt = VT_BOOL;
|
|
vFalse.boolVal = VARIANT_FALSE;
|
|
|
|
m_piTicket->get_IsAuthenticated(0,
|
|
VARIANT_FALSE,
|
|
vFalse,
|
|
&m_ticketValid);
|
|
|
|
if(!m_bSecureTransported) // secure bit should NOI set
|
|
{
|
|
if (S_OK == m_piTicket->GetProperty(ATTR_PASSPORTFLAGS, &vFlags))
|
|
{ // the bit should NOT set
|
|
if ( vFlags.vt == VT_I4 && (vFlags.lVal & k_ulFlagsSecuredTransportedTicket) != 0)
|
|
m_ticketValid = VARIANT_FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
// profile stuff
|
|
m_piProfile->get_IsValid(&m_profileValid);
|
|
|
|
if (m_ticketValid)
|
|
{
|
|
m_fromQueryString = true;
|
|
|
|
// Set the cookies
|
|
if (!m_pRegistryConfig->setCookiesP())
|
|
{
|
|
retVal = FALSE;
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
retVal = TRUE;
|
|
|
|
Cleanup:
|
|
|
|
return retVal;
|
|
}
|
|
|
|
BOOL CManager::handleCookieData(
|
|
BSTR auth,
|
|
BSTR prof,
|
|
BSTR consent,
|
|
BSTR secAuth
|
|
)
|
|
{
|
|
BOOL retVal;
|
|
HRESULT hr;
|
|
VARIANT vDoSecureCheck;
|
|
VARIANT_BOOL bValid;
|
|
_variant_t vFlags;
|
|
|
|
// the consent cookie
|
|
if(consent != NULL && SysStringLen(consent) != 0)
|
|
{
|
|
hr = DecryptTicketAndProfile(auth, prof, !(m_pRegistryConfig->bInDA()), consent, m_pRegistryConfig, m_piTicket, m_piProfile);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If regular cookie domain/path is identical to consent cookie domain/path, then
|
|
// MSPProf cookie is equivalent to consent cookie, and we should set m_bUsingConsentCookie
|
|
// to true
|
|
//
|
|
|
|
BOOL bUsingConsentCookie = lstrcmpA(m_pRegistryConfig->getTicketDomain(), m_pRegistryConfig->getProfileDomain()) == 0 &&
|
|
lstrcmpA(m_pRegistryConfig->getTicketPath(), m_pRegistryConfig->getProfilePath()) == 0;
|
|
|
|
hr = DecryptTicketAndProfile(auth, prof, !(m_pRegistryConfig->bInDA()) && !bUsingConsentCookie, NULL, m_pRegistryConfig, m_piTicket, m_piProfile);
|
|
}
|
|
|
|
if(hr != S_OK)
|
|
{
|
|
m_ticketValid = VARIANT_FALSE;
|
|
m_profileValid = VARIANT_FALSE;
|
|
retVal = FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
VariantInit(&vDoSecureCheck);
|
|
vDoSecureCheck.vt = VT_BOOL;
|
|
|
|
if(secAuth && secAuth[0])
|
|
{
|
|
if(DoSecureCheck(secAuth, m_pRegistryConfig, m_piTicket) == S_OK)
|
|
vDoSecureCheck.boolVal = VARIANT_TRUE;
|
|
else
|
|
vDoSecureCheck.boolVal = VARIANT_FALSE;
|
|
}
|
|
else
|
|
vDoSecureCheck.boolVal = VARIANT_FALSE;
|
|
|
|
m_piTicket->get_IsAuthenticated(0,
|
|
VARIANT_FALSE,
|
|
vDoSecureCheck,
|
|
&m_ticketValid);
|
|
|
|
// if the cookie should not include the secure bit
|
|
if (S_OK == m_piTicket->GetProperty(ATTR_PASSPORTFLAGS, &vFlags))
|
|
{ // the bit should NOT set
|
|
if ( vFlags.vt == VT_I4 && (vFlags.lVal & k_ulFlagsSecuredTransportedTicket) != 0)
|
|
m_ticketValid = VARIANT_FALSE;
|
|
}
|
|
|
|
// for insecure case, the secure cookie should not come
|
|
if(!m_bSecureTransported && (secAuth && secAuth[0])) // this should not come
|
|
{
|
|
m_ticketValid = VARIANT_FALSE;
|
|
}
|
|
|
|
// profile stuff
|
|
m_piProfile->get_IsValid(&m_profileValid);
|
|
|
|
if(!m_ticketValid)
|
|
{
|
|
retVal = FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
retVal = TRUE;
|
|
|
|
Cleanup:
|
|
|
|
return retVal;
|
|
}
|
|
|
|
STDMETHODIMP CManager::get_HasSavedPassword(VARIANT_BOOL *pVal)
|
|
{
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::get_HasSavedPassword, Calling m_piTicket->get_HasSavedPassword");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return m_piTicket->get_HasSavedPassword(pVal);
|
|
}
|
|
|
|
STDMETHODIMP CManager::Commit(BSTR *pNewProfileCookie)
|
|
{
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::Commit, Enter");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
if (!m_pRegistryConfig)
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
|
|
if (!m_valid || !g_config->isValid() || !m_pRegistryConfig) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
if (!m_ticketValid || !m_profileValid)
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_IT_FOR_COMMITSTR,
|
|
IID_IPassportManager, PP_E_INVALID_TICKET);
|
|
return PP_E_INVALID_TICKET;
|
|
}
|
|
|
|
// Write new passport profile cookie...
|
|
// return a safearray if we aren't used from ASP
|
|
BSTR newP = NULL;
|
|
HRESULT hr = m_piProfile->incrementVersion();
|
|
hr = m_piProfile->get_unencryptedProfile(&newP);
|
|
TAKEOVER_BSTR(newP);
|
|
|
|
if (hr != S_OK || newP == NULL)
|
|
{
|
|
AtlReportError(CLSID_Manager,
|
|
L"PassportManager.Commit: unknown failure.",
|
|
IID_IPassportManager, E_FAIL);
|
|
return E_FAIL;
|
|
}
|
|
|
|
CCoCrypt* crypt = NULL;
|
|
BSTR newCH = NULL;
|
|
crypt = m_pRegistryConfig->getCurrentCrypt(); // IsValid ensures this is non-null
|
|
crypt->Encrypt(m_pRegistryConfig->getCurrentCryptVersion(),(LPSTR)newP, SysStringByteLen(newP), &newCH);
|
|
if (!newCH)
|
|
{
|
|
AtlReportError(CLSID_Manager,
|
|
L"PassportManager.Commit: encryption failure.",
|
|
IID_IPassportManager, E_FAIL);
|
|
FREE_BSTR(newP);
|
|
return E_FAIL;
|
|
}
|
|
FREE_BSTR(newP);
|
|
TAKEOVER_BSTR(newCH);
|
|
|
|
if (m_bOnStartPageCalled)
|
|
{
|
|
if (m_pRegistryConfig->setCookiesP())
|
|
{
|
|
try
|
|
{
|
|
VARIANT_BOOL persist;
|
|
_bstr_t domain;
|
|
_bstr_t path;
|
|
|
|
if (m_pRegistryConfig->getTicketPath())
|
|
path = m_pRegistryConfig->getTicketPath();
|
|
else
|
|
path = L"/";
|
|
|
|
m_piTicket->get_HasSavedPassword(&persist);
|
|
IRequestDictionaryPtr piCookies = m_piResponse->Cookies;
|
|
|
|
VARIANT vtNoParam;
|
|
VariantInit(&vtNoParam);
|
|
vtNoParam.vt = VT_ERROR;
|
|
vtNoParam.scode = DISP_E_PARAMNOTFOUND;
|
|
|
|
IWriteCookiePtr piCookie = piCookies->Item[L"MSPProf"];
|
|
piCookie->Item[vtNoParam] = newCH;
|
|
domain = m_pRegistryConfig->getTicketDomain();
|
|
if (domain.length())
|
|
piCookie->put_Domain(domain);
|
|
if (persist)
|
|
piCookie->put_Expires(g_dtExpire);
|
|
piCookie->put_Path(path);
|
|
|
|
}
|
|
catch (...)
|
|
{
|
|
FREE_BSTR(newCH);
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
}
|
|
GIVEAWAY_BSTR(newCH);
|
|
*pNewProfileCookie = newCH;
|
|
|
|
if(g_pPerf)
|
|
{
|
|
g_pPerf->incrementCounter(PM_PROFILECOMMITS_SEC);
|
|
g_pPerf->incrementCounter(PM_PROFILECOMMITS_TOTAL);
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(g_pPerf);
|
|
}
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::Commit, Exit");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CManager::_Ticket(IPassportTicket** piTicket)
|
|
{
|
|
return m_piTicket->QueryInterface(IID_IPassportTicket,(void**)piTicket);
|
|
}
|
|
|
|
STDMETHODIMP CManager::_Profile(IPassportProfile** piProfile)
|
|
{
|
|
return m_piProfile->QueryInterface(IID_IPassportProfile,(void**)piProfile);
|
|
}
|
|
|
|
STDMETHODIMP CManager::DomainExists(
|
|
BSTR bstrDomainName,
|
|
VARIANT_BOOL* pbExists
|
|
)
|
|
{
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::DomainExists, Enter");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
|
|
if(!pbExists)
|
|
return E_INVALIDARG;
|
|
|
|
if(!g_config->isValid())
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
CNexusConfig* cnc = g_config->checkoutNexusConfig();
|
|
|
|
*pbExists = cnc->DomainExists(bstrDomainName) ? VARIANT_TRUE : VARIANT_FALSE;
|
|
|
|
cnc->Release();
|
|
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::DomainExists, Exit");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CManager::get_Domains(VARIANT *pArrayVal)
|
|
{
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::get_Domains, Enter");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
if (!pArrayVal)
|
|
return E_INVALIDARG;
|
|
|
|
if (!g_config->isValid()) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
CNexusConfig* cnc = g_config->checkoutNexusConfig();
|
|
|
|
int iArr = 0;
|
|
LPCWSTR *arr = cnc->getDomains(&iArr);
|
|
|
|
if (!arr || iArr == 0)
|
|
{
|
|
VariantClear(pArrayVal);
|
|
return S_OK;
|
|
}
|
|
|
|
// Make a safearray with all the goods
|
|
SAFEARRAYBOUND rgsabound;
|
|
rgsabound.lLbound = 0;
|
|
rgsabound.cElements = iArr;
|
|
SAFEARRAY *sa = SafeArrayCreate(VT_VARIANT, 1, &rgsabound);
|
|
|
|
if (!sa)
|
|
{
|
|
cnc->Release();
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
VariantInit(pArrayVal);
|
|
pArrayVal->vt = VT_ARRAY | VT_VARIANT;
|
|
pArrayVal->parray = sa;
|
|
|
|
VARIANT *vArray;
|
|
SafeArrayAccessData(sa, (void**)&vArray);
|
|
|
|
for (long i = 0; i < iArr; i++)
|
|
{
|
|
vArray[i].vt = VT_BSTR;
|
|
vArray[i].bstrVal = ALLOC_AND_GIVEAWAY_BSTR(arr[i]);
|
|
}
|
|
SafeArrayUnaccessData(sa);
|
|
|
|
delete[] arr;
|
|
cnc->Release();
|
|
return S_OK;
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
g_pTSLogger->AddDateTimeAndLog("CManager::get_Domains, Exit");
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
}
|
|
|
|
STDMETHODIMP CManager::get_Error(long* plError)
|
|
{
|
|
if(plError == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
if(m_ticketValid)
|
|
{
|
|
m_piTicket->get_Error(plError);
|
|
if(*plError == 0)
|
|
*plError = m_lNetworkError;
|
|
}
|
|
else
|
|
{
|
|
*plError = m_lNetworkError;
|
|
}
|
|
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
char szLogString[LOG_STRING_LEN] = "CManager::get_Error";
|
|
AddLongAsString(*plError, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CManager::GetServerInfo(BSTR *pbstrOut)
|
|
{
|
|
if (!m_valid || !g_config->isValid()) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
if(!m_pRegistryConfig)
|
|
// This only happens when OnStartPage was not called first.
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
|
|
if (!m_pRegistryConfig)
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
CNexusConfig* cnc = g_config->checkoutNexusConfig();
|
|
BSTR bstrVersion = cnc->GetXMLInfo();
|
|
cnc->Release();
|
|
|
|
WCHAR wszName[MAX_COMPUTERNAME_LENGTH+1];
|
|
DWORD dwSize = MAX_COMPUTERNAME_LENGTH+1;
|
|
GetComputerName(wszName, &dwSize);
|
|
|
|
*pbstrOut = ALLOC_AND_GIVEAWAY_BSTR_LEN(NULL, wcslen(wszName)+::SysStringLen(bstrVersion)+1);
|
|
|
|
wcscpy(*pbstrOut, wszName);
|
|
BSTR p = *pbstrOut + wcslen(wszName);
|
|
*p = L' ';
|
|
wcsncpy(p+1, bstrVersion, ::SysStringLen(bstrVersion));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CManager::HaveConsent(
|
|
VARIANT_BOOL bNeedFullConsent,
|
|
VARIANT_BOOL bNeedBirthdate,
|
|
VARIANT_BOOL* pbHaveConsent)
|
|
{
|
|
HRESULT hr;
|
|
ULONG flags = 0;
|
|
VARIANT vBdayPrecision;
|
|
BOOL bKid;
|
|
BOOL bConsentSatisfied;
|
|
NeedConsentEnum needConsentCode = NeedConsent_Undefined;
|
|
|
|
if(pbHaveConsent == NULL)
|
|
{
|
|
hr = E_POINTER;
|
|
goto Cleanup;
|
|
}
|
|
*pbHaveConsent = VARIANT_FALSE;
|
|
|
|
VariantInit(&vBdayPrecision);
|
|
|
|
//
|
|
// Get flags.
|
|
//
|
|
|
|
|
|
hr = m_piTicket->needConsent(&flags, &needConsentCode); // ignore return value
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
hr = S_OK;
|
|
goto Cleanup;
|
|
}
|
|
|
|
// if old ticket, we get the consent info from the profile
|
|
if(needConsentCode == NeedConsent_Undefined)
|
|
{
|
|
// then we get from profile
|
|
VARIANT_BOOL bValid;
|
|
CComVariant vFlags;
|
|
m_piProfile->get_IsValid(&bValid);
|
|
|
|
if(bValid == VARIANT_FALSE)
|
|
{
|
|
hr = S_OK;
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = m_piProfile->get_Attribute(L"flags", &vFlags);
|
|
|
|
if(hr != S_OK)
|
|
goto Cleanup;
|
|
|
|
bKid = ((V_I4(&vFlags) & k_ulFlagsAccountType) == k_ulFlagsAccountTypeKid);
|
|
}
|
|
else
|
|
bKid = ((flags & k_ulFlagsAccountType) == k_ulFlagsAccountTypeKid);
|
|
|
|
// we should have the flags by now
|
|
//
|
|
// Do we have the requested level of consent?
|
|
//
|
|
|
|
bConsentSatisfied = bNeedFullConsent ? (flags & 0x60) == 0x40 :
|
|
(flags & 0x60) != 0;
|
|
|
|
if(bKid)
|
|
{
|
|
*pbHaveConsent = (bConsentSatisfied) ? VARIANT_TRUE : VARIANT_FALSE;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Make sure we have birthday if it was requested.
|
|
//
|
|
// no return value check need here, always returns S_OK.
|
|
VARIANT_BOOL bValid;
|
|
m_piProfile->get_IsValid(&bValid);
|
|
|
|
// if profile is not valid, then we don't have consent.
|
|
// return.
|
|
if(bValid == VARIANT_FALSE)
|
|
{
|
|
hr = S_OK;
|
|
goto Cleanup;
|
|
}
|
|
|
|
if(bNeedBirthdate)
|
|
{
|
|
hr = m_piProfile->get_Attribute(L"bday_precision", &vBdayPrecision);
|
|
if(hr != S_OK)
|
|
goto Cleanup;
|
|
|
|
*pbHaveConsent = (vBdayPrecision.lVal != 0 && vBdayPrecision.lVal != 3) ?
|
|
VARIANT_TRUE : VARIANT_FALSE;
|
|
}
|
|
else
|
|
*pbHaveConsent = VARIANT_TRUE;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
|
|
VariantClear(&vBdayPrecision);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// check the qs parameter. if challenge is requested,
|
|
// build the auth header and redirect with a modified qs
|
|
//
|
|
BOOL CManager::checkForPassportChallenge(IRequestDictionaryPtr piServerVariables)
|
|
{
|
|
// just need the request string
|
|
_variant_t vtItemName, vtQueryString;
|
|
vtItemName = L"QUERY_STRING";
|
|
|
|
piServerVariables->get_Item(vtItemName, &vtQueryString);
|
|
if(vtQueryString.vt != VT_BSTR)
|
|
vtQueryString.ChangeType(VT_BSTR);
|
|
|
|
if (vtQueryString.bstrVal && *vtQueryString.bstrVal)
|
|
{
|
|
// check if pchg=1 is there. It is the first parameter ....
|
|
PWSTR psz = wcsstr(vtQueryString.bstrVal, L"pchg=1");
|
|
if (psz)
|
|
{
|
|
|
|
// we are in business. reformat the URL, insert the headers and
|
|
// redirect
|
|
psz = wcsstr(psz, PPLOGIN_PARAM);
|
|
_ASSERT(psz);
|
|
if (psz)
|
|
{
|
|
psz += wcslen(PPLOGIN_PARAM);
|
|
PWSTR pszEndLoginUrl = wcsstr(psz, L"&");
|
|
_ASSERT(pszEndLoginUrl);
|
|
if (pszEndLoginUrl)
|
|
{
|
|
*pszEndLoginUrl = L'\0';
|
|
// unescape the URL
|
|
// use temp buffer ...
|
|
CComBSTR bstrBuf(wcslen(psz)+1);
|
|
DWORD cch = bstrBuf.Length();
|
|
// PPUnescapeUrl(psz, psz, (DWORD*)&dwLen, pszEndLoginUrl - psz);
|
|
if(!InternetCanonicalizeUrl(psz,
|
|
bstrBuf,
|
|
&cch,
|
|
ICU_DECODE | ICU_NO_ENCODE))
|
|
{
|
|
// what else can be done ???
|
|
_ASSERT(FALSE);
|
|
}
|
|
else
|
|
{
|
|
// copy the unescaped URL to the orig buffer
|
|
wcscpy(psz, (BSTR)bstrBuf);
|
|
// set headers first ...
|
|
// just use the qs param with some reformatting
|
|
_bstr_t bstrHeader;
|
|
HeaderFromQS(wcsstr(psz, L"?"), bstrHeader);
|
|
m_piResponse->AddHeader(L"WWW-Authenticate", bstrHeader);
|
|
// Url is ready, redirect ...
|
|
m_piResponse->Redirect(psz);
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// given a queryString, format the www-authenticate header
|
|
//
|
|
BOOL
|
|
CManager::HeaderFromQS(PWSTR pszQS, _bstr_t& bstrHeader)
|
|
{
|
|
|
|
// common header start ...
|
|
bstrHeader = PASSPORT_PROT14;
|
|
BOOL fSuccess = TRUE;
|
|
// advance thru any leading junk ...
|
|
while(!iswalnum(*pszQS) && *pszQS) pszQS++;
|
|
if (!*pszQS)
|
|
return FALSE;
|
|
|
|
WCHAR rgszValue[1000]; // buffer large enough for most values ...
|
|
PCWSTR psz = pszQS, pszNext = pszQS;
|
|
while(TRUE)
|
|
{
|
|
// no param name is more than 10 ....
|
|
WCHAR rgszName[10];
|
|
LONG cch = sizeof(rgszName)/sizeof(WCHAR);
|
|
PCWSTR pszName = psz;
|
|
while(*pszNext && *pszNext != L'&') pszNext++;
|
|
// grab the next qsparam
|
|
// name first
|
|
while(*pszName != L'=' && pszName < pszNext) pszName++;
|
|
_ASSERT(pszName != pszNext); // this should never happen
|
|
if (pszName == pszNext)
|
|
{
|
|
// and if it does, skip this parameter and return FALSE ...
|
|
fSuccess = FALSE;
|
|
}
|
|
else
|
|
{
|
|
PWSTR pszVal = rgszValue;
|
|
_ASSERT(pszName - psz < cch);
|
|
wcsncpy(rgszName, psz, min(pszName - psz, cch));
|
|
rgszName[min(cch-1, pszName - psz)] = L'\0';
|
|
// next comes the value
|
|
pszName++;
|
|
if (pszNext - pszName >= sizeof(rgszValue))
|
|
{
|
|
// have to allocate ...
|
|
pszVal = new WCHAR[pszNext - pszName];
|
|
if (!pszVal)
|
|
{
|
|
fSuccess = FALSE;
|
|
}
|
|
}
|
|
if (pszVal)
|
|
{
|
|
// copy the value ...
|
|
wcsncpy(pszVal, pszName, pszNext - pszName);
|
|
pszVal[pszNext - pszName] = L'\0';
|
|
// and insert in the header ...
|
|
if (psz != pszQS)
|
|
// this is not the first param
|
|
bstrHeader += L",";
|
|
else
|
|
// first separator is a space ...
|
|
bstrHeader += L" ";
|
|
|
|
bstrHeader += _bstr_t(rgszName) + L"=" + pszVal;
|
|
if (pszVal != rgszValue)
|
|
// it was alloc'd
|
|
delete pszVal;
|
|
}
|
|
} // else '=' found
|
|
// skip to the next param ...
|
|
if (!*pszNext)
|
|
break;
|
|
psz = ++pszNext;
|
|
} // while
|
|
|
|
|
|
return fSuccess;
|
|
}
|
|
|
|
|
|
//
|
|
// format WWW-Auth from parameters
|
|
//
|
|
STDMETHODIMP CManager::FormatAuthHeaderFromParams(PCWSTR pszLoginUrl, // unused for now
|
|
PCWSTR pszRetUrl,
|
|
ULONG ulTimeWindow,
|
|
BOOL fForceLogin,
|
|
time_t ct,
|
|
PCWSTR pszCBT, // unused for now
|
|
PCWSTR pszNamespace,
|
|
int nKpp,
|
|
PWSTR pszLCID, // tweener needs the LCID
|
|
ULONG ulSecureLevel,
|
|
_bstr_t& strHeader // return result
|
|
)
|
|
{
|
|
WCHAR temp[10];
|
|
// based on the spec ...
|
|
strHeader = _bstr_t(PASSPORT_PROT14) + L" id=";
|
|
|
|
// site=
|
|
_ultow(m_pRegistryConfig->getSiteId(), temp, 10);
|
|
strHeader += temp;
|
|
|
|
// rtw=
|
|
strHeader += ",tw=";
|
|
_ultow(ulTimeWindow, temp, 10);
|
|
strHeader += temp;
|
|
|
|
if (fForceLogin)
|
|
{
|
|
strHeader += _bstr_t(",fs=1");
|
|
}
|
|
if (pszNamespace && *pszNamespace)
|
|
{
|
|
strHeader += _bstr_t(",ns=") + pszNamespace;
|
|
}
|
|
// ru=
|
|
strHeader += _bstr_t(",ru=") + pszRetUrl;
|
|
|
|
// ct=
|
|
_ultow(ct, temp, 10);
|
|
strHeader += _bstr_t(L",ct=") + temp;
|
|
|
|
// kpp
|
|
if (nKpp != -1)
|
|
{
|
|
_ultow(nKpp, temp, 10);
|
|
strHeader += _bstr_t(L",kpp=") + temp;
|
|
}
|
|
|
|
// key version and version
|
|
_ultow(m_pRegistryConfig->getCurrentCryptVersion(), temp, 10);
|
|
strHeader += _bstr_t(L",kv=") + temp;
|
|
strHeader += _bstr_t(L",ver=") + GetVersionString();
|
|
|
|
// lcid
|
|
strHeader += _bstr_t(L",lcid=") + pszLCID;
|
|
// secure level
|
|
if (ulSecureLevel)
|
|
{
|
|
strHeader += _bstr_t(L",seclog=") + _ultow(ulSecureLevel, temp, 10);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// common code to parse user's parameters
|
|
// and get defaults from registry config
|
|
//
|
|
STDMETHODIMP CManager::GetLoginParams(VARIANT vRU,
|
|
VARIANT vTimeWindow,
|
|
VARIANT vForceLogin,
|
|
VARIANT vCoBrand,
|
|
VARIANT vLCID,
|
|
VARIANT vNameSpace,
|
|
VARIANT vKPP,
|
|
VARIANT vUseSecureAuth,
|
|
// these are the processed values
|
|
_bstr_t& strUrl,
|
|
_bstr_t& strReturnUrl,
|
|
UINT& TimeWindow,
|
|
VARIANT_BOOL& ForceLogin,
|
|
time_t& ct,
|
|
_bstr_t& strCBT,
|
|
_bstr_t& strNameSpace,
|
|
int& nKpp,
|
|
ULONG& ulSecureLevel,
|
|
PWSTR pszLCID)
|
|
{
|
|
USES_CONVERSION;
|
|
LPCWSTR url;
|
|
VARIANT freeMe;
|
|
BSTR CBT = NULL, returnUrl = NULL, bstrNameSpace = NULL;
|
|
int hasCB, hasRU, hasLCID, hasTW, hasFL, hasNameSpace, hasKPP, hasUseSec;
|
|
USHORT Lang;
|
|
HRESULT hr = S_OK;
|
|
|
|
//JVP - begin changes
|
|
#ifdef PASSPORT_VERBOSE_MODE_ON
|
|
char szLogString[LOG_STRING_LEN] = "CManager::GetLoginParams, Enter";
|
|
AddVariantAsString(vRU, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(vTimeWindow, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(vForceLogin, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(vCoBrand, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(vLCID, szLogString, sizeof(szLogString));
|
|
AddVariantAsString(vNameSpace, szLogString, sizeof(szLogString));
|
|
g_pTSLogger->AddDateTimeAndLog(szLogString);
|
|
#endif //PASSPORT_VERBOSE_MODE_ON
|
|
//JVP - end changes
|
|
if (!m_pRegistryConfig)
|
|
m_pRegistryConfig = g_config->checkoutRegistryConfig();
|
|
|
|
if (!m_valid || !g_config->isValid() || !m_pRegistryConfig) // Guarantees config is non-null
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportManager, PP_E_NOT_CONFIGURED);
|
|
return PP_E_NOT_CONFIGURED;
|
|
}
|
|
|
|
// Make sure args are of the right type
|
|
if ((hasTW = GetIntArg(vTimeWindow, (int*) &TimeWindow)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if ((hasFL = GetBoolArg(vForceLogin, &ForceLogin)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if ((hasUseSec = GetIntArg(vUseSecureAuth, (int*)&ulSecureLevel)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if ((hasLCID = GetShortArg(vLCID, &Lang)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
if ((hasKPP = GetIntArg(vKPP, &nKpp)) == CV_BAD)
|
|
return E_INVALIDARG;
|
|
hasCB = GetBstrArg(vCoBrand, &CBT);
|
|
if (hasCB == CV_BAD)
|
|
return E_INVALIDARG;
|
|
strCBT = CBT;
|
|
if (hasCB == CV_FREE)
|
|
{
|
|
TAKEOVER_BSTR(CBT);
|
|
}
|
|
|
|
hasRU = GetBstrArg(vRU, &returnUrl);
|
|
if (hasRU == CV_BAD)
|
|
{
|
|
if (hasCB == CV_FREE && CBT) FREE_BSTR(CBT);
|
|
return E_INVALIDARG;
|
|
}
|
|
strReturnUrl = returnUrl;
|
|
if (hasRU == CV_FREE)
|
|
{
|
|
FREE_BSTR(returnUrl);
|
|
}
|
|
|
|
hasNameSpace = GetBstrArg(vNameSpace, &bstrNameSpace);
|
|
if (hasNameSpace == CV_BAD)
|
|
{
|
|
if (hasCB == CV_FREE && CBT) SysFreeString(CBT);
|
|
if (hasRU == CV_FREE && returnUrl) SysFreeString(returnUrl);
|
|
return E_INVALIDARG;
|
|
}
|
|
if (hasNameSpace == CV_OK)
|
|
strNameSpace = bstrNameSpace;
|
|
else
|
|
// default
|
|
strNameSpace = L"";
|
|
if (hasNameSpace == CV_FREE)
|
|
{
|
|
FREE_BSTR(bstrNameSpace);
|
|
}
|
|
|
|
WCHAR *szAUAttrName;
|
|
if (hasUseSec == CV_OK && SECURELEVEL_USE_HTTPS(ulSecureLevel))
|
|
szAUAttrName = L"AuthSecure";
|
|
else
|
|
szAUAttrName = L"Auth";
|
|
|
|
CNexusConfig* cnc = g_config->checkoutNexusConfig();
|
|
|
|
if (hasLCID == CV_DEFAULT)
|
|
Lang = m_pRegistryConfig->getDefaultLCID();
|
|
if (hasKPP == CV_DEFAULT)
|
|
nKpp = -1;
|
|
|
|
// convert the LCID to str for tweener ...
|
|
_itow((int)Lang, pszLCID, 10);
|
|
VariantInit(&freeMe);
|
|
|
|
if (!m_pRegistryConfig->DisasterModeP())
|
|
{
|
|
// If I'm authenticated, get my domain specific url
|
|
WCHAR UrlBuf[MAX_URL_LENGTH];
|
|
if (m_ticketValid && m_profileValid)
|
|
{
|
|
HRESULT hr = m_piProfile->get_ByIndex(MEMBERNAME_INDEX, &freeMe);
|
|
if (hr != S_OK || freeMe.vt != VT_BSTR)
|
|
{
|
|
cnc->getDomainAttribute(L"Default",
|
|
szAUAttrName,
|
|
sizeof(UrlBuf)/sizeof(WCHAR),
|
|
UrlBuf,
|
|
Lang);
|
|
strUrl = UrlBuf;
|
|
}
|
|
else
|
|
{
|
|
LPCWSTR psz = wcsrchr(freeMe.bstrVal, L'@');
|
|
cnc->getDomainAttribute(psz ? psz+1 : L"Default",
|
|
szAUAttrName,
|
|
sizeof(UrlBuf)/sizeof(WCHAR),
|
|
UrlBuf,
|
|
Lang);
|
|
strUrl = UrlBuf;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cnc->getDomainAttribute(L"Default",
|
|
szAUAttrName,
|
|
sizeof(UrlBuf)/sizeof(WCHAR),
|
|
UrlBuf,
|
|
Lang);
|
|
strUrl = UrlBuf;
|
|
}
|
|
}
|
|
else
|
|
strUrl = A2W(m_pRegistryConfig->getDisasterUrl());
|
|
|
|
time(&ct);
|
|
|
|
if (hasTW == CV_DEFAULT)
|
|
TimeWindow = m_pRegistryConfig->getDefaultTicketAge();
|
|
if (hasFL == CV_DEFAULT)
|
|
ForceLogin = m_pRegistryConfig->forceLoginP() ? VARIANT_TRUE : VARIANT_FALSE;
|
|
if (hasCB == CV_DEFAULT)
|
|
strCBT = m_pRegistryConfig->getDefaultCoBrand();
|
|
if (hasRU == CV_DEFAULT)
|
|
strReturnUrl = m_pRegistryConfig->getDefaultRU() ?
|
|
m_pRegistryConfig->getDefaultRU() : L"";
|
|
|
|
if ((TimeWindow != 0 && TimeWindow < PPM_TIMEWINDOW_MIN) || TimeWindow > PPM_TIMEWINDOW_MAX)
|
|
{
|
|
AtlReportError(CLSID_Manager, (LPCOLESTR) PP_E_INVALID_TIMEWINDOWSTR,
|
|
IID_IPassportManager, PP_E_INVALID_TIMEWINDOW);
|
|
hr = PP_E_INVALID_TIMEWINDOW;
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// get ticket & profile from auth header
|
|
// params:
|
|
// AuthHeader - [in/out] contents of HTTP_Authorization header
|
|
// pszTicket - [out] ptr to the ticket part in the header
|
|
// pszProfile -[out] ptr to the profile
|
|
// pwszF - [out] ptr to error coming in the header
|
|
// Auth header contents is changed as a side effect of the function
|
|
//
|
|
static VOID GetTicketAndProfileFromHeader(PWSTR pszAuthHeader,
|
|
PWSTR& pszTicket,
|
|
PWSTR& pszProfile,
|
|
PWSTR& pszF)
|
|
{
|
|
if (pszAuthHeader && *pszAuthHeader)
|
|
{
|
|
// format is 'Authorization: from-PP='t=xxx&p=xxx'
|
|
PWSTR pwsz = wcsstr(pszAuthHeader, L"from-PP");
|
|
if (pwsz)
|
|
{
|
|
// ticket and profile are enclosed in ''. Not very strict parsing indeed ....
|
|
while(*pwsz != L'\'' && *pwsz)
|
|
pwsz++;
|
|
if (*pwsz++)
|
|
{
|
|
if (*pwsz == L'f')
|
|
{
|
|
// error case
|
|
pszF = pwsz+2;
|
|
}
|
|
else
|
|
{
|
|
// ticket and profile ...
|
|
_ASSERT(*pwsz == L't');
|
|
pszTicket = pwsz+2;
|
|
while(*pwsz != L'&' && *pwsz)
|
|
pwsz++;
|
|
if (*pwsz)
|
|
*pwsz++ = L'\0', pszProfile = pwsz+2;
|
|
_ASSERT(*pwsz == L'p');
|
|
// finally remove the last '
|
|
}
|
|
// set \0 terminator
|
|
while(*pwsz != L'\'' && *pwsz)
|
|
pwsz++;
|
|
if (*pwsz)
|
|
*pwsz = L'\0';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IPassportService implementation
|
|
|
|
STDMETHODIMP CManager::Initialize(BSTR configfile, IServiceProvider* p)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Initialized?
|
|
if (!g_config->isValid()) // This calls UpdateNow if not yet initialized.
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportService, PP_E_NOT_CONFIGURED);
|
|
hr = PP_E_NOT_CONFIGURED;
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CManager::Shutdown()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CManager::ReloadState(IServiceProvider*)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Initialize.
|
|
|
|
if(!g_config->PrepareUpdate(TRUE))
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportService, PP_E_NOT_CONFIGURED);
|
|
hr = PP_E_NOT_CONFIGURED;
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CManager::CommitState(IServiceProvider*)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Finish the two phase update.
|
|
if(!g_config->CommitUpdate())
|
|
{
|
|
AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
|
|
IID_IPassportService, PP_E_NOT_CONFIGURED);
|
|
hr = PP_E_NOT_CONFIGURED;
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CManager::DumpState(BSTR* pbstrState)
|
|
{
|
|
ATLASSERT( *pbstrState != NULL &&
|
|
"CManager:DumpState - "
|
|
"Are you sure you want to hand me a non-null BSTR?" );
|
|
|
|
g_config->Dump(pbstrState);
|
|
|
|
return S_OK;
|
|
}
|
|
|