/**********************************************************************/ /** Microsoft Passport **/ /** Copyright(c) Microsoft Corporation, 1999 - 2001 **/ /**********************************************************************/ /* RegistryConfig.cpp FILE HISTORY: */ // RegistryConfig.cpp: implementation of the CRegistryConfig class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "RegistryConfig.h" #include "KeyCrypto.h" #include "passport.h" #include "keyver.h" #include "dsysdbg.h" extern BOOL g_bRegistering; #define PASSPORT_KEY L"Software\\Microsoft\\Passport\\" #define PASSPORT_SITES_SUBKEY L"Sites" //=========================================================================== // // Functions for verbose logging // // define for logging with dsysdbg.lib DEFINE_DEBUG2(Passport); DEBUG_KEY PassportDebugKeys[] = { {DEB_TRACE, "Trace"}, {0, NULL} }; BOOL g_fLoggingOn = FALSE; #define MAX_LOG_STRLEN 512 void PassportLog(CHAR* Format, ...) { if (g_fLoggingOn) { if (NULL != Format) { SYSTEMTIME SysTime; CHAR rgch[MAX_LOG_STRLEN]; int i, cch; // put the time at the front cch = sizeof(rgch) / sizeof(rgch[0]) - 1; GetSystemTime(&SysTime); i = GetDateFormatA ( LOCALE_USER_DEFAULT, // locale for which date is to be formatted 0, // flags specifying function options &SysTime, // date to be formatted "ddd',' MMM dd yy ", // date format string rgch, // buffer for storing formatted string cch); // size of buffer if (i > 0) i--; i += GetTimeFormatA ( LOCALE_USER_DEFAULT, // locale for which date is to be formatted 0, // flags specifying function options &SysTime, // date to be formatted "HH':'mm':'ss ", // time format string rgch + i, // buffer for storing formatted string cch - i); // size of buffer if (i > 0) i--; va_list ArgList; \ va_start(ArgList, Format); \ _vsnprintf(rgch + i, cch - i, Format, ArgList); rgch[MAX_LOG_STRLEN - 1] = '\0'; PassportDebugPrint(DEB_TRACE, rgch); } } } // // This function opens the logging file. "%WINDIR%\system32\microsoftpassport\passport.log" // HANDLE OpenPassportLoggingFile() { WCHAR szLogPath[MAX_PATH + 13] = {0}; UINT cchMax = sizeof(szLogPath) / sizeof(szLogPath[0]) - 1; UINT cch; HANDLE hLogFile = INVALID_HANDLE_VALUE; cch = GetWindowsDirectory(szLogPath, cchMax); if ((0 == cch) || (cch > cchMax)) { goto Cleanup; } if (NULL == wcsncat(szLogPath, L"\\system32\\microsoftpassport\\passport.log", cchMax - cch)) { goto Cleanup; } szLogPath[MAX_PATH] = L'\0'; hLogFile = CreateFileW(szLogPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, //&sa, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE != hLogFile) { SetFilePointer(hLogFile, 0, NULL, FILE_END); } Cleanup: return hLogFile; } // // This function checks if logging is supposed to be enabled and if it is then // it opens the log file and sets the appropriate global variables. // If logging is supposed to be off then the appropriate variables are also // changed to the correct values. // VOID CheckLogging(HKEY hPassport) { DWORD dwVerbose = 0; DWORD cb = sizeof(DWORD); HANDLE hLogFile = INVALID_HANDLE_VALUE; // first run off and get the reg value, if this call fails we simply assume no logging if (ERROR_SUCCESS == RegQueryValueExW(hPassport, L"Verbose", NULL, NULL, (LPBYTE)&dwVerbose, &cb)) { // only start logging if it is off and only stop logging if it's already on if (!g_fLoggingOn && (0 != dwVerbose)) { if (INVALID_HANDLE_VALUE != (hLogFile = OpenPassportLoggingFile())) { // set the logging file handle PassportSetLoggingFile(hLogFile); // set it to log to a file PassportSetLoggingOption(TRUE); g_fLoggingOn = TRUE; PassportLog("Start Logging\r\n"); } } else if (g_fLoggingOn && (0 == dwVerbose)) { PassportLog("Stop Logging\r\n"); PassportSetLoggingOption(FALSE); g_fLoggingOn = FALSE; } } } void InitLogging() { // // Initialize the logging stuff // PassportInitDebug(PassportDebugKeys); PassportInfoLevel = DEB_TRACE; } void CloseLogging() { PassportUnloadDebug(); } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// using namespace ATL; //=========================================================================== // // CRegistryConfig // CRegistryConfig::CRegistryConfig( LPSTR szSiteName ) : m_siteId(0), m_valid(FALSE), m_ticketPath(NULL), m_profilePath(NULL), m_securePath(NULL), m_hostName(NULL), m_hostIP(NULL), m_ticketDomain(NULL), m_profileDomain(NULL), m_secureDomain(NULL), m_disasterUrl(NULL), m_disasterMode(FALSE), m_forceLogin(FALSE), m_setCookies(TRUE), m_szReason(NULL), m_refs(0), m_coBrand(NULL), m_ru(NULL), m_ticketAge(1800), m_bInDA(FALSE), m_hkPassport(NULL), m_secureLevel(0),m_notUseHTTPOnly(0), m_pcrypts(NULL), m_pcryptValidTimes(NULL), m_KPP(-1),m_NameSpace(NULL),m_ExtraParams(NULL) { // Get site id, key from registry DWORD bufSize = sizeof(m_siteId); LONG lResult; HKEY hkSites = NULL; DWORD dwBufSize = 0, disMode; DWORD dwLCID; // // Record the current DLL state in case it changes // partway through this routine. // BOOL fRegistering = g_bRegistering; if(szSiteName) { lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, PASSPORT_KEY PASSPORT_SITES_SUBKEY, 0, KEY_READ, &hkSites); if(lResult != ERROR_SUCCESS) { m_valid = FALSE; setReason(L"Invalid site name. Site not found."); goto Cleanup; } lResult = RegOpenKeyExA( hkSites, szSiteName, 0, KEY_READ, &m_hkPassport); if(lResult != ERROR_SUCCESS) { m_valid = FALSE; setReason(L"Invalid site name. Site not found."); goto Cleanup; } } else { lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, PASSPORT_KEY, 0, KEY_READ, &m_hkPassport ); if(lResult != ERROR_SUCCESS) { m_valid = FALSE; setReason(L"No RegKey HKLM\\SOFTWARE\\Microsoft\\Passport"); goto Cleanup; } } // Get the current key bufSize = sizeof(m_currentKey); if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("CurrentKey"), NULL, NULL, (LPBYTE)&m_currentKey, &bufSize)) { m_valid = FALSE; setReason(L"No CurrentKey defined in the registry."); goto Cleanup; } if(m_currentKey < KEY_VERSION_MIN || m_currentKey > KEY_VERSION_MAX) { m_valid = FALSE; setReason(L"Invalid CurrentKey value in the registry."); goto Cleanup; } // Get default LCID bufSize = sizeof(dwLCID); if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("LanguageID"), NULL, NULL, (LPBYTE)&dwLCID, &bufSize)) { dwLCID = 0; } m_lcid = static_cast(dwLCID & 0xFFFF); // Get disaster mode status bufSize = sizeof(disMode); if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("StandAlone"), NULL, NULL, (LPBYTE)&disMode, &bufSize)) { m_disasterMode = FALSE; } else if (disMode != 0) { m_disasterMode = TRUE; } // Get the disaster URL if (m_disasterMode) { if (ERROR_SUCCESS == RegQueryValueEx(m_hkPassport, _T("DisasterURL"), NULL, NULL, NULL, &dwBufSize) && dwBufSize > 1) { m_disasterUrl = new WCHAR[dwBufSize]; if ((!m_disasterUrl) || ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("DisasterURL"), NULL, NULL, (LPBYTE) m_disasterUrl, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading DisasterURL from registry. (Query worked, but couldn't retrieve data)"); goto Cleanup; } } else { m_valid = FALSE; setReason(L"DisasterURL missing from registry."); goto Cleanup; } } // // This function wraps the allocations of the crypt objects in a try/except // since the objects themselves do a poor job in low memory conditions // try { m_pcrypts = new INT2CRYPT; m_pcryptValidTimes = new INT2TIME; } catch(...) { m_valid = FALSE; setReason(L"Out of memory."); goto Cleanup; } if (!m_pcrypts || !m_pcryptValidTimes) { m_valid = FALSE; setReason(L"Out of memory."); goto Cleanup; } m_valid = readCryptoKeys(m_hkPassport); if (!m_valid) { if (!m_szReason) setReason(L"Error reading Passport crypto keys from registry."); goto Cleanup; } if (m_pcrypts->count(m_currentKey) == 0) { m_valid = FALSE; if (!m_szReason) setReason(L"Error reading Passport crypto keys from registry."); goto Cleanup; } // Get the optional default cobrand if (ERROR_SUCCESS == RegQueryValueExW(m_hkPassport, L"CoBrandTemplate", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 2) { m_coBrand = (WCHAR*) new char[dwBufSize]; if (!m_coBrand || ERROR_SUCCESS != RegQueryValueExW(m_hkPassport, L"CoBrandTemplate", NULL, NULL, (LPBYTE) m_coBrand, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading CoBrand from registry. (Query worked, but couldn't retrieve data)"); goto Cleanup; } } } // Get the optional default return URL if (ERROR_SUCCESS == RegQueryValueExW(m_hkPassport, L"ReturnURL", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 2) { m_ru = (WCHAR*) new char[dwBufSize]; if (!m_ru || ERROR_SUCCESS != RegQueryValueExW(m_hkPassport, L"ReturnURL", NULL, NULL, (LPBYTE) m_ru, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading ReturnURL from registry. (Query worked, but couldn't retrieve data)"); goto Cleanup; } } } // Get the host name if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "HostName", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 1) { m_hostName = new char[dwBufSize]; if (m_hostName == NULL || ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "HostName", NULL, NULL, (LPBYTE) m_hostName, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading HostName from registry. (Query worked, but couldn't retrieve data)"); goto Cleanup; } } } // Get the host ip if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "HostIP", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 1) { m_hostIP = new char[dwBufSize]; if (!m_hostIP || ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "HostIP", NULL, NULL, (LPBYTE) m_hostIP, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading HostIP from registry. (Query worked, but couldn't retrieve data)"); goto Cleanup; } } } // Get the optional domain to set ticket cookies into if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "TicketDomain", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 1) { m_ticketDomain = new char[dwBufSize]; if (!m_ticketDomain || ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "TicketDomain", NULL, NULL, (LPBYTE) m_ticketDomain, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading TicketDomain from registry. (Query worked, but couldn't retrieve data)"); goto Cleanup; } } } // Get the optional domain to set profile cookies into if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "ProfileDomain", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 1) { m_profileDomain = new char[dwBufSize]; if (!m_profileDomain || ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "ProfileDomain", NULL, NULL, (LPBYTE) m_profileDomain, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading ProfileDomain from registry. (Query worked, but couldn't retrieve data)"); goto Cleanup; } } } // Get the optional domain to set secure cookies into if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "SecureDomain", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 1) { m_secureDomain = new char[dwBufSize]; if (!m_secureDomain || ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "SecureDomain", NULL, NULL, (LPBYTE) m_secureDomain, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading SecureDomain from registry. (Query worked, but couldn't retrieve data)"); goto Cleanup; } } } // Get the optional path to set ticket cookies into if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "TicketPath", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 1) { m_ticketPath = new char[dwBufSize]; if (!m_ticketPath || ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "TicketPath", NULL, NULL, (LPBYTE) m_ticketPath, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading TicketPath from registry. (Query worked, but couldn't retrieve data)"); goto Cleanup; } } } // Get the optional path to set profile cookies into if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "ProfilePath", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 1) { m_profilePath = new char[dwBufSize]; if (!m_profilePath || ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "ProfilePath", NULL, NULL, (LPBYTE) m_profilePath, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading ProfilePath from registry. (Query worked, but couldn't retrieve data)"); goto Cleanup; } } } // Get the optional path to set secure cookies into if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "SecurePath", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 1) { m_securePath = new char[dwBufSize]; if (!m_securePath || ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "SecurePath", NULL, NULL, (LPBYTE) m_securePath, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading SecurePath from registry. (Query worked, but couldn't retrieve data)"); goto Cleanup; } } } bufSize = sizeof(m_siteId); // Now get the site id if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("SiteId"), NULL, NULL, (LPBYTE)&m_siteId, &bufSize)) { m_valid = FALSE; setReason(L"No SiteId specified in registry"); goto Cleanup; } // And the default ticket time window if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("TimeWindow"), NULL, NULL, (LPBYTE)&m_ticketAge, &bufSize)) { m_ticketAge = 1800; } bufSize = sizeof(DWORD); DWORD forced; if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("ForceSignIn"), NULL, NULL, (LPBYTE)&forced, &bufSize)) { m_forceLogin = FALSE; } else { m_forceLogin = forced == 0 ? FALSE : TRUE; } bufSize = sizeof(DWORD); DWORD noSetCookies; if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("DisableCookies"), NULL, NULL, (LPBYTE)&noSetCookies, &bufSize)) { m_setCookies = TRUE; } else { m_setCookies = !noSetCookies; } bufSize = sizeof(DWORD); DWORD dwInDA; if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("InDA"), NULL, NULL, (LPBYTE)&dwInDA, &bufSize)) { m_bInDA = FALSE; } else { m_bInDA = (dwInDA != 0); } bufSize = sizeof(m_secureLevel); // Now get the site id if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("SecureLevel"), NULL, NULL, (LPBYTE)&m_secureLevel, &bufSize)) { m_secureLevel = 0; } bufSize = sizeof(m_notUseHTTPOnly); // Now get the NotUseHTTPOnly if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("NotUseHTTPOnly"), NULL, NULL, (LPBYTE)&m_notUseHTTPOnly, &bufSize)) { m_notUseHTTPOnly = 0; } // Get the KPP value bufSize = sizeof(m_KPP); if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("KPP"), NULL, NULL, (LPBYTE)&m_KPP, &bufSize)) { m_KPP = -1; } // Get the optional namespace if (ERROR_SUCCESS == RegQueryValueExW(m_hkPassport, L"NameSpace", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 2) { m_NameSpace = (WCHAR*) new char[dwBufSize]; if (!m_NameSpace || ERROR_SUCCESS != RegQueryValueExW(m_hkPassport, L"NameSpace", NULL, NULL, (LPBYTE) m_NameSpace, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading NameSpace from registry."); goto Cleanup; } } } // Get the optional extra parameters if (ERROR_SUCCESS == RegQueryValueExW(m_hkPassport, L"ExtraParams", NULL, NULL, NULL, &dwBufSize)) { if (dwBufSize > 2) { m_ExtraParams = (WCHAR*) new char[dwBufSize]; if (!m_ExtraParams || ERROR_SUCCESS != RegQueryValueExW(m_hkPassport, L"ExtraParams", NULL, NULL, (LPBYTE) m_ExtraParams, &dwBufSize)) { m_valid = FALSE; setReason(L"Error reading ExtraParams from registry."); goto Cleanup; } } } // // Check for the verbose flag in the registry and do the appropriate stuff to either // turn logging on or off. // // Only check if this is the default site. // if (!szSiteName) { CheckLogging(m_hkPassport); } m_szReason = NULL; m_valid = TRUE; Cleanup: if ( NULL != hkSites ) { RegCloseKey(hkSites); } if (m_valid == FALSE && !fRegistering) { g_pAlert->report(PassportAlertInterface::ERROR_TYPE, PM_INVALID_CONFIGURATION, m_szReason); } return; } //=========================================================================== // // ~CRegistryConfig // CRegistryConfig::~CRegistryConfig() { if (m_pcrypts) { if (!m_pcrypts->empty()) { INT2CRYPT::iterator itb = m_pcrypts->begin(); for (; itb != m_pcrypts->end(); itb++) { delete itb->second; } m_pcrypts->clear(); } delete m_pcrypts; } // may be a leak that we don't iterate through and delete the elements if (m_pcryptValidTimes) { delete m_pcryptValidTimes; } if (m_szReason) SysFreeString(m_szReason); if (m_ticketDomain) delete[] m_ticketDomain; if (m_profileDomain) delete[] m_profileDomain; if (m_secureDomain) delete[] m_secureDomain; if (m_ticketPath) delete[] m_ticketPath; if (m_profilePath) delete[] m_profilePath; if (m_securePath) delete[] m_securePath; if (m_disasterUrl) delete[] m_disasterUrl; if (m_coBrand) delete[] m_coBrand; if (m_hostName) delete[] m_hostName; if (m_hostIP) delete[] m_hostIP; if (m_ru) delete[] m_ru; if (m_NameSpace) delete[] m_NameSpace; if (m_ExtraParams) delete[] m_ExtraParams; if (m_hkPassport != NULL) { RegCloseKey(m_hkPassport); } } //=========================================================================== // // GetCurrentConfig // #define __MAX_STRING_LENGTH__ 1024 HRESULT CRegistryConfig::GetCurrentConfig(LPCWSTR name, VARIANT* pVal) { if(m_hkPassport == NULL || !m_valid) { AtlReportError(CLSID_Profile, PP_E_SITE_NOT_EXISTSSTR, IID_IPassportProfile, PP_E_SITE_NOT_EXISTS); return PP_E_SITE_NOT_EXISTS; } if(!name || !pVal) return E_INVALIDARG; HRESULT hr = S_OK; BYTE *pBuf = NULL; ATL::CComVariant v; BYTE dataBuf[__MAX_STRING_LENGTH__]; DWORD bufLen = sizeof(dataBuf); BYTE *pData = dataBuf; DWORD dwErr = ERROR_SUCCESS; DWORD dataType = 0; dwErr = RegQueryValueEx(m_hkPassport, name, NULL, &dataType, (LPBYTE)pData, &bufLen); if (dwErr == ERROR_MORE_DATA) { pBuf = (PBYTE)malloc(bufLen); if (!pBuf) { hr = E_OUTOFMEMORY; goto Exit; } pData = pBuf; dwErr = RegQueryValueEx(m_hkPassport, name, NULL, &dataType, (LPBYTE)pData, &bufLen); } if (dwErr != ERROR_SUCCESS) { hr = PP_E_NO_ATTRIBUTE; AtlReportError(CLSID_Manager, PP_E_NO_ATTRIBUTESTR, IID_IPassportManager3, PP_E_NO_ATTRIBUTE); } else { switch(dataType) { case REG_DWORD: case REG_DWORD_BIG_ENDIAN: { DWORD* pdw = (DWORD*)pData; v = (long)*pdw; } break; case REG_SZ: case REG_EXPAND_SZ: { LPCWSTR pch = (LPCWSTR)pData; v = (LPCWSTR)pch; } break; default: AtlReportError(CLSID_Manager, PP_E_TYPE_NOT_SUPPORTEDSTR, IID_IPassportManager, PP_E_TYPE_NOT_SUPPORTED); hr = PP_E_TYPE_NOT_SUPPORTED; break; } } Exit: if(pBuf) free(pBuf); if (hr == S_OK) hr = v.Detach(pVal); return hr; } #define MAX_ENCKEYSIZE 1024 //=========================================================================== // // readCryptoKeys // BOOL CRegistryConfig::readCryptoKeys( HKEY hkPassport ) { LONG lResult; BOOL retVal = FALSE; HKEY hkDataKey = NULL, hkTimeKey = NULL; DWORD iterIndex = 0, keySize, keyTime, keyNumSize; BYTE encKeyBuf[MAX_ENCKEYSIZE]; int kNum; TCHAR szKeyNum[4]; CKeyCrypto kc; int foundKeys = 0; HANDLE hToken = NULL; if (OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hToken)) { if (FALSE == RevertToSelf()) { setReason(L"Unable to revert to self"); goto Cleanup; } } // Open both the keydata and keytimes key, // if there's no keytimes key, we'll assume all keys are valid forever, // or more importantly, we won't break if that key isn't there lResult = RegOpenKeyEx(hkPassport, TEXT("KeyData"), 0, KEY_READ, &hkDataKey); if(lResult != ERROR_SUCCESS) { setReason(L"No Valid Crypto Keys"); goto Cleanup; } RegOpenKeyEx(hkPassport, TEXT("KeyTimes"), 0, KEY_READ, &hkTimeKey); // Ok, now enumerate the KeyData keys and create crypt objects while (1) { keySize = sizeof(encKeyBuf); keyNumSize = sizeof(szKeyNum) >> (sizeof(TCHAR) - 1); lResult = RegEnumValue(hkDataKey, iterIndex++, szKeyNum, &keyNumSize, NULL, NULL, (LPBYTE)&(encKeyBuf[0]), &keySize); if (lResult != ERROR_SUCCESS) { break; } kNum = KeyVerC2I(szKeyNum[0]); if (kNum > 0) { DATA_BLOB iBlob; DATA_BLOB oBlob = {0}; iBlob.cbData = keySize; iBlob.pbData = (LPBYTE)&(encKeyBuf[0]); if(kc.decryptKey(&iBlob, &oBlob) != S_OK) { g_pAlert->report(PassportAlertInterface::ERROR_TYPE, PM_CANT_DECRYPT_CONFIG); break; } else { // Now set up a crypt object CCoCrypt* cr = new CCoCrypt(); if (NULL == cr) { if(oBlob.pbData) { RtlSecureZeroMemory(oBlob.pbData, oBlob.cbData); ::LocalFree(oBlob.pbData); ZeroMemory(&oBlob, sizeof(oBlob)); } setReason(L"Out of memory"); goto Cleanup; } BSTR km = ::SysAllocStringByteLen((LPSTR)oBlob.pbData, oBlob.cbData); if (NULL == km) { if(oBlob.pbData) { RtlSecureZeroMemory(oBlob.pbData, oBlob.cbData); ::LocalFree(oBlob.pbData); ZeroMemory(&oBlob, sizeof(oBlob)); } delete cr; setReason(L"Out of memory"); goto Cleanup; } cr->setKeyMaterial(km); ::SysFreeString(km); if(oBlob.pbData) { RtlSecureZeroMemory(oBlob.pbData, oBlob.cbData); ::LocalFree(oBlob.pbData); ZeroMemory(&oBlob, sizeof(oBlob)); } // Add it to the bucket... // wrap the STL calls since in low memory conditions they can AV try { INT2CRYPT::value_type pMapVal(kNum, cr); m_pcrypts->insert(pMapVal); } catch(...) { setReason(L"Out of memory"); goto Cleanup; } foundKeys++; keySize = sizeof(DWORD); if (RegQueryValueEx(hkTimeKey, szKeyNum, NULL,NULL,(LPBYTE)&keyTime,&keySize) == ERROR_SUCCESS && (m_currentKey != kNum)) { // wrap the STL calls since in low memory conditions they can AV try { INT2TIME::value_type pTimeVal(kNum, keyTime); m_pcryptValidTimes->insert(pTimeVal); } catch(...) { setReason(L"Out of memory"); goto Cleanup; } } } } if (iterIndex > 100) // Safety latch goto Cleanup; } retVal = foundKeys > 0 ? TRUE : FALSE; Cleanup: if (hToken) { // put the impersonation token back if (!SetThreadToken(NULL, hToken)) { setReason(L"Unable to set thread token"); retVal = FALSE; } CloseHandle(hToken); } if (hkDataKey) RegCloseKey(hkDataKey); if (hkTimeKey) RegCloseKey(hkTimeKey); return retVal; } //=========================================================================== // // getCrypt // CCoCrypt* CRegistryConfig::getCrypt(int keyNum, time_t* validUntil) { if (validUntil) // If they asked for the validUntil information { INT2TIME::const_iterator timeIt = m_pcryptValidTimes->find(keyNum); if (timeIt == m_pcryptValidTimes->end()) *validUntil = 0; else *validUntil = (*timeIt).second; } // Now look up the actual crypt object INT2CRYPT::const_iterator it = m_pcrypts->find(keyNum); if (it == m_pcrypts->end()) return NULL; return (*it).second; } //=========================================================================== // // getFailureString // BSTR CRegistryConfig::getFailureString() { if (m_valid) return NULL; return m_szReason; } //=========================================================================== // // setReason // void CRegistryConfig::setReason(LPTSTR reason) { if (m_szReason) SysFreeString(m_szReason); m_szReason = SysAllocString(reason); } //=========================================================================== // // AddRef // CRegistryConfig* CRegistryConfig::AddRef() { InterlockedIncrement(&m_refs); return this; } //=========================================================================== // // Release // void CRegistryConfig::Release() { long refs = InterlockedDecrement(&m_refs); if (refs == 0) delete this; } //=========================================================================== // // GetHostName // long CRegistryConfig::GetHostName( LPSTR szSiteName, LPSTR szHostName, LPDWORD lpdwHostNameBufLen ) { long lResult; HKEY hkSites = NULL; HKEY hkPassport = NULL; if(!szSiteName || szSiteName[0] == '\0') { lResult = E_UNEXPECTED; goto Cleanup; } lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, PASSPORT_KEY PASSPORT_SITES_SUBKEY, 0, KEY_READ, &hkSites ); if(lResult != ERROR_SUCCESS) goto Cleanup; lResult = RegOpenKeyExA(hkSites, szSiteName, 0, KEY_READ, &hkPassport ); if(lResult != ERROR_SUCCESS) goto Cleanup; lResult = RegQueryValueExA(hkPassport, "HostName", NULL, NULL, (LPBYTE)szHostName, lpdwHostNameBufLen ); Cleanup: if(hkSites != NULL) RegCloseKey(hkSites); if(hkPassport != NULL) RegCloseKey(hkPassport); return lResult; }