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.
441 lines
10 KiB
441 lines
10 KiB
/*++
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name :
|
|
sslconfigchangeprov.cxx
|
|
|
|
Abstract:
|
|
SSL CONFIG PROV server
|
|
|
|
Listens for metabase notifications related to SSL
|
|
and informs connected client appropriately
|
|
|
|
|
|
Author:
|
|
Jaroslav Dunajsky April-24-2001
|
|
|
|
Environment:
|
|
Win32 - User Mode
|
|
|
|
Project:
|
|
Stream Filter Worker Process
|
|
--*/
|
|
|
|
|
|
|
|
|
|
#include "precomp.hxx"
|
|
|
|
//
|
|
// Constants
|
|
//
|
|
|
|
#define W3_SERVER_MB_PATH L"/LM/W3SVC/"
|
|
#define W3_SERVER_MB_PATH_CCH 10
|
|
|
|
//
|
|
// private declarations
|
|
//
|
|
|
|
class MB_LISTENER
|
|
: public MB_BASE_NOTIFICATION_SINK
|
|
{
|
|
public:
|
|
|
|
MB_LISTENER( SSL_CONFIG_CHANGE_PROV_SERVER * pSslConfigChangeProv )
|
|
:
|
|
_pSslConfigChangeProv( pSslConfigChangeProv )
|
|
{
|
|
}
|
|
|
|
STDMETHOD( SynchronizedSinkNotify )(
|
|
DWORD dwMDNumElements,
|
|
MD_CHANGE_OBJECT pcoChangeList[]
|
|
)
|
|
{
|
|
DBG_ASSERT( _pSslConfigChangeProv != NULL );
|
|
return _pSslConfigChangeProv->MetabaseChangeNotification(
|
|
dwMDNumElements,
|
|
pcoChangeList );
|
|
}
|
|
|
|
private:
|
|
SSL_CONFIG_CHANGE_PROV_SERVER * _pSslConfigChangeProv;
|
|
};
|
|
|
|
|
|
|
|
//virtual
|
|
HRESULT
|
|
SSL_CONFIG_CHANGE_PROV_SERVER::PipeListener(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Listens on SslConfigPipe and executes commands
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
SSL_CONFIG_PIPE_COMMAND Command;
|
|
|
|
//
|
|
// Even though change notification pipe doesn't expect
|
|
// any data received from client
|
|
// we will use PipeReceiveCommand() for detection when pipe
|
|
// get's closed so that we can recycle it
|
|
//
|
|
|
|
hr = PipeReceiveCommand( &Command );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
//
|
|
// client should never send data over the change notification pipe
|
|
//
|
|
DBG_ASSERT( FAILED( hr ) );
|
|
|
|
Cleanup:
|
|
//BUGBUG handle error
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT
|
|
SSL_CONFIG_CHANGE_PROV_SERVER::Initialize(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Initialize named pipe
|
|
Connect to metabase
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
HANDLE hEvent = NULL;
|
|
|
|
//
|
|
// Initialize the metabase access (ABO)
|
|
//
|
|
|
|
hr = CoCreateInstance( CLSID_MSAdminBase,
|
|
NULL,
|
|
CLSCTX_SERVER,
|
|
IID_IMSAdminBase,
|
|
reinterpret_cast<LPVOID *>(&_pAdminBase) );
|
|
if( FAILED(hr) )
|
|
{
|
|
DBGPRINTF(( DBG_CONTEXT,
|
|
"Error creating ABO object. hr = %x\n",
|
|
hr ));
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Initialize the metabase sink
|
|
// (it will not start listening yet)
|
|
//
|
|
|
|
_pListener = new MB_LISTENER( this );
|
|
if ( _pListener == NULL )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
|
|
DBGPRINTF(( DBG_CONTEXT,
|
|
"Error creating metabase listener. hr = %x\n",
|
|
hr ));
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Initialize parent - it will create pipe and
|
|
// start listener thread ( thread will execute PipeListener() )
|
|
//
|
|
hr = SSL_CONFIG_PIPE::PipeInitializeServer( WSZ_SSL_CONFIG_CHANGE_PIPE );
|
|
if( FAILED(hr) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Start listening for metabase changes
|
|
//
|
|
|
|
DBG_ASSERT( _pAdminBase != NULL );
|
|
|
|
hr = _pListener->StartListening( _pAdminBase );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
|
|
hr = S_OK;
|
|
Cleanup:
|
|
if ( FAILED( hr ) )
|
|
{
|
|
Terminate();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
SSL_CONFIG_CHANGE_PROV_SERVER::Terminate(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Close named pipe for metabase change notifications
|
|
Close metabase named pipe
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
//
|
|
// if there are any blocked pipe calls
|
|
// they need to get cancelled not to block
|
|
// metabase callbacks from completion
|
|
//
|
|
if ( SSL_CONFIG_PIPE::IsPipeInitialized() )
|
|
{
|
|
SSL_CONFIG_PIPE::PipeCancel();
|
|
}
|
|
//
|
|
// Stop listening for metabase changes
|
|
// all metabase change callbacks will be completed after
|
|
// function returns
|
|
//
|
|
if ( _pListener != NULL )
|
|
{
|
|
_pListener->StopListening( _pAdminBase );
|
|
}
|
|
|
|
//
|
|
// Terminate pipe
|
|
//
|
|
hr = SSL_CONFIG_PIPE::PipeTerminate();
|
|
DBG_ASSERT( SUCCEEDED( hr ) );
|
|
|
|
//
|
|
// Terminate metabase listener
|
|
//
|
|
|
|
if ( _pListener != NULL )
|
|
{
|
|
_pListener->Release();
|
|
_pListener = NULL;
|
|
}
|
|
|
|
//
|
|
// Terminate the metabase access (ABO)
|
|
//
|
|
|
|
if ( _pAdminBase != NULL )
|
|
{
|
|
_pAdminBase->Release();
|
|
_pAdminBase = NULL;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT
|
|
SSL_CONFIG_CHANGE_PROV_SERVER::MetabaseChangeNotification(
|
|
DWORD dwMDNumElements,
|
|
MD_CHANGE_OBJECT pcoChangeList[]
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handle metabase change notifications
|
|
|
|
Arguments:
|
|
|
|
dwMDNumElements - Number of elements changed
|
|
pcoChangeList - Elements changed
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
LPWSTR pszSiteString;
|
|
DWORD dwSiteId;
|
|
LPWSTR pszAfter;
|
|
BOOL fDoSiteConfigUpdate;
|
|
BOOL fDoSiteBindingUpdate;
|
|
SSL_CONFIG_PIPE_COMMAND Command;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
|
|
DBG_ASSERT( dwMDNumElements != 0 );
|
|
DBG_ASSERT( pcoChangeList != NULL );
|
|
|
|
//
|
|
// Only handle the W3SVC changes
|
|
//
|
|
|
|
for( DWORD i = 0; i < dwMDNumElements; ++i )
|
|
{
|
|
if( _wcsnicmp( pcoChangeList[i].pszMDPath,
|
|
W3_SERVER_MB_PATH,
|
|
W3_SERVER_MB_PATH_CCH ) == 0 )
|
|
{
|
|
fDoSiteConfigUpdate = FALSE;
|
|
fDoSiteBindingUpdate = FALSE;
|
|
|
|
//
|
|
// Was this change made for a site, or for all of W3SVC
|
|
//
|
|
|
|
pszSiteString = pcoChangeList[i].pszMDPath + W3_SERVER_MB_PATH_CCH;
|
|
if ( *pszSiteString != L'\0' )
|
|
{
|
|
dwSiteId = wcstoul( pszSiteString, &pszAfter, 10 );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// A site id of 0 means we will flush all site config
|
|
//
|
|
|
|
dwSiteId = 0;
|
|
}
|
|
|
|
//
|
|
// Now check whether the changed property was an SSL prop
|
|
//
|
|
|
|
for ( DWORD j = 0; j < pcoChangeList[ i ].dwMDNumDataIDs; j++ )
|
|
{
|
|
if ( fDoSiteConfigUpdate )
|
|
{
|
|
break;
|
|
}
|
|
|
|
switch( pcoChangeList[ i ].pdwMDDataIDs[ j ] )
|
|
{
|
|
case MD_SSL_CERT_HASH:
|
|
case MD_SSL_CERT_CONTAINER:
|
|
case MD_SSL_CERT_PROVIDER:
|
|
case MD_SSL_CERT_OPEN_FLAGS:
|
|
case MD_SSL_CERT_STORE_NAME:
|
|
case MD_SSL_CERT_IS_FORTEZZA:
|
|
case MD_SSL_CERT_FORTEZZA_PIN:
|
|
case MD_SSL_CERT_FORTEZZA_SERIAL_NUMBER:
|
|
case MD_SSL_CERT_FORTEZZA_PERSONALITY:
|
|
case MD_SSL_CERT_FORTEZZA_PROG_PIN:
|
|
case MD_SSL_CTL_IDENTIFIER:
|
|
case MD_SSL_CTL_CONTAINER:
|
|
case MD_SSL_CTL_PROVIDER:
|
|
case MD_SSL_CTL_PROVIDER_TYPE:
|
|
case MD_SSL_CTL_OPEN_FLAGS:
|
|
case MD_SSL_CTL_STORE_NAME:
|
|
case MD_SSL_CTL_SIGNER_HASH:
|
|
case MD_SSL_USE_DS_MAPPER:
|
|
case MD_SSL_ACCESS_PERM:
|
|
case MD_CERT_CHECK_MODE:
|
|
case MD_REVOCATION_FRESHNESS_TIME:
|
|
case MD_REVOCATION_URL_RETRIEVAL_TIMEOUT:
|
|
fDoSiteConfigUpdate = TRUE;
|
|
break;
|
|
case MD_SECURE_BINDINGS:
|
|
fDoSiteBindingUpdate = TRUE;
|
|
break;
|
|
case MD_SERVER_STATE:
|
|
fDoSiteConfigUpdate = TRUE;
|
|
fDoSiteBindingUpdate = TRUE;
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update the site bindings if necessary
|
|
//
|
|
|
|
if ( fDoSiteBindingUpdate )
|
|
{
|
|
ZeroMemory( &Command,
|
|
sizeof( Command ) );
|
|
Command.dwCommandId = CMD_CHANGED_SECURE_BINDINGS;
|
|
Command.dwParameter1 = dwSiteId;
|
|
|
|
hr = PipeSendCommand( &Command );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto failed;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update the site configurations if necessary
|
|
//
|
|
|
|
if ( fDoSiteConfigUpdate )
|
|
{
|
|
//
|
|
// dwSiteId == 0 means flush all sites
|
|
//
|
|
ZeroMemory( &Command,
|
|
sizeof( Command ) );
|
|
Command.dwCommandId = CMD_CHANGED_SSL_CONFIGURATION;
|
|
Command.dwParameter1 = dwSiteId;
|
|
|
|
hr = PipeSendCommand( &Command );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto failed;
|
|
}
|
|
|
|
if ( dwSiteId == 0 )
|
|
{
|
|
//
|
|
// If we've already flushed every site, then no
|
|
// reason to read any more changes
|
|
//
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return S_OK;
|
|
failed:
|
|
DBG_ASSERT( FAILED( hr ) );
|
|
//
|
|
// failure may have been caused by the fact
|
|
// that there is no client connected yet
|
|
//
|
|
|
|
return hr;
|
|
}
|
|
|
|
|