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.
486 lines
10 KiB
486 lines
10 KiB
#ifndef _SITECONFIG_HXX_
|
|
#define _SITECONFIG_HXX_
|
|
|
|
/*++
|
|
|
|
Copyright (c) 1998 Microsoft Corporation
|
|
|
|
Module Name :
|
|
siteconfig.hxx
|
|
|
|
Abstract:
|
|
SSL configuration for a given site
|
|
|
|
Author:
|
|
Bilal Alam (BAlam) 29-March-2000
|
|
|
|
Environment:
|
|
Win32 - User Mode
|
|
|
|
Project:
|
|
Stream Filter Worker Process
|
|
--*/
|
|
|
|
class ENDPOINT_CONFIG_HASH;
|
|
class SERVER_CERT;
|
|
|
|
|
|
typedef ULONGLONG ENDPOINT_KEY;
|
|
|
|
#define ENDPOINT_CONFIG_SIGNATURE (DWORD)'GFCS'
|
|
#define ENDPOINT_CONFIG_SIGNATURE_FREE (DWORD)'gfcs'
|
|
|
|
|
|
|
|
class ENDPOINT_CONFIG
|
|
{
|
|
public:
|
|
|
|
const ENDPOINT_KEY*
|
|
QueryEndpointKey(
|
|
VOID
|
|
) const
|
|
{
|
|
return &_EndpointKey;
|
|
}
|
|
|
|
SERVER_CERT *
|
|
QueryServerCert(
|
|
VOID
|
|
) const
|
|
{
|
|
return _pServerCert;
|
|
}
|
|
|
|
IIS_CTL *
|
|
QueryIisCtl(
|
|
VOID
|
|
) const
|
|
{
|
|
return _pIisCtl;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CheckSignature(
|
|
VOID
|
|
) const
|
|
{
|
|
return _dwSignature == ENDPOINT_CONFIG_SIGNATURE;
|
|
}
|
|
|
|
VOID
|
|
ReferenceEndpointConfig(
|
|
VOID
|
|
)
|
|
{
|
|
InterlockedIncrement( &_cRefs );
|
|
}
|
|
|
|
VOID
|
|
DereferenceEndpointConfig(
|
|
VOID
|
|
)
|
|
{
|
|
if ( InterlockedDecrement( &_cRefs ) == 0 )
|
|
{
|
|
delete this;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
QuerySslConfigured(
|
|
VOID
|
|
)
|
|
{
|
|
return _SiteCreds.QueryIsAvailable();
|
|
}
|
|
|
|
CredHandle *
|
|
QueryCredentials(
|
|
VOID
|
|
)
|
|
{
|
|
return _SiteCreds.QueryCredentials();
|
|
}
|
|
|
|
BOOL
|
|
QueryUseDSMapper(
|
|
VOID
|
|
)
|
|
{
|
|
if ( _pEndpointConfigData == NULL )
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return !!(_pEndpointConfigData->ParamDesc.DefaultFlags &
|
|
HTTP_SERVICE_CONFIG_SSL_FLAG_USE_DS_MAPPER);
|
|
}
|
|
|
|
}
|
|
|
|
BOOL
|
|
QueryNegotiateClientCert(
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// _fRequireClientCert is used for SSL optimization
|
|
// If RequireClientCert is set on the root level of the site
|
|
// then IIS will ask for mutual authentication right away
|
|
// That way the expensive renegotiation when the whole
|
|
// ssl key exchange must be repeated is eliminated
|
|
//
|
|
|
|
if ( _pEndpointConfigData == NULL )
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return !!(_pEndpointConfigData->ParamDesc.DefaultFlags &
|
|
HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT);
|
|
}
|
|
|
|
}
|
|
|
|
BOOL
|
|
QueryNoRawFilter(
|
|
VOID
|
|
)
|
|
{
|
|
if ( _pEndpointConfigData == NULL )
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return !!(_pEndpointConfigData->ParamDesc.DefaultFlags &
|
|
HTTP_SERVICE_CONFIG_SSL_FLAG_NO_RAW_FILTER);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsCtlRequired(
|
|
VOID
|
|
)
|
|
{
|
|
if ( _pEndpointConfigData == NULL )
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return
|
|
_pEndpointConfigData->ParamDesc.pDefaultSslCtlIdentifier != NULL &&
|
|
_pEndpointConfigData->ParamDesc.pDefaultSslCtlIdentifier[0] != L'\0';
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
QueryCertCheckMode(
|
|
VOID
|
|
)
|
|
{
|
|
if ( _pEndpointConfigData == NULL )
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return _pEndpointConfigData->ParamDesc.DefaultCertCheckMode;
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
QueryRevocationFreshnessTime(
|
|
VOID
|
|
)
|
|
{
|
|
if ( _pEndpointConfigData == NULL )
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return _pEndpointConfigData->ParamDesc.DefaultRevocationFreshnessTime;
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
QueryRevocationUrlRetrievalTimeout(
|
|
VOID
|
|
)
|
|
{
|
|
if ( _pEndpointConfigData == NULL )
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return _pEndpointConfigData->ParamDesc.DefaultRevocationUrlRetrievalTimeout;
|
|
}
|
|
}
|
|
|
|
HRESULT
|
|
AcquireCredentials(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
HRESULT
|
|
Initialize(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
VOID
|
|
Terminate(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
HRESULT
|
|
GetEndpointConfig(
|
|
CONNECTION_INFO * pConnectionInfo,
|
|
ENDPOINT_CONFIG ** ppEndpointConfig,
|
|
BOOL fCreateEmptyIfNotFound = FALSE
|
|
);
|
|
|
|
static
|
|
ENDPOINT_KEY
|
|
GenerateEndpointKey(
|
|
DWORD LocalAddress,
|
|
USHORT LocalPort
|
|
)
|
|
{
|
|
LARGE_INTEGER liKey;
|
|
|
|
// CODEWORK: this will break for IPv6
|
|
// Currently only wildcard IPs are supported for IPv6
|
|
liKey.HighPart = LocalAddress;
|
|
liKey.LowPart = LocalPort;
|
|
return liKey.QuadPart;
|
|
}
|
|
|
|
static
|
|
HRESULT
|
|
FlushByServerCert(
|
|
SERVER_CERT * pServerCert
|
|
);
|
|
|
|
static
|
|
HRESULT
|
|
FlushByIisCtl(
|
|
IIS_CTL * pIisCtl
|
|
);
|
|
|
|
|
|
static
|
|
HRESULT
|
|
FlushByEndpoint(
|
|
DWORD LocalAddress,
|
|
USHORT LocalPort
|
|
);
|
|
|
|
static
|
|
VOID
|
|
Cleanup(
|
|
VOID
|
|
);
|
|
|
|
|
|
static
|
|
VOID
|
|
WINAPI
|
|
ConfigStoreChangeCallback(
|
|
PVOID pParam,
|
|
BOOL fWaitFired
|
|
);
|
|
|
|
private:
|
|
|
|
// Constructor is private
|
|
// GetEndpointConfig() is to be called to get reference to the object
|
|
//
|
|
ENDPOINT_CONFIG(
|
|
DWORD LocalAddress,
|
|
USHORT LocalPort,
|
|
SERVER_CERT * pServerCert,
|
|
IIS_CTL * pIisCtl,
|
|
PHTTP_SERVICE_CONFIG_SSL_SET pEndpointConfigData
|
|
)
|
|
{
|
|
_cRefs = 1;
|
|
_dwSignature = ENDPOINT_CONFIG_SIGNATURE;
|
|
_LocalAddress = LocalAddress;
|
|
_LocalPort = LocalPort;
|
|
_EndpointKey = GenerateEndpointKey( LocalAddress, LocalPort );
|
|
_pServerCert = pServerCert;
|
|
_pEndpointConfigData = pEndpointConfigData; // takes ownership of the memory
|
|
_pIisCtl = pIisCtl;
|
|
}
|
|
|
|
// Destructor is private
|
|
// DereferenceEndpointConfig() is to be called for cleanup
|
|
//
|
|
virtual ~ENDPOINT_CONFIG();
|
|
|
|
static
|
|
LK_PREDICATE
|
|
ServerCertPredicate(
|
|
ENDPOINT_CONFIG * pEndpointConfig,
|
|
void * pvState
|
|
);
|
|
|
|
static
|
|
LK_PREDICATE
|
|
IisCtlPredicate(
|
|
ENDPOINT_CONFIG * pEndpointConfig,
|
|
void * pvState
|
|
);
|
|
|
|
static
|
|
LK_PREDICATE
|
|
SiteIdPredicate(
|
|
ENDPOINT_CONFIG * pEndpointConfig,
|
|
void * pvState
|
|
);
|
|
|
|
static
|
|
LK_PREDICATE
|
|
EndpointPredicate(
|
|
ENDPOINT_CONFIG * pEndpointConfig,
|
|
void * pvState
|
|
);
|
|
|
|
static
|
|
HRESULT
|
|
GetEndpointConfigData(
|
|
IN DWORD LocalAddress,
|
|
IN USHORT LocalPort,
|
|
OUT PHTTP_SERVICE_CONFIG_SSL_SET * ppEndpointConfigData,
|
|
OUT BOOL * pfWildcardMatch
|
|
);
|
|
|
|
private:
|
|
|
|
DWORD _dwSignature;
|
|
LONG _cRefs;
|
|
// key representing IP:Port
|
|
ENDPOINT_KEY _EndpointKey;
|
|
//
|
|
// we don't really need to store _LocalAddress and _LocalPort
|
|
// but for the debugging or logging it may be convenient
|
|
// to have the info available
|
|
//
|
|
DWORD _LocalAddress;
|
|
USHORT _LocalPort;
|
|
//
|
|
// SSL specific objects
|
|
//
|
|
SERVER_CERT * _pServerCert;
|
|
IIS_CTL * _pIisCtl;
|
|
SITE_CREDENTIALS _SiteCreds;
|
|
//
|
|
// SSL config and Enable Raw Filter flag
|
|
//
|
|
PHTTP_SERVICE_CONFIG_SSL_SET _pEndpointConfigData;
|
|
//
|
|
// Hash table caching endpoint configuration
|
|
//
|
|
static ENDPOINT_CONFIG_HASH * sm_pEndpointConfigHash;
|
|
//
|
|
// Objects needed to handle persistent endpoint config store
|
|
// change notification
|
|
//
|
|
static HANDLE sm_hHttpApiConfigChangeEvent;
|
|
static HKEY sm_hHttpApiConfigKey;
|
|
static HANDLE sm_hWaitHandle;
|
|
|
|
enum INIT_STATE {
|
|
INIT_NONE,
|
|
INIT_HTTPAPI,
|
|
INIT_HASH,
|
|
INIT_CHANGE_NOTIF
|
|
};
|
|
// Initialization state
|
|
static INIT_STATE sm_InitState;
|
|
};
|
|
|
|
class ENDPOINT_CONFIG_HASH
|
|
: public CTypedHashTable<
|
|
ENDPOINT_CONFIG_HASH,
|
|
ENDPOINT_CONFIG,
|
|
const ENDPOINT_KEY *
|
|
>
|
|
{
|
|
public:
|
|
ENDPOINT_CONFIG_HASH()
|
|
: CTypedHashTable< ENDPOINT_CONFIG_HASH,
|
|
ENDPOINT_CONFIG,
|
|
const ENDPOINT_KEY * > ( "ENDPOINT_CONFIG_HASH" )
|
|
{
|
|
}
|
|
|
|
static
|
|
const ENDPOINT_KEY *
|
|
ExtractKey(
|
|
const ENDPOINT_CONFIG * pEndpointConfig
|
|
)
|
|
{
|
|
return pEndpointConfig->QueryEndpointKey();
|
|
}
|
|
|
|
static
|
|
DWORD
|
|
CalcKeyHash(
|
|
const ENDPOINT_KEY * pEndpointKey
|
|
)
|
|
{
|
|
return HashBlob( pEndpointKey,
|
|
sizeof( ENDPOINT_KEY ) );
|
|
}
|
|
|
|
static
|
|
bool
|
|
EqualKeys(
|
|
const ENDPOINT_KEY * pEndpointKey1,
|
|
const ENDPOINT_KEY * pEndpointKey2
|
|
)
|
|
{
|
|
return *pEndpointKey1 == *pEndpointKey2;
|
|
}
|
|
|
|
static
|
|
void
|
|
AddRefRecord(
|
|
ENDPOINT_CONFIG * pEndpointConfig,
|
|
int nIncr
|
|
)
|
|
{
|
|
if ( nIncr == +1 )
|
|
{
|
|
pEndpointConfig->ReferenceEndpointConfig();
|
|
}
|
|
else if ( nIncr == -1 )
|
|
{
|
|
pEndpointConfig->DereferenceEndpointConfig();
|
|
}
|
|
}
|
|
private:
|
|
//
|
|
// Not implemented methods
|
|
// Declarations present to prevent compiler
|
|
// to generate default ones.
|
|
//
|
|
ENDPOINT_CONFIG_HASH( const ENDPOINT_CONFIG_HASH& );
|
|
ENDPOINT_CONFIG_HASH& operator=( const ENDPOINT_CONFIG_HASH& );
|
|
|
|
|
|
};
|
|
|
|
#endif
|