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.
 
 
 
 
 
 

882 lines
20 KiB

//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000.
//
// File: filters-r.c
//
// Contents: Filter management for registry.
//
//
// History: KrishnaG.
// AbhisheV.
//
//----------------------------------------------------------------------------
#include "precomp.h"
extern LPWSTR FilterDNAttributes[];
DWORD
RegEnumFilterData(
HKEY hRegistryKey,
LPWSTR pszIpsecRootContainer,
PIPSEC_FILTER_DATA ** pppIpsecFilterData,
PDWORD pdwNumFilterObjects
)
{
DWORD dwError = 0;
PIPSEC_FILTER_OBJECT * ppIpsecFilterObjects = NULL;
PIPSEC_FILTER_DATA pIpsecFilterData = NULL;
PIPSEC_FILTER_DATA * ppIpsecFilterData = NULL;
DWORD dwNumFilterObjects = 0;
DWORD i = 0;
DWORD j = 0;
dwError = RegEnumFilterObjects(
hRegistryKey,
pszIpsecRootContainer,
&ppIpsecFilterObjects,
&dwNumFilterObjects
);
BAIL_ON_WIN32_ERROR(dwError);
if (dwNumFilterObjects) {
ppIpsecFilterData = (PIPSEC_FILTER_DATA *) AllocPolMem(
dwNumFilterObjects*sizeof(PIPSEC_FILTER_DATA)
);
if (!ppIpsecFilterData) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
}
for (i = 0; i < dwNumFilterObjects; i++) {
dwError = RegUnmarshallFilterData(
*(ppIpsecFilterObjects + i),
&pIpsecFilterData
);
if (!dwError) {
*(ppIpsecFilterData + j) = pIpsecFilterData;
j++;
}
}
if (j == 0) {
if (ppIpsecFilterData) {
FreePolMem(ppIpsecFilterData);
ppIpsecFilterData = NULL;
}
}
*pppIpsecFilterData = ppIpsecFilterData;
*pdwNumFilterObjects = j;
dwError = ERROR_SUCCESS;
cleanup:
if (ppIpsecFilterObjects) {
FreeIpsecFilterObjects(
ppIpsecFilterObjects,
dwNumFilterObjects
);
}
return(dwError);
error:
if (ppIpsecFilterData) {
FreeMulIpsecFilterData(
ppIpsecFilterData,
i
);
}
*pppIpsecFilterData = NULL;
*pdwNumFilterObjects = 0;
goto cleanup;
}
DWORD
RegEnumFilterObjects(
HKEY hRegistryKey,
LPWSTR pszIpsecRootContainer,
PIPSEC_FILTER_OBJECT ** pppIpsecFilterObjects,
PDWORD pdwNumFilterObjects
)
{
DWORD dwError = 0;
DWORD i = 0;
DWORD dwCount = 0;
PIPSEC_FILTER_OBJECT pIpsecFilterObject = NULL;
PIPSEC_FILTER_OBJECT * ppIpsecFilterObjects = NULL;
DWORD dwNumFilterObjectsReturned = 0;
DWORD dwIndex = 0;
WCHAR szFilterName[MAX_PATH];
DWORD dwSize = 0;
*pppIpsecFilterObjects = NULL;
*pdwNumFilterObjects = 0;
while (1) {
dwSize = MAX_PATH;
szFilterName[0] = L'\0';
dwError = RegEnumKeyExW(
hRegistryKey,
dwIndex,
szFilterName,
&dwSize,
NULL,
NULL,
0,
0
);
if (dwError == ERROR_NO_MORE_ITEMS) {
break;
}
BAIL_ON_WIN32_ERROR(dwError);
if (!wcsstr(szFilterName, L"ipsecFilter")) {
dwIndex++;
continue;
}
pIpsecFilterObject = NULL;
dwError =UnMarshallRegistryFilterObject(
hRegistryKey,
pszIpsecRootContainer,
szFilterName,
REG_RELATIVE_NAME,
&pIpsecFilterObject
);
if (dwError == ERROR_SUCCESS) {
dwError = ReallocatePolMem(
(LPVOID *) &ppIpsecFilterObjects,
sizeof(PIPSEC_FILTER_OBJECT)*(dwNumFilterObjectsReturned),
sizeof(PIPSEC_FILTER_OBJECT)*(dwNumFilterObjectsReturned + 1)
);
BAIL_ON_WIN32_ERROR(dwError);
*(ppIpsecFilterObjects + dwNumFilterObjectsReturned) = pIpsecFilterObject;
dwNumFilterObjectsReturned++;
}
dwIndex++;
}
*pppIpsecFilterObjects = ppIpsecFilterObjects;
*pdwNumFilterObjects = dwNumFilterObjectsReturned;
dwError = ERROR_SUCCESS;
return(dwError);
error:
if (ppIpsecFilterObjects) {
FreeIpsecFilterObjects(
ppIpsecFilterObjects,
dwNumFilterObjectsReturned
);
}
if (pIpsecFilterObject) {
FreeIpsecFilterObject(
pIpsecFilterObject
);
}
*pppIpsecFilterObjects = NULL;
*pdwNumFilterObjects = 0;
return(dwError);
}
DWORD
RegSetFilterData(
HKEY hRegistryKey,
LPWSTR pszIpsecRootContainer,
LPWSTR pszLocationName,
PIPSEC_FILTER_DATA pIpsecFilterData
)
{
DWORD dwError = 0;
PIPSEC_FILTER_OBJECT pIpsecFilterObject = NULL;
dwError = RegMarshallFilterObject(
pIpsecFilterData,
&pIpsecFilterObject
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = RegSetFilterObject(
hRegistryKey,
pszIpsecRootContainer,
pIpsecFilterObject
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = RegBackPropIncChangesForFilterToNFA(
hRegistryKey,
pszIpsecRootContainer,
pszLocationName,
pIpsecFilterObject
);
BAIL_ON_WIN32_ERROR(dwError);
error:
if (pIpsecFilterObject) {
FreeIpsecFilterObject(pIpsecFilterObject);
}
return(dwError);
}
DWORD
RegSetFilterObject(
HKEY hRegistryKey,
LPWSTR pszIpsecRootContainer,
PIPSEC_FILTER_OBJECT pIpsecFilterObject
)
{
DWORD dwError = 0;
dwError = PersistFilterObject(
hRegistryKey,
pIpsecFilterObject
);
BAIL_ON_WIN32_ERROR(dwError);
error:
return(dwError);
}
DWORD
RegCreateFilterData(
HKEY hRegistryKey,
LPWSTR pszIpsecRootContainer,
PIPSEC_FILTER_DATA pIpsecFilterData
)
{
DWORD dwError = 0;
PIPSEC_FILTER_OBJECT pIpsecFilterObject = NULL;
dwError = RegMarshallFilterObject(
pIpsecFilterData,
&pIpsecFilterObject
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = RegCreateFilterObject(
hRegistryKey,
pszIpsecRootContainer,
pIpsecFilterObject
);
BAIL_ON_WIN32_ERROR(dwError);
error:
if (pIpsecFilterObject) {
FreeIpsecFilterObject(
pIpsecFilterObject
);
}
return(dwError);
}
DWORD
RegCreateFilterObject(
HKEY hRegistryKey,
LPWSTR pszIpsecRootContainer,
PIPSEC_FILTER_OBJECT pIpsecFilterObject
)
{
DWORD dwError = 0;
dwError = PersistFilterObject(
hRegistryKey,
pIpsecFilterObject
);
BAIL_ON_WIN32_ERROR(dwError);
error:
return(dwError);
}
DWORD
RegDeleteFilterData(
HKEY hRegistryKey,
LPWSTR pszIpsecRootContainer,
GUID FilterIdentifier
)
{
DWORD dwError = ERROR_SUCCESS;
WCHAR szGuid[MAX_PATH];
WCHAR szDistinguishedName[MAX_PATH];
LPWSTR pszStringUuid = NULL;
szGuid[0] = L'\0';
szDistinguishedName[0] = L'\0';
dwError = UuidToString(
&FilterIdentifier,
&pszStringUuid
);
BAIL_ON_WIN32_ERROR(dwError);
wcscpy(szGuid, L"{");
wcscat(szGuid, pszStringUuid);
wcscat(szGuid, L"}");
wcscpy(szDistinguishedName,L"ipsecFilter");
wcscat(szDistinguishedName, szGuid);
dwError = RegDeleteKeyW(
hRegistryKey,
szDistinguishedName
);
BAIL_ON_WIN32_ERROR(dwError);
error:
if (pszStringUuid) {
RpcStringFree(&pszStringUuid);
}
return(dwError);
}
DWORD
RegUnmarshallFilterData(
PIPSEC_FILTER_OBJECT pIpsecFilterObject,
PIPSEC_FILTER_DATA * ppIpsecFilterData
)
{
DWORD dwError = 0;
dwError = UnmarshallFilterObject(
pIpsecFilterObject,
ppIpsecFilterData
);
return(dwError);
}
DWORD
RegMarshallFilterObject(
PIPSEC_FILTER_DATA pIpsecFilterData,
PIPSEC_FILTER_OBJECT * ppIpsecFilterObject
)
{
DWORD dwError = 0;
PIPSEC_FILTER_OBJECT pIpsecFilterObject = NULL;
WCHAR szGuid[MAX_PATH];
WCHAR szDistinguishedName[MAX_PATH];
LPBYTE pBuffer = NULL;
DWORD dwBufferLen = 0;
LPWSTR pszStringUuid = NULL;
time_t PresentTime;
szGuid[0] = L'\0';
szDistinguishedName[0] = L'\0';
pIpsecFilterObject = (PIPSEC_FILTER_OBJECT)AllocPolMem(
sizeof(IPSEC_FILTER_OBJECT)
);
if (!pIpsecFilterObject) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
dwError = UuidToString(
&pIpsecFilterData->FilterIdentifier,
&pszStringUuid
);
BAIL_ON_WIN32_ERROR(dwError);
wcscpy(szGuid, L"{");
wcscat(szGuid, pszStringUuid);
wcscat(szGuid, L"}");
//
// Fill in the distinguishedName
//
wcscpy(szDistinguishedName,L"ipsecFilter");
wcscat(szDistinguishedName, szGuid);
pIpsecFilterObject->pszDistinguishedName = AllocPolStr(
szDistinguishedName
);
if (!pIpsecFilterObject->pszDistinguishedName) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
//
// Fill in the ipsecName
//
if (pIpsecFilterData->pszIpsecName &&
*pIpsecFilterData->pszIpsecName) {
pIpsecFilterObject->pszIpsecName = AllocPolStr(
pIpsecFilterData->pszIpsecName
);
if (!pIpsecFilterObject->pszIpsecName) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
}
if (pIpsecFilterData->pszDescription &&
*pIpsecFilterData->pszDescription) {
pIpsecFilterObject->pszDescription = AllocPolStr(
pIpsecFilterData->pszDescription
);
if (!pIpsecFilterObject->pszDescription) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
}
//
// Fill in the ipsecID
//
pIpsecFilterObject->pszIpsecID = AllocPolStr(
szGuid
);
if (!pIpsecFilterObject->pszIpsecID) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
//
// Fill in the ipsecDataType
//
pIpsecFilterObject->dwIpsecDataType = 0x100;
//
// Marshall the pIpsecDataBuffer and the Length
//
dwError = MarshallFilterBuffer(
pIpsecFilterData,
&pBuffer,
&dwBufferLen
);
BAIL_ON_WIN32_ERROR(dwError);
pIpsecFilterObject->pIpsecData = pBuffer;
pIpsecFilterObject->dwIpsecDataLen = dwBufferLen;
time(&PresentTime);
pIpsecFilterObject->dwWhenChanged = (DWORD) PresentTime;
*ppIpsecFilterObject = pIpsecFilterObject;
cleanup:
if (pszStringUuid) {
RpcStringFree(
&pszStringUuid
);
}
return(dwError);
error:
if (pIpsecFilterObject) {
FreeIpsecFilterObject(
pIpsecFilterObject
);
}
*ppIpsecFilterObject = NULL;
goto cleanup;
}
DWORD
MarshallFilterBuffer(
PIPSEC_FILTER_DATA pIpsecFilterData,
LPBYTE * ppBuffer,
DWORD * pdwBufferLen
)
{
LPBYTE pMem = NULL;
DWORD dwNumFilterSpecs = 0;
PIPSEC_FILTER_SPEC * ppIpsecFilterSpecs = NULL;
PIPSEC_FILTER_SPEC pIpsecFilterSpec = NULL;
DWORD i = 0;
DWORD dwNumBytesAdvanced = 0;
DWORD dwError = 0;
LPBYTE pBuffer = NULL;
LPBYTE pCurrentPos = NULL;
PSPEC_BUFFER pSpecBuffer = NULL;
DWORD dwSpecSize = 0;
DWORD dwTotalSize = 0;
DWORD dwEffectiveSize = 0;
// {80DC20B5-2EC8-11d1-A89E-00A0248D3021}
static const GUID GUID_IPSEC_FILTER_BLOB =
{ 0x80dc20b5, 0x2ec8, 0x11d1, { 0xa8, 0x9e, 0x0, 0xa0, 0x24, 0x8d, 0x30, 0x21 } };
//
// Advance by the GUID
//
dwTotalSize += sizeof(GUID);
//
// Advance by a DWORD - Total size of the buffer.
//
dwTotalSize += sizeof(DWORD);
//
// Advance by a DWORD - this is dwNumFilterSpecs;
//
dwTotalSize += sizeof(DWORD);
dwNumFilterSpecs = pIpsecFilterData->dwNumFilterSpecs;
pSpecBuffer = (PSPEC_BUFFER)AllocPolMem(
sizeof(SPEC_BUFFER)*dwNumFilterSpecs
);
if (!pSpecBuffer) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
for (i = 0; i < dwNumFilterSpecs;i++){
dwError = MarshallFilterSpecBuffer(
*(pIpsecFilterData->ppFilterSpecs + i),
&pMem,
&dwSpecSize
);
BAIL_ON_WIN32_ERROR(dwError);
dwTotalSize += dwSpecSize;
//
// Fill in the spec size information
//
(pSpecBuffer + i)->dwSize = dwSpecSize;
(pSpecBuffer + i)->pMem = pMem;
}
dwTotalSize++;
pBuffer = AllocPolMem(dwTotalSize);
if (!pBuffer) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
pCurrentPos = pBuffer;
//
// Copy the GUID
//
memcpy(pCurrentPos, &GUID_IPSEC_FILTER_BLOB, sizeof(GUID));
pCurrentPos += sizeof(GUID);
dwEffectiveSize = dwTotalSize - sizeof(GUID) - sizeof(DWORD) - 1;
memcpy(pCurrentPos, &dwEffectiveSize, sizeof(DWORD));
pCurrentPos += sizeof(DWORD);
memcpy(pCurrentPos, &dwNumFilterSpecs, sizeof(DWORD));
pCurrentPos += sizeof(DWORD);
for (i = 0; i < dwNumFilterSpecs; i++) {
pMem = (pSpecBuffer + i)->pMem;
dwSpecSize = (pSpecBuffer + i)->dwSize;
memcpy(pCurrentPos, pMem, dwSpecSize);
pCurrentPos += dwSpecSize;
}
*ppBuffer = pBuffer;
*pdwBufferLen = dwTotalSize;
cleanup:
if (pSpecBuffer) {
FreeSpecBuffer(
pSpecBuffer,
dwNumFilterSpecs
);
}
return(dwError);
error:
if (pBuffer) {
FreePolMem(pBuffer);
}
*ppBuffer = NULL;
*pdwBufferLen = 0;
goto cleanup;
}
DWORD
MarshallFilterSpecBuffer(
PIPSEC_FILTER_SPEC pIpsecFilterSpec,
LPBYTE * ppMem,
DWORD * pdwSize
)
{
DWORD dwSrcDNSNameLen = 0;
DWORD dwDestDNSNameLen = 0;
DWORD dwDescriptionLen = 0;
LPBYTE pMem = NULL;
LPBYTE pCurrentPos = NULL;
DWORD dwSize = 0;
DWORD dwError = 0;
dwSize += sizeof(DWORD);
if (pIpsecFilterSpec->pszSrcDNSName &&
*pIpsecFilterSpec->pszSrcDNSName) {
dwSrcDNSNameLen = (wcslen(pIpsecFilterSpec->pszSrcDNSName) + 1)
*sizeof(WCHAR);
}
else {
dwSrcDNSNameLen = sizeof(WCHAR);
}
if (dwSrcDNSNameLen) {
dwSize += dwSrcDNSNameLen;
}
dwSize += sizeof(DWORD);
if (pIpsecFilterSpec->pszDestDNSName &&
*pIpsecFilterSpec->pszDestDNSName) {
dwDestDNSNameLen = (wcslen(pIpsecFilterSpec->pszDestDNSName) + 1)
*sizeof(WCHAR);
}
else {
dwDestDNSNameLen = sizeof(WCHAR);
}
if (dwDestDNSNameLen) {
dwSize += dwDestDNSNameLen;
}
dwSize += sizeof(DWORD);
if (pIpsecFilterSpec->pszDescription &&
*pIpsecFilterSpec->pszDescription) {
dwDescriptionLen = (wcslen(pIpsecFilterSpec->pszDescription) + 1)
*sizeof(WCHAR);
}
else {
dwDescriptionLen = sizeof(WCHAR);
}
if (dwDescriptionLen) {
dwSize += dwDescriptionLen;
}
//
// Filter Spec GUID
//
dwSize += sizeof(GUID);
//
// dwMirrorFlag
//
dwSize += sizeof(DWORD);
dwSize += sizeof(IPSEC_FILTER);
pMem = (LPBYTE)AllocPolMem(dwSize);
if (!pMem) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
pCurrentPos = pMem;
memcpy(pCurrentPos, &(dwSrcDNSNameLen), sizeof(DWORD));
pCurrentPos += sizeof(DWORD);
if (pIpsecFilterSpec->pszSrcDNSName &&
*pIpsecFilterSpec->pszSrcDNSName) {
memcpy(pCurrentPos, pIpsecFilterSpec->pszSrcDNSName, dwSrcDNSNameLen);
}
pCurrentPos += dwSrcDNSNameLen;
memcpy(pCurrentPos, &(dwDestDNSNameLen), sizeof(DWORD));
pCurrentPos += sizeof(DWORD);
if (pIpsecFilterSpec->pszDestDNSName &&
*pIpsecFilterSpec->pszDestDNSName) {
memcpy(pCurrentPos, pIpsecFilterSpec->pszDestDNSName, dwDestDNSNameLen);
}
pCurrentPos += dwDestDNSNameLen;
memcpy(pCurrentPos, &(dwDescriptionLen), sizeof(DWORD));
pCurrentPos += sizeof(DWORD);
if (pIpsecFilterSpec->pszDescription &&
*pIpsecFilterSpec->pszDescription) {
memcpy(pCurrentPos, pIpsecFilterSpec->pszDescription, dwDescriptionLen);
}
pCurrentPos += dwDescriptionLen;
memcpy(pCurrentPos, &(pIpsecFilterSpec->FilterSpecGUID), sizeof(GUID));
pCurrentPos += sizeof(GUID);
memcpy(pCurrentPos, &(pIpsecFilterSpec->dwMirrorFlag), sizeof(DWORD));
pCurrentPos += sizeof(DWORD);
memcpy(pCurrentPos, &(pIpsecFilterSpec->Filter), sizeof(IPSEC_FILTER));
*ppMem = pMem;
*pdwSize = dwSize;
return(dwError);
error:
*ppMem = NULL;
*pdwSize = 0;
return(dwError);
}
DWORD
RegGetFilterData(
HKEY hRegistryKey,
LPWSTR pszIpsecRootContainer,
GUID FilterGUID,
PIPSEC_FILTER_DATA * ppIpsecFilterData
)
{
DWORD dwError = 0;
PIPSEC_FILTER_OBJECT pIpsecFilterObject = NULL;
PIPSEC_FILTER_DATA pIpsecFilterData = NULL;
WCHAR szIpsecFilterName[MAX_PATH];
LPWSTR pszFilterName = NULL;
szIpsecFilterName[0] = L'\0';
wcscpy(szIpsecFilterName, L"ipsecFilter");
dwError = UuidToString(&FilterGUID, &pszFilterName);
BAIL_ON_WIN32_ERROR(dwError);
wcscat(szIpsecFilterName, L"{");
wcscat(szIpsecFilterName, pszFilterName);
wcscat(szIpsecFilterName, L"}");
dwError =UnMarshallRegistryFilterObject(
hRegistryKey,
pszIpsecRootContainer,
szIpsecFilterName,
REG_RELATIVE_NAME,
&pIpsecFilterObject
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = RegUnmarshallFilterData(
pIpsecFilterObject,
&pIpsecFilterData
);
BAIL_ON_WIN32_ERROR(dwError);
error:
if (pIpsecFilterObject) {
FreeIpsecFilterObject(
pIpsecFilterObject
);
}
if (pszFilterName) {
RpcStringFree(&pszFilterName);
}
*ppIpsecFilterData = pIpsecFilterData;
return(dwError);
}
VOID
FreeSpecBuffer(
PSPEC_BUFFER pSpecBuffer,
DWORD dwNumFilterSpecs
)
{
DWORD i = 0;
if (pSpecBuffer) {
for (i = 0; i < dwNumFilterSpecs; i++) {
if ((pSpecBuffer+i)->pMem) {
FreePolMem((pSpecBuffer+i)->pMem);
}
}
FreePolMem(pSpecBuffer);
}
return;
}