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.
659 lines
16 KiB
659 lines
16 KiB
//+-------------------------------------------------------------------------
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1995 - 1999
|
|
//
|
|
// File: dblog.cpp
|
|
//
|
|
// Contents: Database Log Event APIs
|
|
//
|
|
// Functions: I_DBLogCrypt32Event
|
|
// I_DBLogAttach
|
|
// I_DBLogDetach
|
|
//
|
|
// History: 11-Oct-00 philh created
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
#include "global.hxx"
|
|
#include <dbgdef.h>
|
|
|
|
#ifdef ROOT_AUTO_UPDATE_DOGFOOD
|
|
|
|
#ifdef STATIC
|
|
#undef STATIC
|
|
#endif
|
|
#define STATIC
|
|
|
|
#include "sql.h"
|
|
#include "sqlext.h"
|
|
#include "sqltypes.h"
|
|
#include "odbcss.h"
|
|
|
|
#define SQL_CALL_SUCCESS(status) (status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO)
|
|
|
|
#if DBG || DEBUG
|
|
#define DebugPrint(a) _DebugPrintW a
|
|
void
|
|
__cdecl
|
|
_DebugPrintW(
|
|
LPCWSTR szFormat,
|
|
...
|
|
)
|
|
{
|
|
WCHAR szBuffer[512];
|
|
va_list ap;
|
|
|
|
va_start(ap, szFormat);
|
|
vswprintf(szBuffer, szFormat, ap);
|
|
OutputDebugStringW(szBuffer);
|
|
}
|
|
|
|
int debugLine = __LINE__;
|
|
#define DEBUG_MARKER debugLine = __LINE__
|
|
|
|
#else
|
|
|
|
#define DebugPrint(a)
|
|
#define DEBUG_MARKER
|
|
|
|
#endif
|
|
|
|
#define SHA1_HASH_LEN 20
|
|
#define SHA1_HASH_NAME_LEN (2 * SHA1_HASH_LEN)
|
|
|
|
typedef struct _DBLOG_EVENT_DATA {
|
|
DWORD dwStatus;
|
|
DWORD dwCPU64;
|
|
TIMESTAMP_STRUCT TimeStamp;
|
|
WCHAR wszOperation[16];
|
|
WCHAR wszHash[SHA1_HASH_NAME_LEN + 1];
|
|
WCHAR wszSubject[64];
|
|
WCHAR wszBuildLab[64];
|
|
WCHAR wszMachineName[32];
|
|
} DBLOG_EVENT_DATA, *PDBLOG_EVENT_DATA;
|
|
|
|
|
|
void
|
|
I_DBLogAttach()
|
|
{
|
|
}
|
|
|
|
void
|
|
I_DBLogDetach()
|
|
{
|
|
}
|
|
|
|
DWORD WINAPI I_DBLogCrypt32EventThreadProc(
|
|
LPVOID lpThreadParameter
|
|
)
|
|
{
|
|
PDBLOG_EVENT_DATA pEventData = (PDBLOG_EVENT_DATA) lpThreadParameter;
|
|
|
|
SQLRETURN RetCode = SQL_SUCCESS;
|
|
HSTMT hStmt = NULL;
|
|
HENV hEnv = NULL, hDbc = NULL;
|
|
|
|
__try {
|
|
__try {
|
|
RetCode = SQLAllocHandle(
|
|
SQL_HANDLE_ENV,
|
|
SQL_NULL_HANDLE,
|
|
&hEnv
|
|
);
|
|
|
|
if(!SQL_CALL_SUCCESS(RetCode)) {
|
|
DEBUG_MARKER;
|
|
__leave;
|
|
}
|
|
|
|
RetCode = SQLSetEnvAttr(
|
|
hEnv,
|
|
SQL_ATTR_ODBC_VERSION,
|
|
(SQLPOINTER) SQL_OV_ODBC3,
|
|
SQL_IS_INTEGER
|
|
);
|
|
|
|
if(!SQL_CALL_SUCCESS(RetCode)) {
|
|
DEBUG_MARKER;
|
|
__leave;
|
|
}
|
|
|
|
RetCode = SQLAllocHandle(
|
|
SQL_HANDLE_DBC,
|
|
hEnv,
|
|
&hDbc
|
|
);
|
|
|
|
if(!SQL_CALL_SUCCESS(RetCode)) {
|
|
DEBUG_MARKER;
|
|
__leave;
|
|
}
|
|
|
|
RetCode = SQLSetConnectAttr(
|
|
hDbc,
|
|
SQL_ATTR_LOGIN_TIMEOUT,
|
|
(SQLPOINTER) 120,
|
|
SQL_IS_UINTEGER
|
|
);
|
|
|
|
if(!SQL_CALL_SUCCESS(RetCode)) {
|
|
DEBUG_MARKER;
|
|
__leave;
|
|
}
|
|
|
|
RetCode = SQLSetConnectAttr(
|
|
hDbc,
|
|
SQL_COPT_SS_INTEGRATED_SECURITY,
|
|
(SQLPOINTER) SQL_IS_OFF,
|
|
SQL_IS_INTEGER
|
|
);
|
|
|
|
if(!SQL_CALL_SUCCESS(RetCode)) {
|
|
DEBUG_MARKER;
|
|
__leave;
|
|
}
|
|
|
|
{
|
|
SQLWCHAR szConnect[1024];
|
|
SQLSMALLINT cbConnect = 0;
|
|
|
|
SQLWCHAR szInConnect[] = L"DRIVER=SQL Server;SERVER=kschutz-team2;UID=crypt32;PWD=crypt32;DATABASE=Crypt32";
|
|
|
|
RetCode = SQLDriverConnectW(
|
|
hDbc,
|
|
NULL,
|
|
szInConnect,
|
|
SQL_NTS,
|
|
szConnect,
|
|
sizeof(szConnect) / sizeof(szConnect[0]),
|
|
&cbConnect,
|
|
SQL_DRIVER_NOPROMPT
|
|
);
|
|
|
|
if(!SQL_CALL_SUCCESS(RetCode)) {
|
|
DEBUG_MARKER;
|
|
__leave;
|
|
}
|
|
}
|
|
|
|
RetCode = SQLAllocHandle(
|
|
SQL_HANDLE_STMT,
|
|
hDbc,
|
|
&hStmt
|
|
);
|
|
|
|
if(!SQL_CALL_SUCCESS(RetCode)) {
|
|
DEBUG_MARKER;
|
|
__leave;
|
|
}
|
|
|
|
WCHAR szStatement[] =
|
|
L"INSERT INTO AddRoot2 ("
|
|
L"OPERATION,"
|
|
L"STATUS,"
|
|
L"TIMESTAMP,"
|
|
L"HASH,"
|
|
L"SUBJECT,"
|
|
L"MACHINENAME,"
|
|
L"BUILDLAB,"
|
|
L"CPU64"
|
|
L") VALUES (?,?,?,?,?,?,?,?)";
|
|
|
|
RetCode = SQLPrepareW(
|
|
hStmt,
|
|
szStatement,
|
|
SQL_NTS
|
|
);
|
|
|
|
if(!SQL_CALL_SUCCESS(RetCode)) {
|
|
DEBUG_MARKER;
|
|
__leave;
|
|
}
|
|
|
|
SQLUSMALLINT iParamNo = 1;
|
|
|
|
//
|
|
// OPERATION
|
|
//
|
|
SQLLEN cbOperation = SQL_NTS;
|
|
SQLBindParameter(
|
|
hStmt,
|
|
iParamNo++,
|
|
SQL_PARAM_INPUT,
|
|
SQL_C_WCHAR,
|
|
SQL_WCHAR,
|
|
sizeof(pEventData->wszOperation) / sizeof(WCHAR),
|
|
0,
|
|
pEventData->wszOperation,
|
|
0,
|
|
&cbOperation
|
|
);
|
|
|
|
//
|
|
// STATUS
|
|
//
|
|
SQLLEN cbStatus = 0;
|
|
SQLBindParameter(
|
|
hStmt,
|
|
iParamNo++,
|
|
SQL_PARAM_INPUT,
|
|
SQL_C_LONG,
|
|
SQL_INTEGER,
|
|
0,
|
|
0,
|
|
&pEventData->dwStatus,
|
|
0,
|
|
&cbStatus
|
|
);
|
|
|
|
//
|
|
// TIMESTAMP
|
|
//
|
|
|
|
SQLLEN cbTimeStamp = 0;
|
|
SQLBindParameter(
|
|
hStmt,
|
|
iParamNo++,
|
|
SQL_PARAM_INPUT,
|
|
SQL_C_TIMESTAMP,
|
|
SQL_TIMESTAMP,
|
|
19,
|
|
0,
|
|
&pEventData->TimeStamp,
|
|
0,
|
|
&cbTimeStamp
|
|
);
|
|
|
|
//
|
|
// HASH
|
|
//
|
|
|
|
SQLLEN cbHash = SQL_NTS;
|
|
SQLBindParameter(
|
|
hStmt,
|
|
iParamNo++,
|
|
SQL_PARAM_INPUT,
|
|
SQL_C_WCHAR,
|
|
SQL_WCHAR,
|
|
sizeof(pEventData->wszHash) / sizeof(WCHAR),
|
|
0,
|
|
pEventData->wszHash,
|
|
0,
|
|
&cbHash
|
|
);
|
|
|
|
//
|
|
// SUBJECT
|
|
//
|
|
|
|
SQLLEN cbSubject = SQL_NTS;
|
|
SQLBindParameter(
|
|
hStmt,
|
|
iParamNo++,
|
|
SQL_PARAM_INPUT,
|
|
SQL_C_WCHAR,
|
|
SQL_WCHAR,
|
|
sizeof(pEventData->wszSubject) / sizeof(WCHAR),
|
|
0,
|
|
pEventData->wszSubject,
|
|
0,
|
|
&cbSubject
|
|
);
|
|
|
|
//
|
|
// MACHINENAME
|
|
//
|
|
|
|
SQLLEN cbMachineName = SQL_NTS;
|
|
SQLBindParameter(
|
|
hStmt,
|
|
iParamNo++,
|
|
SQL_PARAM_INPUT,
|
|
SQL_C_WCHAR,
|
|
SQL_WCHAR,
|
|
sizeof(pEventData->wszMachineName) / sizeof(WCHAR),
|
|
0,
|
|
pEventData->wszMachineName,
|
|
0,
|
|
&cbMachineName
|
|
);
|
|
|
|
//
|
|
// BUILDLAB
|
|
//
|
|
|
|
SQLLEN cbBuildLab = SQL_NTS;
|
|
SQLBindParameter(
|
|
hStmt,
|
|
iParamNo++,
|
|
SQL_PARAM_INPUT,
|
|
SQL_C_WCHAR,
|
|
SQL_WCHAR,
|
|
sizeof(pEventData->wszBuildLab) / sizeof(WCHAR),
|
|
0,
|
|
pEventData->wszBuildLab,
|
|
0,
|
|
&cbBuildLab
|
|
);
|
|
|
|
//
|
|
// CPU64
|
|
//
|
|
SQLLEN cbCPU64 = 0;
|
|
SQLBindParameter(
|
|
hStmt,
|
|
iParamNo++,
|
|
SQL_PARAM_INPUT,
|
|
SQL_C_TINYINT,
|
|
SQL_TINYINT,
|
|
0,
|
|
0,
|
|
&pEventData->dwCPU64,
|
|
0,
|
|
&cbCPU64
|
|
);
|
|
|
|
|
|
RetCode = SQLExecute(hStmt);
|
|
DEBUG_MARKER;
|
|
}
|
|
__finally {
|
|
|
|
}
|
|
|
|
if (!SQL_CALL_SUCCESS(RetCode)) {
|
|
|
|
SDWORD swError;
|
|
SQLWCHAR szErrorMsg[SQL_MAX_MESSAGE_LENGTH];
|
|
SWORD swErrorMsg;
|
|
SQLWCHAR szSQLState[50];
|
|
|
|
SQLErrorW(
|
|
hEnv,
|
|
hDbc,
|
|
hStmt,
|
|
szSQLState,
|
|
&swError,
|
|
szErrorMsg,
|
|
SQL_MAX_MESSAGE_LENGTH - 1,
|
|
&swErrorMsg
|
|
);
|
|
|
|
DebugPrint(
|
|
(L"I_DBLogCrypt32EventThreadProc: Error (%d) - %s (%s)\n",
|
|
debugLine,
|
|
szErrorMsg,
|
|
szSQLState)
|
|
);
|
|
}
|
|
|
|
if (hStmt) {
|
|
SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
|
|
}
|
|
|
|
|
|
if (hDbc) {
|
|
SQLDisconnect(hDbc);
|
|
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
|
|
}
|
|
|
|
if (hEnv) {
|
|
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
|
|
}
|
|
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DebugPrint(
|
|
(L"I_DBLogCrypt32EventThreadProc: Exception Error (%d)\n",
|
|
GetExceptionCode())
|
|
);
|
|
RetCode = SQL_ERROR;
|
|
}
|
|
|
|
PkiFree(pEventData);
|
|
|
|
|
|
DebugPrint(
|
|
(L"I_DBLogCrypt32EventThreadProc %s\n",
|
|
(SQL_CALL_SUCCESS(RetCode) ? L"succeeded" : L"failed"))
|
|
);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
I_DBLogCrypt32Event(
|
|
IN WORD wType,
|
|
IN DWORD dwEventID,
|
|
IN WORD wNumStrings,
|
|
IN LPCWSTR *rgpwszStrings
|
|
)
|
|
{
|
|
PDBLOG_EVENT_DATA pEventData = NULL;
|
|
HANDLE hThread = NULL;
|
|
|
|
if (NULL == (pEventData = (PDBLOG_EVENT_DATA) PkiZeroAlloc(
|
|
sizeof(DBLOG_EVENT_DATA))))
|
|
goto OutOfMemory;
|
|
|
|
switch (dwEventID) {
|
|
case MSG_ROOT_AUTO_UPDATE_INFORMATIONAL:
|
|
case MSG_UNTRUSTED_ROOT_INFORMATIONAL:
|
|
case MSG_PARTIAL_CHAIN_INFORMATIONAL:
|
|
switch (dwEventID) {
|
|
case MSG_ROOT_AUTO_UPDATE_INFORMATIONAL:
|
|
// Successful auto update of third-party root certificate::
|
|
// Subject: <%1> Sha1 thumbprint: <%2>
|
|
wcscpy(pEventData->wszOperation, L"AddCert");
|
|
break;
|
|
case MSG_UNTRUSTED_ROOT_INFORMATIONAL:
|
|
// Untrusted root certificate:: Subject: <%1>
|
|
// Sha1 thumbprint: <%2>
|
|
wcscpy(pEventData->wszOperation, L"UntrustedRoot");
|
|
break;
|
|
case MSG_PARTIAL_CHAIN_INFORMATIONAL:
|
|
// Partial Chain:: Issuer: <%1>
|
|
// Subject Sha1 thumbprint: <%2>
|
|
wcscpy(pEventData->wszOperation, L"PartialChain");
|
|
break;
|
|
}
|
|
if (2 <= wNumStrings) {
|
|
wcsncpy(pEventData->wszSubject, rgpwszStrings[0],
|
|
sizeof(pEventData->wszSubject) / sizeof(WCHAR) - 1);
|
|
wcsncpy(pEventData->wszHash, rgpwszStrings[1],
|
|
sizeof(pEventData->wszHash) / sizeof(WCHAR) - 1);
|
|
}
|
|
break;
|
|
|
|
case MSG_ROOT_LIST_AUTO_UPDATE_URL_RETRIEVAL_INFORMATIONAL:
|
|
// Successful auto update of third-party root list cab from: <%1>
|
|
case MSG_ROOT_LIST_AUTO_UPDATE_URL_RETRIEVAL_ERROR:
|
|
// Failed auto update of third-party root list cab from: <%1>
|
|
// with error: %2
|
|
wcscpy(pEventData->wszOperation, L"FetchCab");
|
|
break;
|
|
|
|
case MSG_ROOT_LIST_AUTO_UPDATE_EXTRACT_ERROR:
|
|
// Failed extract of third-party root list from auto update
|
|
// cab at: <%1> with error: %2
|
|
wcscpy(pEventData->wszOperation, L"ExtractCtl");
|
|
break;
|
|
|
|
case MSG_ROOT_CERT_AUTO_UPDATE_URL_RETRIEVAL_INFORMATIONAL:
|
|
// Successful auto update of third-party root certificate from: <%1>
|
|
case MSG_ROOT_CERT_AUTO_UPDATE_URL_RETRIEVAL_ERROR:
|
|
// Failed auto update of third-party root certificate from: <%1>
|
|
// with error: %2
|
|
wcscpy(pEventData->wszOperation, L"FetchCert");
|
|
|
|
// %1 contains
|
|
// "RootDir" "/" "AsciiHexHash" ".cer"
|
|
// for example,
|
|
// "http://www.xyz.com/roots/216B2A29E62A00CE820146D8244141B92511B279.cer"
|
|
{
|
|
LPCWSTR pwszHash = rgpwszStrings[0];
|
|
DWORD cchHash;
|
|
|
|
cchHash = wcslen(pwszHash);
|
|
|
|
if ((SHA1_HASH_NAME_LEN + 4) <= cchHash)
|
|
memcpy(pEventData->wszHash,
|
|
pwszHash + (cchHash - (SHA1_HASH_NAME_LEN + 4)),
|
|
SHA1_HASH_NAME_LEN * sizeof(WCHAR));
|
|
}
|
|
break;
|
|
|
|
case MSG_CRYPT32_EVENT_LOG_THRESHOLD_WARNING:
|
|
// Reached crypt32 threshold of %1 events and will suspend
|
|
// logging for %2 minutes
|
|
wcscpy(pEventData->wszOperation, L"EventOverflow");
|
|
break;
|
|
|
|
case MSG_ROOT_SEQUENCE_NUMBER_AUTO_UPDATE_URL_RETRIEVAL_INFORMATIONAL:
|
|
// Successful auto update of third-party root list sequence
|
|
// number from: <%1>
|
|
case MSG_ROOT_SEQUENCE_NUMBER_AUTO_UPDATE_URL_RETRIEVAL_ERROR:
|
|
// Failed auto update of third-party root list sequence number
|
|
// from: <%1> with error: %2
|
|
wcscpy(pEventData->wszOperation, L"FetchSeq");
|
|
break;
|
|
|
|
default:
|
|
goto SkipDbLogCrypt32Event;
|
|
}
|
|
|
|
if (MSG_CRYPT32_EVENT_LOG_THRESHOLD_WARNING == dwEventID)
|
|
pEventData->dwStatus = (DWORD) ERROR_BUFFER_OVERFLOW;
|
|
else if (EVENTLOG_ERROR_TYPE == wType && 2 <= wNumStrings)
|
|
// The second string should contain the error code string
|
|
pEventData->dwStatus = (DWORD) wcstoul(rgpwszStrings[1], NULL, 0);
|
|
|
|
{
|
|
SYSTEMTIME SystemTime;
|
|
GetLocalTime(&SystemTime);
|
|
pEventData->TimeStamp.day = SystemTime.wDay;
|
|
pEventData->TimeStamp.month = SystemTime.wMonth;
|
|
pEventData->TimeStamp.year = SystemTime.wYear;
|
|
pEventData->TimeStamp.hour = SystemTime.wHour;
|
|
pEventData->TimeStamp.minute = SystemTime.wMinute;
|
|
pEventData->TimeStamp.second = SystemTime.wSecond;
|
|
// pEventData->TimeStamp.fraction = 0;
|
|
}
|
|
|
|
{
|
|
WCHAR wszMachineName[MAX_PATH] = L"";
|
|
DWORD cchMachineName = sizeof(wszMachineName) / sizeof(WCHAR);
|
|
|
|
// intentionally ignore any failures
|
|
GetComputerNameExW(
|
|
ComputerNameDnsHostname,
|
|
wszMachineName,
|
|
&cchMachineName
|
|
);
|
|
|
|
wcsncpy(pEventData->wszMachineName, wszMachineName,
|
|
sizeof(pEventData->wszMachineName) / sizeof(WCHAR) - 1);
|
|
}
|
|
|
|
{
|
|
HKEY hKey;
|
|
WCHAR wszBuildLab[MAX_PATH];
|
|
DWORD dwStatus;
|
|
|
|
wcscpy(wszBuildLab, L"<BuildLab Unknown>");
|
|
|
|
dwStatus = RegOpenKeyExW(
|
|
HKEY_LOCAL_MACHINE,
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion",
|
|
0,
|
|
KEY_READ,
|
|
&hKey
|
|
);
|
|
|
|
if (dwStatus == ERROR_SUCCESS) {
|
|
DWORD dwType = REG_SZ;
|
|
DWORD cbBuildLab = sizeof(wszBuildLab);
|
|
|
|
dwStatus = RegQueryValueExW(
|
|
hKey,
|
|
L"BuildLab",
|
|
0,
|
|
&dwType,
|
|
(LPBYTE) wszBuildLab,
|
|
&cbBuildLab
|
|
);
|
|
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
dwType = REG_SZ;
|
|
cbBuildLab = sizeof(wszBuildLab);
|
|
|
|
dwStatus = RegQueryValueExW(
|
|
hKey,
|
|
L"CurrentBuildNumber",
|
|
0,
|
|
&dwType,
|
|
(LPBYTE) wszBuildLab,
|
|
&cbBuildLab
|
|
);
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
wcsncpy(pEventData->wszBuildLab, wszBuildLab,
|
|
sizeof(pEventData->wszBuildLab) / sizeof(WCHAR) - 1);
|
|
}
|
|
|
|
#if defined(M_IA64) || defined(IA64) || defined(_IA64_)
|
|
pEventData->dwCPU64 = 1;
|
|
#endif
|
|
|
|
// Create the thread to do the logging to the database
|
|
if (NULL == (hThread = CreateThread(
|
|
NULL, // lpThreadAttributes
|
|
0, // dwStackSize
|
|
I_DBLogCrypt32EventThreadProc,
|
|
pEventData,
|
|
0, // dwCreationFlags
|
|
NULL // pdwThreadId
|
|
)))
|
|
goto CreateThreadError;
|
|
|
|
CloseHandle(hThread);
|
|
|
|
CommonReturn:
|
|
return;
|
|
|
|
ErrorReturn:
|
|
PkiFree(pEventData);
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(OutOfMemory)
|
|
TRACE_ERROR(SkipDbLogCrypt32Event)
|
|
TRACE_ERROR(CreateThreadError)
|
|
}
|
|
|
|
|
|
#else
|
|
|
|
void
|
|
I_DBLogAttach()
|
|
{
|
|
}
|
|
|
|
void
|
|
I_DBLogDetach()
|
|
{
|
|
}
|
|
|
|
void
|
|
I_DBLogCrypt32Event(
|
|
IN WORD wType,
|
|
IN DWORD dwEventID,
|
|
IN WORD wNumStrings,
|
|
IN LPCWSTR *rgpwszStrings
|
|
)
|
|
{
|
|
}
|
|
|
|
#endif
|