You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1161 lines
35 KiB
1161 lines
35 KiB
/**********************************************************************/
|
|
/** 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<short>(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;
|
|
}
|