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.
 
 
 
 
 
 

1119 lines
29 KiB

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name :
siteconfig.cxx
Abstract:
SSL configuration for a given site
Author:
Bilal Alam (BAlam) 29-March-2000
Environment:
Win32 - User Mode
Project:
Stream Filter Worker Process
--*/
#include "precomp.hxx"
ENDPOINT_CONFIG_HASH * ENDPOINT_CONFIG::sm_pEndpointConfigHash;
ENDPOINT_CONFIG::INIT_STATE ENDPOINT_CONFIG::sm_InitState = INIT_NONE;
HANDLE ENDPOINT_CONFIG::sm_hHttpApiConfigChangeEvent = NULL;
HKEY ENDPOINT_CONFIG::sm_hHttpApiConfigKey = NULL;
HANDLE ENDPOINT_CONFIG::sm_hWaitHandle = NULL;
//static
HRESULT
ENDPOINT_CONFIG::Initialize(
VOID
)
/*++
Routine Description:
Initialize site configuration globals
Arguments:
None
Return Value:
HRESULT
--*/
{
HRESULT hr = E_FAIL;
DWORD dwError = NO_ERROR;
HTTPAPI_VERSION HttpApiVersion = HTTPAPI_VERSION_1;
//
// Initialize HttpApi to be able to retrieve SSL config
//
dwError = HttpInitialize( HttpApiVersion, HTTP_INITIALIZE_CONFIG, NULL );
if ( dwError != NO_ERROR )
{
hr = HRESULT_FROM_WIN32( dwError );
goto Failed;
}
sm_InitState = INIT_HTTPAPI;
sm_pEndpointConfigHash = new ENDPOINT_CONFIG_HASH();
if ( sm_pEndpointConfigHash == NULL )
{
hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
goto Failed;
}
sm_InitState = INIT_HASH;
//
// Create event for HttpApi config store change notifications
//
sm_hHttpApiConfigChangeEvent = CreateEvent( NULL, // SD
FALSE, // fManualReset
FALSE, //fInitialState
NULL ); // name*/
if( sm_hHttpApiConfigChangeEvent == NULL )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
DBGPRINTF(( DBG_CONTEXT,
"CreateEvent() failed. hr = 0x%x\n",
hr ));
goto Failed;
}
dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Services\\HTTP\\Parameters\\SslBindingInfo",
0,
KEY_READ,
&sm_hHttpApiConfigKey );
if ( dwError != ERROR_SUCCESS )
{
// backup plan
// if SslBindingInfo doesn't extst yet, simply listen on
// parent node. HTTP\Parameters is guaranteed to exist on valid install
//
dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Services\\HTTP\\Parameters",
0,
KEY_READ,
&sm_hHttpApiConfigKey );
if ( dwError != ERROR_SUCCESS )
{
hr = HRESULT_FROM_WIN32( dwError );
DBGPRINTF(( DBG_CONTEXT,
"Failed to open registry. hr = 0x%x\n",
hr ));
CloseHandle( sm_hHttpApiConfigChangeEvent );
sm_hHttpApiConfigChangeEvent = NULL;
goto Failed;
}
}
DBG_ASSERT( sm_hHttpApiConfigKey != NULL );
//
// Watch the registry key for a change
//
dwError = RegNotifyChangeKeyValue( sm_hHttpApiConfigKey,
TRUE,
REG_NOTIFY_CHANGE_LAST_SET |
REG_NOTIFY_CHANGE_NAME,
sm_hHttpApiConfigChangeEvent,
TRUE );
if( dwError != ERROR_SUCCESS )
{
hr = HRESULT_FROM_WIN32( dwError );
RegCloseKey( sm_hHttpApiConfigKey );
sm_hHttpApiConfigKey = NULL;
CloseHandle( sm_hHttpApiConfigChangeEvent );
sm_hHttpApiConfigChangeEvent = NULL;
DBGPRINTF(( DBG_CONTEXT,
"RegNotifyChangeKeyValue failed. hr = 0x%x\n",
hr ));
goto Failed;
}
//
// Register a callback function to wait on the event
//
if( !RegisterWaitForSingleObject(
&sm_hWaitHandle,
sm_hHttpApiConfigChangeEvent,
( WAITORTIMERCALLBACK )ENDPOINT_CONFIG::ConfigStoreChangeCallback,
NULL,
INFINITE,
WT_EXECUTEDEFAULT ) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
RegCloseKey( sm_hHttpApiConfigKey );
sm_hHttpApiConfigKey = NULL;
CloseHandle( sm_hHttpApiConfigChangeEvent );
sm_hHttpApiConfigChangeEvent = NULL;
DBGPRINTF(( DBG_CONTEXT,
"RegisterWaitForSingleObject failed. hr = 0x%x\n",
hr ));
goto Failed;
}
sm_InitState = INIT_CHANGE_NOTIF;
return NO_ERROR;
Failed:
Terminate();
return hr;
}
//static
VOID
ENDPOINT_CONFIG::Terminate(
VOID
)
/*++
Routine Description:
Cleanup site configuration globals
Arguments:
None
Return Value:
None
--*/
{
switch( sm_InitState )
{
case INIT_CHANGE_NOTIF:
if ( sm_hWaitHandle != NULL )
{
UnregisterWaitEx( sm_hWaitHandle,
INVALID_HANDLE_VALUE );
sm_hWaitHandle = NULL;
}
//
// NOTE:
// registry key must be closed before event is destroyed
// because closing handle will assure that sm_hHttpApiConfigChangeEvent event
// will not be used any more
//
if ( sm_hHttpApiConfigKey != NULL )
{
CloseHandle( sm_hHttpApiConfigKey );
sm_hHttpApiConfigKey = NULL;
}
if ( sm_hHttpApiConfigChangeEvent != NULL )
{
CloseHandle( sm_hHttpApiConfigChangeEvent );
sm_hHttpApiConfigChangeEvent = NULL;
}
case INIT_HASH:
if ( sm_pEndpointConfigHash != NULL )
{
//
// Clear hash table before deleting it
//
sm_pEndpointConfigHash->Clear();
delete sm_pEndpointConfigHash;
sm_pEndpointConfigHash = NULL;
}
case INIT_HTTPAPI:
HttpTerminate( HTTP_INITIALIZE_CONFIG, NULL );
case INIT_NONE:
break;
}
}
//private
//static
HRESULT
ENDPOINT_CONFIG::GetEndpointConfigData(
IN DWORD LocalAddress,
IN USHORT LocalPort,
OUT PHTTP_SERVICE_CONFIG_SSL_SET * ppEndpointConfigData,
OUT BOOL * pfWildcardMatch
)
/*++
Routine Description:
lookup SSL configuration
Arguments:
LocalAddress - IP address in network order
LocalPort - Port in network order
ppEndpointConfigData - allocated within this function - delete[] must be used to free it
pfWildcardMatch - was wildcard IP address match used?
)
Return Value:
HRESULT
--*/
{
DWORD dwError;
DWORD ReturnLength = 0;
HTTP_SERVICE_CONFIG_SSL_QUERY QueryParam;
PHTTP_SERVICE_CONFIG_SSL_SET pSetParam = NULL;
HRESULT hr = NO_ERROR;
SOCKADDR_IN SockAddr;
if ( ppEndpointConfigData == NULL ||
pfWildcardMatch == NULL )
{
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
ZeroMemory( &SockAddr, sizeof(SockAddr) );
ZeroMemory( &QueryParam, sizeof(QueryParam) );
*pfWildcardMatch = FALSE;
QueryParam.QueryDesc = HttpServiceConfigQueryExact;
//
// build sock addr for HTTPAPI lookup
//
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = LocalPort;
SockAddr.sin_addr.s_addr = LocalAddress;
QueryParam.KeyDesc.pIpPort = (PSOCKADDR) &SockAddr;
// Loop - check nonwildcard info first, if it fails then try wildcard
//
for(;;)
{
dwError = HttpQueryServiceConfiguration(
NULL,
HttpServiceConfigSSLCertInfo,
&QueryParam,
sizeof(QueryParam),
NULL,
0,
&ReturnLength,
NULL
);
if ( dwError == ERROR_INSUFFICIENT_BUFFER )
{
pSetParam = (PHTTP_SERVICE_CONFIG_SSL_SET) new BYTE[ReturnLength];
if ( pSetParam == NULL )
{
hr = HRESULT_FROM_WIN32( ERROR_OUTOFMEMORY );
goto Finished;
}
dwError = HttpQueryServiceConfiguration(
NULL,
HttpServiceConfigSSLCertInfo,
&QueryParam,
sizeof(QueryParam),
pSetParam,
ReturnLength,
&ReturnLength,
NULL
);
//
// It is possible that the size returned on the first call may
// have changed between first and second call.
// It would be caused by configuration change.
// Probability of it happening is very low.
// If it happens then one connection attempt will fail and it is
// acceptable
//
}
// If not found (and other error will mean end of trying)
// or if wildcard lookup already executed
// then leave the loop
//
if ( dwError != ERROR_FILE_NOT_FOUND || SockAddr.sin_addr.s_addr == INADDR_ANY )
{
break;
}
else
{
//
// continue loop for wildcard lookup
//
SockAddr.sin_addr.s_addr = INADDR_ANY;
}
}
if ( dwError != NO_ERROR )
{
hr = HRESULT_FROM_WIN32( dwError );
goto Finished;
}
if ( SockAddr.sin_addr.s_addr == INADDR_ANY )
{
*pfWildcardMatch = TRUE;
}
*ppEndpointConfigData = pSetParam;
hr = S_OK;
Finished:
return hr;
}
//static
HRESULT
ENDPOINT_CONFIG::GetEndpointConfig(
CONNECTION_INFO * pConnectionInfo,
ENDPOINT_CONFIG ** ppEndpointConfig,
BOOL fCreateEmptyIfNotFound
)
/*++
Routine Description:
Lookup site configuration in hash table. If not there then create it
and add it to table
Arguments:
dwSiteId - Site ID to lookup
ppEndpointConfig - Filled with pointer to site config on success
fCreateEmptyIfNotFound - if endpoint config was not located
in the persistent store, create empty
endpoint config and stick it to cache
That will optimize lookup for EnableRawFilter
checks
Return Value:
HRESULT
HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) when endpoint config not found
--*/
{
LK_RETCODE lkrc;
ENDPOINT_CONFIG * pEndpointConfig = NULL;
SERVER_CERT * pServerCert = NULL;
IIS_CTL * pIisCtl = NULL;
HRESULT hr = NO_ERROR;
STACK_STRU( strMBPath, 64 );
DWORD LocalAddress = 0;
USHORT LocalPort = 0;
BOOL fWildcardMatch = FALSE;
PHTTP_SERVICE_CONFIG_SSL_SET pEndpointConfigData = NULL;
if ( ppEndpointConfig == NULL ||
pConnectionInfo == NULL )
{
DBG_ASSERT( FALSE );
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
*ppEndpointConfig = NULL;
//
// Figure out Ip Address and Port
//
//
// Pass Port and IP address in network order
// (HTTP service will return them in network order so no changes are needed)
//
if( pConnectionInfo->LocalAddressType == TDI_ADDRESS_TYPE_IP )
{
LocalAddress = pConnectionInfo->SockLocalAddress.ipv4SockAddress.sin_addr.s_addr;
LocalPort = pConnectionInfo->SockLocalAddress.ipv4SockAddress.sin_port;
}
else if ( pConnectionInfo->LocalAddressType == TDI_ADDRESS_TYPE_IP6 )
{
//
// IPv6 connections will be able to handle SSL connections only
// in the case when all IP addresses on the machine are configured to
// listen on secure port (IPv4 wildcard binding must be configured).
// CODEWORK: Once in the future there may be a need to implement
// for IPv6 support.
//
LocalAddress = INADDR_ANY; // Wildcard IP
LocalPort = pConnectionInfo->SockLocalAddress.ipv6SockAddress.sin6_port;
}
else
{
//
// We support only IPv4 and IPv6. Any other value means error
//
DBG_ASSERT( FALSE );
hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
goto ExitPoint;
}
//
// First lookup in the cache
// Because we don't preread all the endpoint configuration stored in HttpAPI Config
// store in out hash table, it is not straightforward to handle wildcard endpoint
// configuration
// If endpoint configuration lookup returned data based on wildcard endpoint config
// we will still store it in the hash table for the specific endpoint we looked up
// Otherwise there is is risk that wildcard endpoint config stored in the hash table
// could override individual endpoint settings that exist in the HttpAPI config store
// but were not yet read and stored in our hash table
//
DBG_ASSERT( sm_pEndpointConfigHash != NULL );
ENDPOINT_KEY EndpointKey = GenerateEndpointKey( LocalAddress, LocalPort );
lkrc = sm_pEndpointConfigHash->FindKey(
&EndpointKey,
&pEndpointConfig );
if ( lkrc == LK_SUCCESS )
{
DBG_ASSERT( pEndpointConfig != NULL );
*ppEndpointConfig = pEndpointConfig;
hr = S_OK;
goto ExitPoint;
}
//
// Ok, nothing cached. We will have to make a lookup in the persistent store
//
//
// Try to lookup config info through HTTPAPI
// fWildcardMatch is currently ignored we will store retrieved config data
// for the specific endpoint
//
hr = GetEndpointConfigData(
LocalAddress,
LocalPort,
&pEndpointConfigData,
&fWildcardMatch );
if ( hr == HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) && fCreateEmptyIfNotFound )
{
//
// Create empty endpoint info
// This will optimize the EnableRawFilter lookups
// because without cached entry for each new raw Filter connection
// we would need to make HttpApi config lookup
// (empty endpoint indicates that it is OK to do Raw Filter handling)
//
pEndpointConfigData = NULL;
pEndpointConfig = new ENDPOINT_CONFIG( LocalAddress,
LocalPort,
NULL, // no Server Cert info
NULL, // No Ctl info
pEndpointConfigData );
if ( pEndpointConfig == NULL )
{
hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
goto ExitPoint;
}
else
{
// ENDPOINT_CONFIG took ownership of pEndpointConfigData
pEndpointConfigData = NULL;
}
}
else if ( FAILED( hr ) )
{
//
// Not finding the site just means this is not an SSL site
//
goto ExitPoint;
}
else if ( pEndpointConfigData != NULL &&
pEndpointConfigData->ParamDesc.SslHashLength == 0 )
{
//
// Store endpoint config for nonsecure Endpoint
// to flag if Raw Filters are enabled or disabled
//
pEndpointConfig = new ENDPOINT_CONFIG( LocalAddress,
LocalPort,
NULL,
NULL,
pEndpointConfigData );
if ( pEndpointConfig == NULL )
{
hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
goto ExitPoint;
}
else
{
// ENDPOINT_CONFIG took ownership of pEndpointConfigData
pEndpointConfigData = NULL;
}
}
else
{
//
// To get this far means that we expect correct SSL endpoint info
// to be available
//
//
// We have enough to lookup in SERVER_CERT cache
//
hr = SERVER_CERT::GetServerCertificate( (PBYTE) pEndpointConfigData->ParamDesc.pSslHash,
pEndpointConfigData->ParamDesc.SslHashLength,
pEndpointConfigData->ParamDesc.pSslCertStoreName,
&pServerCert );
if ( FAILED( hr ) )
{
//
// If we couldn't get a server cert, SSL will
// not be enablable for this site
//
goto ExitPoint;
}
DBG_ASSERT( pServerCert != NULL );
hr = IIS_CTL::GetIisCtl( pEndpointConfigData->ParamDesc.pDefaultSslCtlIdentifier,
pEndpointConfigData->ParamDesc.pDefaultSslCtlStoreName,
&pIisCtl );
//
// if CTL context creation failed, we must not fail site config creation
// because CTLs are not mandatory for all scenarios (only client certificate
// scenarios require them, so we have to make sure that those would be failing )
//
if ( FAILED( hr ) )
{
pIisCtl = NULL;
//
// BUGBUG: Error loading CTL should be logged into event log
//
hr = S_OK;
}
//
// OK. Create the config and attempt to add it to the cache
//
pEndpointConfig = new ENDPOINT_CONFIG( ( LocalAddress ),
LocalPort,
pServerCert,
pIisCtl,
pEndpointConfigData );
if ( pEndpointConfig == NULL )
{
if ( pServerCert != NULL )
{
pServerCert->DereferenceServerCert();
pServerCert = NULL;
}
if ( pIisCtl != NULL )
{
pIisCtl->DereferenceIisCtl();
pIisCtl = NULL;
}
hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
goto ExitPoint;
}
else
{
// ENDPOINT_CONFIG took ownership of pEndpointConfigData
pEndpointConfigData = NULL;
}
//
// Acquire credentials
//
hr = pEndpointConfig->AcquireCredentials();
if ( FAILED( hr ) )
{
delete pEndpointConfig;
pEndpointConfig = NULL;
goto ExitPoint;
}
}
//
// We don't care what the success of the insertion was. If it failed,
// then the pEndpointConfig will not be extra referenced and the caller
// will clean it up when it derefs
//
sm_pEndpointConfigHash->InsertRecord( pEndpointConfig );
*ppEndpointConfig = pEndpointConfig;
hr = S_OK;
ExitPoint:
if ( pEndpointConfigData != NULL )
{
delete [] pEndpointConfigData;
pEndpointConfigData = NULL;
}
return hr;
}
//static
LK_PREDICATE
ENDPOINT_CONFIG::ServerCertPredicate(
ENDPOINT_CONFIG * pEndpointConfig,
void * pvState
)
/*++
Description:
DeleteIf() predicate used to find items which reference the
SERVER_CERT pointed to by pvState
Arguments:
pEndpointConfig - SSL endpoint config
pvState - SERVER_CERT to check for
Returns:
LK_PREDICATE - LKP_PERFORM indicates removing the current
token from token cache
LKP_NO_ACTION indicates doing nothing.
--*/
{
LK_PREDICATE lkpAction;
SERVER_CERT * pServerCert;
DBG_ASSERT( pEndpointConfig != NULL );
pServerCert = (SERVER_CERT*) pvState;
DBG_ASSERT( pServerCert != NULL );
DBG_ASSERT( pServerCert->CheckSignature() );
if ( pEndpointConfig->QueryServerCert() == pServerCert )
{
lkpAction = LKP_PERFORM;
}
else
{
lkpAction = LKP_NO_ACTION;
}
return lkpAction;
}
//static
HRESULT
ENDPOINT_CONFIG::FlushByServerCert(
SERVER_CERT * pServerCert
)
/*++
Routine Description:
Flush the ENDPOINT_CONFIG cache of anything referecing the given server
certificate
Arguments:
pServerCert - Server certificate to reference
Return Value:
HRESULT
--*/
{
DBG_ASSERT( sm_pEndpointConfigHash != NULL );
sm_pEndpointConfigHash->DeleteIf( ENDPOINT_CONFIG::ServerCertPredicate,
pServerCert );
return NO_ERROR;
}
//static
LK_PREDICATE
ENDPOINT_CONFIG::IisCtlPredicate(
ENDPOINT_CONFIG * pEndpointConfig,
void * pvState
)
/*++
Description:
DeleteIf() predicate used to find items which reference the
SERVER_CERT pointed to by pvState
Arguments:
pEndpointConfig - SSL endpoint config
pvState - IIS_CTL to check for
Returns:
LK_PREDICATE - LKP_PERFORM indicates removing the current
token from token cache
LKP_NO_ACTION indicates doing nothing.
--*/
{
LK_PREDICATE lkpAction;
IIS_CTL * pIisCtl;
DBG_ASSERT( pEndpointConfig != NULL );
pIisCtl = (IIS_CTL*) pvState;
DBG_ASSERT( pIisCtl != NULL );
DBG_ASSERT( pIisCtl->CheckSignature() );
if ( pEndpointConfig->QueryIisCtl() == pIisCtl )
{
lkpAction = LKP_PERFORM;
}
else
{
lkpAction = LKP_NO_ACTION;
}
return lkpAction;
}
//static
HRESULT
ENDPOINT_CONFIG::FlushByIisCtl(
IIS_CTL * pIisCtl
)
/*++
Routine Description:
Flush the ENDPOINT_CONFIG cache of anything referecing the given CTL
Arguments:
pIisCtl -
Return Value:
HRESULT
--*/
{
DBG_ASSERT( sm_pEndpointConfigHash != NULL );
sm_pEndpointConfigHash->DeleteIf( ENDPOINT_CONFIG::IisCtlPredicate,
pIisCtl );
return NO_ERROR;
}
//static
LK_PREDICATE
ENDPOINT_CONFIG::SiteIdPredicate(
ENDPOINT_CONFIG * /*pEndpointConfig*/,
void * pvState
)
/*++
Description:
DeleteIf() predicate to delete config specified by site id (pvState)
Arguments:
pEndpointConfig - SSL Endpoint config
pvState - Site ID
Returns:
LK_PREDICATE - LKP_PERFORM indicates removing the current
token from token cache
LKP_NO_ACTION indicates doing nothing.
--*/
{
LK_PREDICATE lkpAction;
DWORD dwSiteId;
dwSiteId = PtrToUlong(pvState);
//
// Site Id is legacy value - all endpoints will be deleted
// upon change because we don't internally track site ID any more
// CODEWORK: Site concept should be completely removed from the code
// Remove before RC1
lkpAction = LKP_PERFORM;
return lkpAction;
}
//static
LK_PREDICATE
ENDPOINT_CONFIG::EndpointPredicate(
ENDPOINT_CONFIG * pEndpointConfig,
void * pvState
)
/*++
Description:
DeleteIf() predicate to delete config specified by site id (pvState)
Arguments:
pEndpointConfig - SSL Endpoint config
pvState - Endpoint key
Returns:
LK_PREDICATE - LKP_PERFORM indicates removing the current
token from token cache
LKP_NO_ACTION indicates doing nothing.
--*/
{
LK_PREDICATE lkpAction;
ENDPOINT_KEY * pEndpointKey;
DBG_ASSERT( pEndpointConfig != NULL );
pEndpointKey = (ENDPOINT_KEY *) (pvState);
if ( *( pEndpointConfig->QueryEndpointKey() ) == *pEndpointKey ||
*pEndpointKey == GenerateEndpointKey( INADDR_ANY, 0 ) )
{
// 0 means to delete all the endpoint info
lkpAction = LKP_PERFORM;
}
else
{
lkpAction = LKP_NO_ACTION;
}
return lkpAction;
}
//static
HRESULT
ENDPOINT_CONFIG::FlushByEndpoint(
DWORD LocalAddress,
USHORT LocalPort
)
/*++
Routine Description:
Flush specified site configuration. If dwSiteId is 0, then flush all
Arguments:
LocalAddress - IP Address
LocalPort - Port
if LocalAddress=INADDR_ANY and LocalPort=0 then all endpoints will be flushed
Return Value:
HRESULT
--*/
{
DBG_ASSERT( sm_pEndpointConfigHash != NULL );
ENDPOINT_KEY EndpointKey = GenerateEndpointKey( LocalAddress, LocalPort );
sm_pEndpointConfigHash->DeleteIf( ENDPOINT_CONFIG::EndpointPredicate,
(PVOID) &EndpointKey );
return NO_ERROR;
}
ENDPOINT_CONFIG::~ENDPOINT_CONFIG()
{
if ( _pServerCert != NULL )
{
_pServerCert->DereferenceServerCert();
_pServerCert = NULL;
}
if ( _pIisCtl != NULL )
{
_pIisCtl->DereferenceIisCtl();
_pIisCtl = NULL;
}
if ( _pEndpointConfigData != NULL )
{
delete [] _pEndpointConfigData;
_pEndpointConfigData = NULL;
}
_dwSignature = ENDPOINT_CONFIG_SIGNATURE_FREE;
}
HRESULT
ENDPOINT_CONFIG::AcquireCredentials(
VOID
)
/*++
Routine Description:
Do the Schannel thing to get credentials handle representing the
server cert/mapping configuration of this site
Arguments:
None
Return Value:
HRESULT
--*/
{
DBG_ASSERT( _pServerCert != NULL );
return _SiteCreds.AcquireCredentials( _pServerCert,
QueryUseDSMapper() );
}
// static
VOID
WINAPI
ENDPOINT_CONFIG::ConfigStoreChangeCallback(
PVOID /*pParam*/,
BOOL /*fWaitFired*/
)
/*++
Routine Description:
Callback when HttpApi config store change occurs
Note: Currently we listen directly on registry changes
CODEWORK: once httpapi provides change notification mechanism
we have to use that one
Arguments:
not used
Return Value:
--*/
{
//
// If we fail to re-register for change notifications
// we will ignore it. This will unfortunately stop all
// the future change notifications
// CODEWORK: consider if there is anything else we can do
//
RegNotifyChangeKeyValue( sm_hHttpApiConfigKey,
TRUE,
REG_NOTIFY_CHANGE_LAST_SET |
REG_NOTIFY_CHANGE_NAME,
sm_hHttpApiConfigChangeEvent,
TRUE );
//
// There is no straightforward mechanism to figure out individual change
// that happened. That's why we will flush all endpoints config
// ( Changes in the endpoint config are not frequent so this should not be
// a performance problem at all )
//
FlushByEndpoint( INADDR_ANY, 0 );
}
//static
VOID
ENDPOINT_CONFIG::Cleanup(
VOID
)
/*++
Routine Description:
Cleanup must be called before Terminate
Arguments:
none
Return Value:
VOID
--*/
{
sm_pEndpointConfigHash->Clear();
}