mirror of https://github.com/tongzx/nt5src
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.
545 lines
17 KiB
545 lines
17 KiB
#define INITGUID
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <ole2.h>
|
|
#define USE_CAPI2
|
|
#if defined(USE_CAPI2)
|
|
#include <wincrypt.h>
|
|
#endif
|
|
#include "admex.h"
|
|
|
|
//
|
|
// HRESULTTOWIN32() maps an HRESULT to a Win32 error. If the facility code
|
|
// of the HRESULT is FACILITY_WIN32, then the code portion (i.e. the
|
|
// original Win32 error) is returned. Otherwise, the original HRESULT is
|
|
// returned unchagned.
|
|
//
|
|
|
|
#define HRESULTTOWIN32(hres) \
|
|
((HRESULT_FACILITY(hres) == FACILITY_WIN32) \
|
|
? HRESULT_CODE(hres) \
|
|
: (hres))
|
|
|
|
|
|
#define RETURNCODETOHRESULT(rc) \
|
|
(((rc) < 0x10000) \
|
|
? HRESULT_FROM_WIN32(rc) \
|
|
: (rc))
|
|
|
|
#define PAD4(a) (((a)+3)&~3)
|
|
|
|
VOID
|
|
DisplayErrorMessage(
|
|
DWORD dwErr,
|
|
DWORD dwMsg = 0
|
|
);
|
|
|
|
/////////////////////////////////////////////////////
|
|
|
|
VOID
|
|
DisplayErrorMessage(
|
|
DWORD dwErr,
|
|
DWORD dwMsg
|
|
)
|
|
{
|
|
LPSTR pErr;
|
|
CHAR achMsg[2048];
|
|
|
|
if ( dwMsg != 0 )
|
|
{
|
|
if ( LoadString( NULL, dwMsg, achMsg, sizeof(achMsg) ) )
|
|
{
|
|
printf( achMsg );
|
|
}
|
|
}
|
|
|
|
if ( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
dwErr,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(LPSTR)&pErr,
|
|
0,
|
|
NULL ) )
|
|
{
|
|
puts( pErr );
|
|
|
|
LocalFree( pErr );
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
Dump(
|
|
LPSTR pszMsg,
|
|
LPBYTE pb,
|
|
DWORD dw
|
|
)
|
|
{
|
|
printf( "%s size is %d\n", pszMsg, dw );
|
|
|
|
for ( UINT x = 0 ; x < dw ; ++x )
|
|
{
|
|
printf( "%02x ", pb[x] );
|
|
}
|
|
|
|
if ( dw )
|
|
{
|
|
printf( "\n" );
|
|
}
|
|
}
|
|
|
|
|
|
int __cdecl main( int argc, char*argv[] )
|
|
{
|
|
IMSAdminReplication* pIf;
|
|
IMSAdminCryptoCapabilities* pIfS;
|
|
IClassFactory* pcsfFactory = NULL;
|
|
int iA;
|
|
HRESULT hRes;
|
|
COSERVERINFO csiMachineName;
|
|
WCHAR awchComputer[64];
|
|
BYTE abBuf[32768];
|
|
DWORD dwReqSize;
|
|
MULTI_QI rgmq;
|
|
LPSTR pszMachineName = NULL;
|
|
int arg;
|
|
BOOL fDoTest = FALSE;
|
|
HKEY hKey;
|
|
CHAR achName[128];
|
|
DWORD dwNameLen;
|
|
DWORD dwValueLen;
|
|
DWORD dwType;
|
|
int iV, iV2;
|
|
LPBYTE pbSerial;
|
|
DWORD dwSerialLen, dwSerialLen2;
|
|
DWORD dwErr;
|
|
|
|
for ( arg = 1 ; arg < argc ; ++arg )
|
|
{
|
|
if ( argv[arg][0] == '-' )
|
|
{
|
|
switch ( argv[arg][1] )
|
|
{
|
|
case 'm':
|
|
pszMachineName = argv[arg]+2;
|
|
break;
|
|
|
|
case 't':
|
|
fDoTest = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( argc < 1 )
|
|
{
|
|
CHAR achMsg[2048];
|
|
|
|
if ( LoadString( NULL, 100, achMsg, sizeof(achMsg) ) )
|
|
{
|
|
printf( achMsg );
|
|
}
|
|
return 3;
|
|
}
|
|
|
|
//fill the structure for CoCreateInstanceEx
|
|
ZeroMemory( &csiMachineName, sizeof(csiMachineName) );
|
|
// csiMachineName.pAuthInfo = NULL;
|
|
// csiMachineName.dwFlags = 0;
|
|
// csiMachineName.pServerInfoExt = NULL;
|
|
|
|
if ( pszMachineName )
|
|
{
|
|
if ( !MultiByteToWideChar( CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
pszMachineName,
|
|
-1,
|
|
awchComputer,
|
|
sizeof(awchComputer) ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
csiMachineName.pwszName = awchComputer;
|
|
}
|
|
else
|
|
{
|
|
csiMachineName.pwszName = NULL;
|
|
}
|
|
|
|
CoInitializeEx( NULL, COINIT_MULTITHREADED );
|
|
|
|
if ( fDoTest )
|
|
{
|
|
hRes = CoGetClassObject(CLSID_MSCryptoAdmEx, CLSCTX_SERVER, &csiMachineName,
|
|
IID_IClassFactory, (void**) &pcsfFactory);
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminReplication, (void **) &rgmq.pItf);
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
rgmq.pItf->Release();
|
|
}
|
|
else
|
|
{
|
|
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
|
|
}
|
|
pcsfFactory->Release();
|
|
}
|
|
else
|
|
{
|
|
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
|
|
}
|
|
|
|
//
|
|
// call replication I/F
|
|
//
|
|
|
|
rgmq.pIID = &IID_IMSAdminReplication;
|
|
rgmq.pItf = NULL;
|
|
rgmq.hr = 0;
|
|
|
|
if ( SUCCEEDED( hRes = CoCreateInstanceEx( CLSID_MSCryptoAdmEx,
|
|
NULL,
|
|
CLSCTX_SERVER,
|
|
&csiMachineName,
|
|
1,
|
|
&rgmq ) ) &&
|
|
SUCCEEDED( hRes = rgmq.hr ) )
|
|
{
|
|
pIf = (IMSAdminReplication*)rgmq.pItf;
|
|
|
|
hRes = pIf->GetSignature( sizeof(abBuf), abBuf, &dwReqSize );
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
Dump( "GetSignature:", abBuf, dwReqSize );
|
|
|
|
hRes = pIf->Serialize( sizeof(abBuf), abBuf, &dwReqSize );
|
|
}
|
|
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
Dump( "Serialize:", abBuf, dwReqSize );
|
|
|
|
hRes = pIf->DeSerialize( dwReqSize, abBuf );
|
|
}
|
|
|
|
pIf->Release();
|
|
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
|
|
}
|
|
|
|
//
|
|
// call crypto capabilities I/F
|
|
//
|
|
|
|
rgmq.pIID = &IID_IMSAdminCryptoCapabilities;
|
|
rgmq.pItf = NULL;
|
|
rgmq.hr = 0;
|
|
|
|
if ( SUCCEEDED( hRes = CoCreateInstanceEx( CLSID_MSCryptoAdmEx,
|
|
NULL,
|
|
CLSCTX_SERVER,
|
|
&csiMachineName,
|
|
1,
|
|
&rgmq ) ) &&
|
|
SUCCEEDED( hRes = rgmq.hr ) )
|
|
{
|
|
pIfS = (IMSAdminCryptoCapabilities*)rgmq.pItf;
|
|
|
|
hRes = pIfS->GetProtocols( sizeof(abBuf), abBuf, &dwReqSize );
|
|
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
Dump( "Protocols:", abBuf, dwReqSize );
|
|
|
|
hRes = pIfS->GetSupportedAlgs( sizeof(abBuf), (LPDWORD)abBuf, &dwReqSize );
|
|
}
|
|
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
Dump( "Algs:", abBuf, dwReqSize );
|
|
|
|
hRes = pIfS->GetRootCertificates( sizeof(abBuf), abBuf, &dwReqSize );
|
|
}
|
|
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
Dump( "CAs:", abBuf, dwReqSize );
|
|
|
|
hRes = pIfS->GetMaximumCipherStrength( &dwReqSize );
|
|
}
|
|
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
Dump( "Cipher strength:", (LPBYTE)&dwReqSize, sizeof(DWORD) );
|
|
}
|
|
|
|
pIfS->Release();
|
|
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Check full access to registry ( granted only to administrators )
|
|
//
|
|
|
|
if ( (dwErr = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
"SYSTEM\\CurrentControlSet\\Services\\InetInfo\\Parameters",
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey )) == ERROR_SUCCESS )
|
|
{
|
|
RegCloseKey( hKey );
|
|
}
|
|
else
|
|
{
|
|
hRes = RETURNCODETOHRESULT( dwErr );
|
|
}
|
|
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
hRes = CoGetClassObject(CLSID_MSCryptoAdmEx, CLSCTX_SERVER, &csiMachineName,
|
|
IID_IClassFactory, (void**) &pcsfFactory);
|
|
}
|
|
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminCryptoCapabilities, (void **) &pIfS);
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// get CA list
|
|
//
|
|
|
|
#if defined(USE_CAPI2)
|
|
|
|
HCERTSTORE hStore = NULL;
|
|
BOOL fReturn = FALSE;
|
|
PCCERT_CONTEXT pCtx;
|
|
|
|
hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
|
0,
|
|
NULL,
|
|
CERT_SYSTEM_STORE_CURRENT_USER,
|
|
"ROOT" );
|
|
|
|
if ( hStore )
|
|
{
|
|
for ( pCtx = NULL, dwSerialLen = 0 ;
|
|
pCtx = CertEnumCertificatesInStore( hStore, pCtx ) ; )
|
|
{
|
|
// CertDeleteCertificateFromStore, CertAddSerializedElementToStore
|
|
dwValueLen = sizeof(abBuf);
|
|
if ( CertSerializeCertificateStoreElement( pCtx, 0, NULL, &dwValueLen ) )
|
|
{
|
|
dwSerialLen += sizeof(DWORD) + PAD4(dwValueLen);
|
|
}
|
|
else
|
|
{
|
|
hRes = RETURNCODETOHRESULT( GetLastError() );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hRes = RETURNCODETOHRESULT( GetLastError() );
|
|
}
|
|
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
if ( pbSerial = (LPBYTE)LocalAlloc( LMEM_FIXED, dwSerialLen ) )
|
|
{
|
|
for ( pCtx = NULL, dwSerialLen2 = 0 ;
|
|
pCtx = CertEnumCertificatesInStore( hStore, pCtx ) ; )
|
|
{
|
|
dwValueLen = dwSerialLen - dwSerialLen2 - sizeof(DWORD);
|
|
if ( CertSerializeCertificateStoreElement( pCtx, 0, pbSerial + dwSerialLen2 + sizeof(DWORD), &dwValueLen ) )
|
|
{
|
|
*(LPDWORD)(pbSerial+dwSerialLen2) = dwValueLen;
|
|
dwSerialLen2 += sizeof(DWORD) + PAD4(dwValueLen);
|
|
}
|
|
else
|
|
{
|
|
hRes = RETURNCODETOHRESULT( GetLastError() );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
//
|
|
// call deserialize. This will be invoked in IIS SYSTEM context
|
|
//
|
|
|
|
hRes = pIfS->SetCAList( dwSerialLen2, pbSerial );
|
|
}
|
|
|
|
LocalFree( pbSerial );
|
|
}
|
|
else
|
|
{
|
|
hRes = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
if ( hStore )
|
|
{
|
|
CertCloseStore( hStore, CERT_CLOSE_STORE_FORCE_FLAG );
|
|
}
|
|
|
|
#else
|
|
|
|
if ( (dwErr = RegOpenKeyEx( HKEY_CURRENT_USER,
|
|
"Software\\Microsoft\\SystemCertificates\\ROOT\\Certificates",
|
|
0,
|
|
KEY_READ,
|
|
&hKey )) == ERROR_SUCCESS )
|
|
{
|
|
//
|
|
// compute length of serialized CA list
|
|
//
|
|
|
|
for ( iV = 0, dwSerialLen = 0 ; ; ++iV )
|
|
{
|
|
dwNameLen = sizeof( achName );
|
|
dwValueLen = sizeof(abBuf);
|
|
if ( RegEnumValue( hKey,
|
|
iV,
|
|
achName,
|
|
&dwNameLen,
|
|
NULL,
|
|
&dwType,
|
|
abBuf,
|
|
&dwValueLen ) != ERROR_SUCCESS )
|
|
{
|
|
break;
|
|
}
|
|
++dwNameLen;
|
|
dwSerialLen += sizeof(DWORD) + PAD4(dwNameLen) + sizeof(DWORD) + PAD4(dwValueLen);
|
|
}
|
|
|
|
if ( pbSerial = (LPBYTE)LocalAlloc( LMEM_FIXED, dwSerialLen ) )
|
|
{
|
|
//
|
|
// build serialized list
|
|
//
|
|
|
|
for ( iV2 = 0, dwSerialLen2 = 0 ;; ++iV2 )
|
|
{
|
|
dwNameLen = sizeof( achName );
|
|
dwValueLen = sizeof(abBuf);
|
|
if ( RegEnumValue( hKey,
|
|
iV2,
|
|
achName,
|
|
&dwNameLen,
|
|
NULL,
|
|
&dwType,
|
|
abBuf,
|
|
&dwValueLen ) != ERROR_SUCCESS )
|
|
{
|
|
break;
|
|
}
|
|
++dwNameLen;
|
|
|
|
if ( iV2 == iV ||
|
|
dwSerialLen2 + sizeof(DWORD) + PAD4(dwNameLen) + sizeof(DWORD) + PAD4(dwValueLen) > dwSerialLen )
|
|
{
|
|
hRes = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
// each element ( name or content ) is stored prefixed by
|
|
// a DWORD length. element actual storage is padded
|
|
// so that length is multiple of 4, to make sure following
|
|
// DWORDs are DWORD aligned.
|
|
|
|
// store value name ( includes zero byte delimiter )
|
|
|
|
*(LPDWORD)(pbSerial+dwSerialLen2) = dwNameLen;
|
|
dwSerialLen2 += sizeof(DWORD);
|
|
memcpy( pbSerial+dwSerialLen2, achName, dwNameLen );
|
|
dwSerialLen2 += PAD4(dwNameLen);
|
|
|
|
// store value content
|
|
|
|
*(LPDWORD)(pbSerial+dwSerialLen2) = dwValueLen;
|
|
dwSerialLen2 += sizeof(DWORD);
|
|
memcpy( pbSerial+dwSerialLen2, abBuf, dwValueLen );
|
|
dwSerialLen2 += PAD4(dwValueLen);
|
|
}
|
|
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
//
|
|
// call deserialize. This will be invoked in IIS SYSTEM context
|
|
//
|
|
|
|
hRes = pIfS->SetCAList( dwSerialLen2, pbSerial );
|
|
}
|
|
|
|
LocalFree( pbSerial );
|
|
}
|
|
else
|
|
{
|
|
hRes = E_OUTOFMEMORY;
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
}
|
|
else
|
|
{
|
|
hRes = RETURNCODETOHRESULT( dwErr );
|
|
}
|
|
|
|
#endif
|
|
if ( FAILED(hRes) )
|
|
{
|
|
DisplayErrorMessage( HRESULTTOWIN32( hRes ), 102 );
|
|
}
|
|
else
|
|
{
|
|
CHAR achMsg[2048];
|
|
|
|
if ( LoadString( NULL, 101, achMsg, sizeof(achMsg) ) )
|
|
{
|
|
printf( achMsg );
|
|
}
|
|
}
|
|
|
|
pIfS->Release();
|
|
}
|
|
pcsfFactory->Release();
|
|
}
|
|
else
|
|
{
|
|
DisplayErrorMessage( HRESULTTOWIN32( hRes ), 102 );
|
|
}
|
|
|
|
}
|
|
|
|
CoUninitialize();
|
|
|
|
return SUCCEEDED(hRes) ? 0 : 1;
|
|
}
|