mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 19:24:29 +03:00
Merging IIS and nginx code into M2 trunk.
This commit is contained in:
640
iis/moduleconfig.cpp
Normal file
640
iis/moduleconfig.cpp
Normal file
@@ -0,0 +1,640 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#undef inline
|
||||
#define inline inline
|
||||
|
||||
// IIS7 Server API header file
|
||||
#include "httpserv.h"
|
||||
|
||||
// Project header files
|
||||
#include "mymodule.h"
|
||||
#include "mymodulefactory.h"
|
||||
#include "moduleconfig.h"
|
||||
|
||||
HRESULT
|
||||
MODSECURITY_STORED_CONTEXT::Initialize(
|
||||
IHttpContext * pW3Context,
|
||||
IAppHostConfigException ** ppException
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
IAppHostAdminManager *pAdminManager = NULL;
|
||||
IAppHostElement *pSessionTrackingElement = NULL;
|
||||
IAppHostPropertyException *pPropertyException = NULL;
|
||||
|
||||
PCWSTR pszConfigPath = pW3Context->GetMetadata()->GetMetaPath();
|
||||
BSTR bstrUrlPath = SysAllocString( pszConfigPath );
|
||||
|
||||
pAdminManager = g_pHttpServer->GetAdminManager();
|
||||
|
||||
if ( ( FAILED( hr ) ) || ( pAdminManager == NULL ) )
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Get a handle to the section:
|
||||
hr = pAdminManager->GetAdminSection(
|
||||
MODSECURITY_SECTION,
|
||||
bstrUrlPath,
|
||||
&pSessionTrackingElement );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
if ( pSessionTrackingElement == NULL )
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Get the property object for the 'enabled' attribute:
|
||||
hr = GetBooleanPropertyValue(
|
||||
pSessionTrackingElement,
|
||||
MODSECURITY_SECTION_ENABLED,
|
||||
&pPropertyException,
|
||||
&m_bIsEnabled);
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// If there is a config failure, we cannot continue execution:
|
||||
if ( pPropertyException != NULL )
|
||||
{
|
||||
|
||||
ppException = ( IAppHostConfigException** ) &pPropertyException;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
if ( m_bIsEnabled == FALSE )
|
||||
{
|
||||
// There is no point in reading any more of the config associated with the session
|
||||
// tracking section, since this feature is not enabled for the current URL
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Get the property object for the 'configfile' attribute:
|
||||
hr = GetStringPropertyValue(
|
||||
pSessionTrackingElement,
|
||||
MODSECURITY_SECTION_CONFIGFILE,
|
||||
&pPropertyException,
|
||||
&m_pszPath);
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// If there is a config failure, we cannot continue execution:
|
||||
if ( pPropertyException != NULL )
|
||||
{
|
||||
|
||||
ppException = ( IAppHostConfigException** ) &pPropertyException;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
Failure:
|
||||
SysFreeString( bstrUrlPath );
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MODSECURITY_STORED_CONTEXT::GetBooleanPropertyValue(
|
||||
IAppHostElement* pElement,
|
||||
WCHAR* pszPropertyName,
|
||||
IAppHostPropertyException** pException,
|
||||
BOOL* pBoolValue )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
IAppHostProperty *pProperty = NULL;
|
||||
VARIANT vPropertyValue;
|
||||
|
||||
if (
|
||||
( pElement == NULL ) ||
|
||||
( pszPropertyName == NULL ) ||
|
||||
( pException == NULL ) ||
|
||||
( pBoolValue == NULL )
|
||||
)
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Get the property object for the BOOLEAN attribute:
|
||||
hr = pElement->GetPropertyByName(
|
||||
pszPropertyName,
|
||||
&pProperty );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
if ( pProperty == NULL )
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Get the attribute value:
|
||||
VariantInit( &vPropertyValue );
|
||||
|
||||
hr = pProperty->get_Value( &vPropertyValue );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// See it there is an exception that might be due to the actual value in the
|
||||
// config not meeting validation criteria
|
||||
*pException = NULL;
|
||||
|
||||
hr = pProperty->get_Exception( pException );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// No need to continue if we got an exception...
|
||||
if ( ( *pException ) != NULL )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Finally, get the value:
|
||||
*pBoolValue = ( vPropertyValue.boolVal == VARIANT_TRUE ) ? TRUE : FALSE;
|
||||
|
||||
|
||||
Failure:
|
||||
VariantClear( &vPropertyValue );
|
||||
|
||||
if ( pProperty != NULL )
|
||||
{
|
||||
pProperty->Release();
|
||||
pProperty = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MODSECURITY_STORED_CONTEXT::GetDWORDPropertyValue(
|
||||
IAppHostElement* pElement,
|
||||
WCHAR* pszPropertyName,
|
||||
IAppHostPropertyException** pException,
|
||||
DWORD* pnValue )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
IAppHostProperty *pProperty = NULL;
|
||||
VARIANT vPropertyValue;
|
||||
|
||||
if (
|
||||
( pElement == NULL ) ||
|
||||
( pszPropertyName == NULL ) ||
|
||||
( pException == NULL ) ||
|
||||
( pnValue == NULL )
|
||||
)
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Get the property object for the INT attribute:
|
||||
hr = pElement->GetPropertyByName(
|
||||
pszPropertyName,
|
||||
&pProperty );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
if ( pProperty == NULL )
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Get the attribute value:
|
||||
VariantInit( &vPropertyValue );
|
||||
|
||||
hr = pProperty->get_Value( &vPropertyValue );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// See it there is an exception that might be due to the actual value in the
|
||||
// config not meeting validation criteria
|
||||
*pException = NULL;
|
||||
|
||||
hr = pProperty->get_Exception( pException );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// No need to continue if we got an exception...
|
||||
if ( ( *pException ) != NULL )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Finally, get the value:
|
||||
*pnValue = vPropertyValue.ulVal;
|
||||
|
||||
Failure:
|
||||
VariantClear( &vPropertyValue );
|
||||
|
||||
if ( pProperty != NULL )
|
||||
{
|
||||
pProperty->Release();
|
||||
pProperty = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MODSECURITY_STORED_CONTEXT::GetTimeSpanPropertyValue(
|
||||
IAppHostElement* pElement,
|
||||
WCHAR* pszPropertyName,
|
||||
IAppHostPropertyException** pException,
|
||||
ULONGLONG* pnValue )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
IAppHostProperty *pProperty = NULL;
|
||||
VARIANT vPropertyValue;
|
||||
|
||||
if (
|
||||
( pElement == NULL ) ||
|
||||
( pszPropertyName == NULL ) ||
|
||||
( pException == NULL ) ||
|
||||
( pnValue == NULL )
|
||||
)
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Get the property object for the INT attribute:
|
||||
hr = pElement->GetPropertyByName(
|
||||
pszPropertyName,
|
||||
&pProperty );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
if ( pProperty == NULL )
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Get the attribute value:
|
||||
VariantInit( &vPropertyValue );
|
||||
|
||||
hr = pProperty->get_Value( &vPropertyValue );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// See it there is an exception that might be due to the actual value in the
|
||||
// config not meeting validation criteria
|
||||
*pException = NULL;
|
||||
|
||||
hr = pProperty->get_Exception( pException );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// No need to continue if we got an exception...
|
||||
if ( ( *pException ) != NULL )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Finally, get the value:
|
||||
*pnValue = vPropertyValue.ullVal;
|
||||
|
||||
Failure:
|
||||
VariantClear( &vPropertyValue );
|
||||
|
||||
if ( pProperty != NULL )
|
||||
{
|
||||
pProperty->Release();
|
||||
pProperty = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MODSECURITY_STORED_CONTEXT::GetStringPropertyValue(
|
||||
IAppHostElement* pElement,
|
||||
WCHAR* pszPropertyName,
|
||||
IAppHostPropertyException** pException,
|
||||
WCHAR** ppszValue )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
IAppHostProperty *pProperty = NULL;
|
||||
DWORD dwLength;
|
||||
VARIANT vPropertyValue;
|
||||
|
||||
if (
|
||||
( pElement == NULL ) ||
|
||||
( pszPropertyName == NULL ) ||
|
||||
( pException == NULL ) ||
|
||||
( ppszValue == NULL )
|
||||
)
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
*ppszValue = NULL;
|
||||
|
||||
// Get the property object for the string attribute:
|
||||
hr = pElement->GetPropertyByName(
|
||||
pszPropertyName,
|
||||
&pProperty );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
if ( pProperty == NULL )
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Get the attribute value:
|
||||
VariantInit( &vPropertyValue );
|
||||
|
||||
hr = pProperty->get_Value( &vPropertyValue );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// See it there is an exception that might be due to the actual value in the
|
||||
// config not meeting validation criteria
|
||||
*pException = NULL;
|
||||
|
||||
hr = pProperty->get_Exception( pException );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// No need to continue if we got an exception...
|
||||
if ( ( *pException ) != NULL )
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
// Finally, get the value:
|
||||
dwLength = SysStringLen( vPropertyValue.bstrVal );
|
||||
*ppszValue = new WCHAR[ dwLength + 1 ];
|
||||
|
||||
if ( (*ppszValue) == NULL )
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
wcsncpy(
|
||||
*ppszValue,
|
||||
vPropertyValue.bstrVal,
|
||||
dwLength );
|
||||
|
||||
(*ppszValue)[ dwLength ] = L'\0';
|
||||
|
||||
Failure:
|
||||
VariantClear( &vPropertyValue );
|
||||
|
||||
if ( pProperty != NULL )
|
||||
{
|
||||
pProperty->Release();
|
||||
pProperty = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
MODSECURITY_STORED_CONTEXT::~MODSECURITY_STORED_CONTEXT()
|
||||
{
|
||||
if ( m_pszPath != NULL )
|
||||
{
|
||||
delete [] m_pszPath;
|
||||
m_pszPath = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MODSECURITY_STORED_CONTEXT::MODSECURITY_STORED_CONTEXT():
|
||||
m_bIsEnabled ( FALSE ),
|
||||
m_pszPath( NULL ),
|
||||
m_Config( NULL ),
|
||||
m_dwLastCheck( 0 )
|
||||
{
|
||||
m_LastChange.dwLowDateTime = 0;
|
||||
m_LastChange.dwHighDateTime = 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
MODSECURITY_STORED_CONTEXT::GlobalWideCharToMultiByte(
|
||||
WCHAR* pSource,
|
||||
DWORD dwLengthSource,
|
||||
CHAR** ppszDestination,
|
||||
USHORT* pdwLengthDestination )
|
||||
{
|
||||
DWORD dwResult = NULL;
|
||||
DWORD dwCount = 0;
|
||||
|
||||
if (
|
||||
( pSource == NULL ) ||
|
||||
( ppszDestination == NULL ) ||
|
||||
( pdwLengthDestination == NULL )
|
||||
)
|
||||
{
|
||||
dwResult = ERROR_INVALID_PARAMETER;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Initialize result length
|
||||
*pdwLengthDestination = 0;
|
||||
*ppszDestination = NULL;
|
||||
|
||||
dwCount = WideCharToMultiByte(
|
||||
CP_ACP,
|
||||
0,
|
||||
pSource,
|
||||
dwLengthSource + 1,
|
||||
*ppszDestination,
|
||||
0,
|
||||
NULL,
|
||||
NULL );
|
||||
|
||||
if ( 0 == dwCount )
|
||||
{
|
||||
dwResult = GetLastError ();
|
||||
|
||||
if ( dwResult == 0 )
|
||||
{
|
||||
dwResult = ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
*ppszDestination = new CHAR[ dwCount + 1 ];
|
||||
|
||||
if ( NULL == ( *ppszDestination ) )
|
||||
{
|
||||
dwResult = ERROR_OUTOFMEMORY;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Make sure the memory is 'clean':
|
||||
SecureZeroMemory(
|
||||
( *ppszDestination ),
|
||||
( dwCount + 1 ) * sizeof ( CHAR ) );
|
||||
|
||||
if (
|
||||
0 == WideCharToMultiByte(
|
||||
CP_ACP,
|
||||
0,
|
||||
pSource,
|
||||
dwLengthSource + 1,
|
||||
*ppszDestination,
|
||||
dwCount,
|
||||
NULL,
|
||||
NULL )
|
||||
)
|
||||
{
|
||||
dwResult = GetLastError();
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
*pdwLengthDestination = ( USHORT )dwCount;
|
||||
|
||||
Exit:
|
||||
if ( dwResult != 0 )
|
||||
{
|
||||
// Make sure we do the proper cleanup in the error case:
|
||||
if ( pdwLengthDestination != NULL )
|
||||
{
|
||||
*pdwLengthDestination = 0;
|
||||
}
|
||||
|
||||
if ( ppszDestination != NULL )
|
||||
{
|
||||
if ( ( *ppszDestination ) != NULL )
|
||||
{
|
||||
delete [] ( *ppszDestination );
|
||||
( *ppszDestination ) = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dwResult;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MODSECURITY_STORED_CONTEXT::GetConfig(
|
||||
IHttpContext * pContext,
|
||||
MODSECURITY_STORED_CONTEXT ** ppModuleConfig
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
MODSECURITY_STORED_CONTEXT * pModuleConfig = NULL;
|
||||
IHttpModuleContextContainer * pMetadataContainer = NULL;
|
||||
IAppHostConfigException * pException = NULL;
|
||||
|
||||
pMetadataContainer = pContext->GetMetadata()->GetModuleContextContainer();
|
||||
|
||||
if ( pMetadataContainer == NULL )
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
return hr;
|
||||
}
|
||||
|
||||
pModuleConfig = (MODSECURITY_STORED_CONTEXT *)pMetadataContainer->GetModuleContext( g_pModuleContext );
|
||||
if ( pModuleConfig != NULL )
|
||||
{
|
||||
//
|
||||
// We found stored data for this module for the metadata
|
||||
// object which is different for unique configuration path
|
||||
//
|
||||
*ppModuleConfig = pModuleConfig;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// If we reach here, that means this is first request or first
|
||||
// request after a configuration change IIS core will throw stored context away
|
||||
// if a change notification arrives for this metadata path
|
||||
//
|
||||
pModuleConfig = new MODSECURITY_STORED_CONTEXT();
|
||||
if ( pModuleConfig == NULL )
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
//
|
||||
// Read module configuration data and store in MODSECURITY_STORED_CONTEXT
|
||||
//
|
||||
hr = pModuleConfig->Initialize( pContext, &pException );
|
||||
if ( FAILED( hr ) || pException != NULL )
|
||||
{
|
||||
pModuleConfig->CleanupStoredContext();
|
||||
|
||||
pModuleConfig = NULL;
|
||||
hr = E_UNEXPECTED;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// Store MODSECURITY_STORED_CONTEXT data as metadata stored context
|
||||
//
|
||||
hr = pMetadataContainer->SetModuleContext( pModuleConfig,
|
||||
g_pModuleContext );
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
pModuleConfig->CleanupStoredContext();
|
||||
pModuleConfig = NULL;
|
||||
|
||||
//
|
||||
// It is possible that some other thread stored context before this thread
|
||||
// could do. Check returned hr and return context stored by other thread
|
||||
//
|
||||
if ( hr == HRESULT_FROM_WIN32( ERROR_ALREADY_ASSIGNED ) )
|
||||
{
|
||||
*ppModuleConfig = (MODSECURITY_STORED_CONTEXT *)pMetadataContainer->GetModuleContext( g_pModuleContext );
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
*ppModuleConfig = pModuleConfig;
|
||||
return hr;
|
||||
}
|
Reference in New Issue
Block a user