Leaked source code of windows server 2003
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

/*++
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;
}