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.
 
 
 
 
 
 

439 lines
13 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name :
updateini.cpp
Abstract:
High level function to update the ini with new values
Author:
Christopher Achille (cachille)
Project:
URLScan Update
Revision History:
March 2002: Created
--*/
#include "stdafx.h"
#include "windows.h"
#include "updateini.h"
#include "parseini.h"
sURLScan_Settings g_urlSettings[] =
{ { L"options",
L"UseAllowVerbs",
{ L"UseAllowVerbs=1 ; If 1, use [AllowVerbs] section, else use the",
L" ; [DenyVerbs] section.",
L"",
NULL }
}, // UseAllowVerbs
{ L"options",
L"UseAllowExtensions",
{ L"UseAllowExtensions=0 ; If 1, use [AllowExtensions] section, else use",
L" ; the [DenyExtensions] section.",
L"",
NULL }
}, // UseAllowExtensions
{ L"options",
L"NormalizeUrlBeforeScan",
{ L"NormalizeUrlBeforeScan=1 ; If 1, canonicalize URL before processing.",
L"",
NULL }
}, // NormalizeUrlBeforeScan
{ L"options",
L"VerifyNormalization",
{ L"VerifyNormalization=1 ; If 1, canonicalize URL twice and reject request",
L" ; if a change occurs.",
NULL }
}, // VerifyNormalization
{ L"options",
L"AllowHighBitCharacters",
{ L"AllowHighBitCharacters=0 ; If 1, allow high bit (ie. UTF8 or MBCS)",
L" ; characters in URL.",
L"",
NULL }
}, // AllowHighBitCharacters
{ L"options",
L"AllowDotInPath",
{ L"AllowDotInPath=0 ; If 1, allow dots that are not file extensions.",
L"",
NULL }
}, // AllowDotInPath
{ L"options",
L"RemoveServerHeader",
{ L"RemoveServerHeader=0 ; If 1, remove the 'Server' header from response.",
L"",
NULL }
}, // RemoveServerHeader
{ L"options",
L"EnableLogging",
{ L"EnableLogging=1 ; If 1, log UrlScan activity.",
L"",
NULL }
}, // EnableLogging
{ L"options",
L"PerProcessLogging",
{ L"PerProcessLogging=0 ; If 1, the UrlScan.log filename will contain a PID",
L" ; (ie. UrlScan.123.log).",
L"",
NULL }
}, // PerProcessLogging
{ L"options",
L"AllowLateScanning",
{ L"AllowLateScanning=0 ; If 1, then UrlScan will load as a low priority",
L" ; filter.",
L"",
NULL }
}, // AllowLateScanning
{ L"options",
L"PerDayLogging",
{ L"PerDayLogging=1 ; If 1, UrlScan will produce a new log each day with",
L" ; activity in the form 'UrlScan.010101.log'.",
L"",
NULL }
}, // PerDayLogging
{ L"options",
L"UseFastPathReject",
{ L"UseFastPathReject=0 ; If 1, then UrlScan will not use the",
L" ; RejectResponseUrl or allow IIS to log the request.",
L"",
NULL }
}, // UseFastPathReject
{ L"options", // Section Name
L"LogLongUrls", // Setting Name
{ L"LogLongUrls=0 ; If 1, then up to 128K per request can be logged.",
L" ; If 0, then only 1k is allowed.",
L"",
NULL }
}, // LogLongURLs
{ L"options",
L"RejectResponseUrl",
{ L";",
L"; If UseFastPathReject is 0, then UrlScan will send",
L"; rejected requests to the URL specified by RejectResponseUrl.",
L"; If not specified, '/<Rejected-by-UrlScan>' will be used.",
L";",
L"",
L"RejectResponseUrl=",
L"",
NULL }
}, // RejectResponseUrl
{ L"options",
L"LoggingDirectory",
{ L";",
L"; LoggingDirectory can be used to specify the directory where the",
L"; log file will be created. This value should be the absolute path",
L"; (ie. c:\\some\\path). If not specified, then UrlScan will create",
L"; the log in the same directory where the UrlScan.dll file is located.",
L";",
L"",
L"LoggingDirectory=",
L"",
NULL }
}, // Logging Directory
{ L"options",
L"AlternateServerName",
{ L";",
L"; If RemoveServerHeader is 0, then AlternateServerName can be",
L"; used to specify a replacement for IIS's built in 'Server' header",
L";",
L"",
L"AlternateServerName=",
L"",
NULL }
}, // AlternateServerName
{ L"RequestLimits",
L"MaxUrl",
{ L"MaxUrl=16384",
NULL }
}, // MaxUrl
{ L"RequestLimits",
L"MaxQueryString",
{ L"MaxQueryString=4096",
NULL}
}, // MaxQueryString
{ L"RequestLimits",
L"MaxAllowedContentLength",
#ifdef PLEASE_BUILD_LESS_AGRESSIVE_DEFAULTS_VERSION
{ L"MaxAllowedContentLength=2000000000",
#else
{ L"MaxAllowedContentLength=30000000",
#endif
NULL }
} // MaxAllowedContentLength
};
sURLScan_Sections g_urlSections[] =
{ { L"RequestLimits", // Section Name
{ L"",
L";",
L"; The entries in this section impose limits on the length",
L"; of allowed parts of requests reaching the server.",
L";",
L"; It is possible to impose a limit on the length of the",
L"; value of a specific request header by prepending \"Max-\" to the",
L"; name of the header. For example, the following entry would",
L"; impose a limit of 100 bytes to the value of the",
L"; 'Content-Type' header:",
L";",
L"; Max-Content-Type=100",
L";",
L"; To list a header and not specify a maximum value, use 0",
L"; (ie. 'Max-User-Agent=0'). Also, any headers not listed",
L"; in this section will not be checked for length limits.",
L";",
L"; There are 3 special case limits:",
L";",
L"; - MaxAllowedContentLength specifies the maximum allowed",
L"; numeric value of the Content-Length request header. For",
L"; example, setting this to 1000 would cause any request",
L"; with a content length that exceeds 1000 to be rejected.",
#ifdef PLEASE_BUILD_LESS_AGRESSIVE_DEFAULTS_VERSION
L"; The default is 2000000000.",
#else
L"; The default is 30000000.",
#endif
L";",
L"; - MaxUrl specifies the maximum length of the request URL,",
L"; not including the query string. The default is 260 (which",
L"; is equivalent to MAX_PATH).",
L";",
L"; - MaxQueryString specifies the maximum length of the query",
L"; string. The default is 4096.",
L";",
L"",
#ifdef PLEASE_BUILD_LESS_AGRESSIVE_DEFAULTS_VERSION
L"MaxAllowedContentLength=2000000000",
#else
L"MaxAllowedContentLength=30000000",
#endif
L"MaxUrl=16384",
L"MaxQueryString=4096",
L"",
NULL }
} // end of RequestLimits
};
sURLScan_Items g_urlItems[] =
{ { L"DenyHeaders",
L"Transfer-Encoding:",
{ L"Transfer-Encoding:",
NULL }
}
};
// GetListLen
//
// Retrieve the Length of a variable length array of Strings
// This is a special case function that works for our structs
// above, because we leave the last String as NULL
//
DWORD GetListLen(LPWSTR szLines[])
{
DWORD dwLen = 0;
while ( szLines[dwLen] != NULL )
{
dwLen++;
}
return dwLen;
}
// GetIniPath
//
// Given the Path to the Dll, create the path to the ini
//
// Parameters:
// szDllPath - [in] The path to the binary for urlscan.dll
// szIniPath - [out] The path to the ini file
// dwIniLen - [in] The length of the string passed in for szIniPath
//
BOOL GetIniPath( LPTSTR szDllPath, LPTSTR szIniPath, DWORD dwIniLen )
{
LPTSTR szLastPeriod;
if ( _tcslen( szDllPath ) >= ( dwIniLen - 3 ) )
{
// Error, string is not big enough
return FALSE;
}
_tcscpy( szIniPath, szDllPath);
szLastPeriod = _tcsrchr( szIniPath, '.' );
if ( !szLastPeriod )
{
// Can not find the extension
return FALSE;
}
_tcscpy( szLastPeriod, URLSCAN_INI_EXTENSION );
return TRUE;
}
// UpdateIniSections
//
// Update the Sections in the Ini, by merging them with the ones we have
// defined
//
BOOL UpdateIniSections( CIniFile *pURLScanIniFile )
{
DWORD dwCurrentSection;
for ( dwCurrentSection = 0;
dwCurrentSection < ( (DWORD) sizeof( g_urlSections ) / sizeof ( sURLScan_Sections ) );
dwCurrentSection++)
{
if ( !pURLScanIniFile->DoesSectionExist( g_urlSections[ dwCurrentSection].szSection ) )
{
// Try to Create Section Then
if ( !pURLScanIniFile->AddSection( g_urlSections[dwCurrentSection].szSection ) )
{
// Failed to Add Section
return FALSE;
}
// Now try to add the correct lines to it
if ( g_urlSections[dwCurrentSection].szLines &&
!pURLScanIniFile->AddLinesToSection( g_urlSections[dwCurrentSection].szSection,
GetListLen( g_urlSections[dwCurrentSection].szLines ),
g_urlSections[dwCurrentSection].szLines ) )
{
// Failed to Add Lines
return FALSE;
}
}
}
return TRUE;
}
// UpdateIniSettings
//
// Update the Ini Settings inside the different sections if they are
// not already set
//
BOOL UpdateIniSettings( CIniFile *pURLScanIniFile )
{
DWORD dwCurrentSettings;
for ( dwCurrentSettings = 0;
dwCurrentSettings < ( (DWORD) sizeof( g_urlSettings ) / sizeof ( sURLScan_Settings ) );
dwCurrentSettings++)
{
if ( !pURLScanIniFile->DoesSectionExist( g_urlSettings[ dwCurrentSettings].szSection ) )
{
// Create Section Since it does not exist
if ( !pURLScanIniFile->AddSection( g_urlSettings[dwCurrentSettings].szSection ) )
{
return FALSE;
}
} // !pURLScanIniFile->DoesSectionExist
if ( !pURLScanIniFile->DoesSettingInSectionExist( g_urlSettings[dwCurrentSettings].szSection,
g_urlSettings[dwCurrentSettings].szSettingName ) )
{
// This setting does not exist, so lets add it
if ( !pURLScanIniFile->AddLinesToSection( g_urlSettings[dwCurrentSettings].szSection,
GetListLen( g_urlSettings[dwCurrentSettings].szLines ),
g_urlSettings[dwCurrentSettings].szLines ) )
{
return FALSE;
}
} // !pURLScanIniFile->DoesSettingInSectionExist
}
return TRUE;
}
// UpdateIniItems
//
// Update the Ini Settings inside the different sections if they are
// not already set
//
BOOL UpdateIniItems( CIniFile *pURLScanIniFile )
{
DWORD dwCurrentItems;
for ( dwCurrentItems = 0;
dwCurrentItems < ( (DWORD) sizeof( g_urlItems ) / sizeof ( sURLScan_Items ) );
dwCurrentItems++)
{
if ( !pURLScanIniFile->DoesSectionExist( g_urlItems[ dwCurrentItems].szSection ) )
{
// Create Section Since it does not exist
if ( !pURLScanIniFile->AddSection( g_urlSettings[dwCurrentItems].szSection ) )
{
return FALSE;
}
} // !pURLScanIniFile->DoesSectionExist
if ( !pURLScanIniFile->DoesItemInSectionExist( g_urlItems[dwCurrentItems].szSection,
g_urlItems[dwCurrentItems].szSettingName ) )
{
// This setting does not exist, so lets add it
if ( !pURLScanIniFile->AddLinesToSection( g_urlItems[dwCurrentItems].szSection,
GetListLen( g_urlItems[dwCurrentItems].szLines ),
g_urlItems[dwCurrentItems].szLines ) )
{
return FALSE;
}
} // !pURLScanIniFile->DoesItemInSectionExist
}
return TRUE;
}
// UpdateIni File
//
// Update the inf file with the new features
//
BOOL UpdateIni( LPTSTR szUrlScanPath )
{
CIniFile URLScanIniFile;
TCHAR szIniLocation[MAX_PATH];
BOOL bRet = TRUE;
if ( !GetIniPath( szUrlScanPath, szIniLocation, MAX_PATH ) ||
!URLScanIniFile.LoadFile( szIniLocation ) )
{
// Either we couldn't determine the location, or we couldn't
// load the file
return FALSE;
}
if ( bRet )
{
// Note: UpdateIniSections must come before UpdateIniSettings
#ifdef PLEASE_BUILD_LESS_AGRESSIVE_DEFAULTS_VERSION
bRet = UpdateIniSections( &URLScanIniFile ) &&
UpdateIniSettings( &URLScanIniFile );
#else
bRet = UpdateIniSections( &URLScanIniFile ) &&
UpdateIniSettings( &URLScanIniFile ) &&
UpdateIniItems( &URLScanIniFile );
#endif
}
if ( bRet )
{
// Everything so far so good, so lets write the new ini
bRet = URLScanIniFile.SaveFile( szIniLocation );
}
return bRet;
}