windows-nt/Source/XPSP1/NT/net/ipsec/spd/server/pamm-fil.c
2020-09-26 16:20:57 +08:00

619 lines
12 KiB
C

#include "precomp.h"
DWORD
PAAddMMFilters(
PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
PIPSEC_NFA_DATA * ppIpsecNFAData,
DWORD dwNumNFACount
)
{
DWORD dwError = 0;
DWORD i = 0;
for (i = 0; i < dwNumNFACount; i++) {
dwError = PAAddMMFilterSpecs(
pIpsecISAKMPData,
*(ppIpsecNFAData + i)
);
}
return (dwError);
}
DWORD
PAAddMMFilterSpecs(
PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
PIPSEC_NFA_DATA pIpsecNFAData
)
{
DWORD dwError = 0;
PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
PIPSEC_FILTER_DATA pIpsecFilterData = NULL;
PMMPOLICYSTATE pMMPolicyState = NULL;
PMMAUTHSTATE pMMAuthState = NULL;
DWORD dwNumFilterSpecs = 0;
PIPSEC_FILTER_SPEC * ppFilterSpecs = NULL;
DWORD i = 0;
PMMFILTERSTATE pMMFilterState = NULL;
PMM_FILTER pSPDMMFilter = NULL;
LPWSTR pServerName = NULL;
DWORD dwPersist = 0;
pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
if (!memcmp(
&(pIpsecNegPolData->NegPolType),
&(GUID_NEGOTIATION_TYPE_DEFAULT),
sizeof(GUID))) {
dwError = ERROR_SUCCESS;
return (dwError);
}
if (IsClearOnly(pIpsecNegPolData->NegPolAction) ||
IsBlocking(pIpsecNegPolData->NegPolAction)) {
dwError = ERROR_SUCCESS;
return (dwError);
}
pIpsecFilterData = pIpsecNFAData->pIpsecFilterData;
if (!pIpsecFilterData) {
dwError = ERROR_SUCCESS;
return (dwError);
}
pMMPolicyState = FindMMPolicyState(
pIpsecISAKMPData->ISAKMPIdentifier
);
if (!pMMPolicyState || !(pMMPolicyState->bInSPD)) {
dwError = ERROR_INVALID_PARAMETER;
return (dwError);
}
pMMAuthState = FindMMAuthState(
pIpsecNFAData->NFAIdentifier
);
if (!pMMAuthState || !(pMMAuthState->bInSPD)) {
dwError = ERROR_INVALID_PARAMETER;
return (dwError);
}
dwNumFilterSpecs = pIpsecFilterData->dwNumFilterSpecs;
ppFilterSpecs = pIpsecFilterData->ppFilterSpecs;
for (i = 0; i < dwNumFilterSpecs; i++) {
dwError = PACreateMMFilterState(
pIpsecISAKMPData,
pIpsecNFAData,
*(ppFilterSpecs + i),
&pMMFilterState
);
if (dwError) {
continue;
}
dwError = PACreateMMFilter(
pIpsecISAKMPData,
pIpsecNFAData,
*(ppFilterSpecs + i),
&pSPDMMFilter
);
if (dwError) {
pMMFilterState->hMMFilter = NULL;
pMMFilterState->pNext = gpMMFilterState;
gpMMFilterState = pMMFilterState;
continue;
}
dwError = AddMMFilter(
pServerName,
dwPersist,
pSPDMMFilter,
&(pMMFilterState->hMMFilter)
);
pMMFilterState->pNext = gpMMFilterState;
gpMMFilterState = pMMFilterState;
PAFreeMMFilter(pSPDMMFilter);
}
return (dwError);
}
DWORD
PACreateMMFilterState(
PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
PIPSEC_NFA_DATA pIpsecNFAData,
PIPSEC_FILTER_SPEC pFilterSpec,
PMMFILTERSTATE * ppMMFilterState
)
{
DWORD dwError = 0;
PMMFILTERSTATE pMMFilterState = NULL;
dwError = AllocateSPDMemory(
sizeof(MMFILTERSTATE),
&pMMFilterState
);
BAIL_ON_WIN32_ERROR(dwError);
memcpy(
&(pMMFilterState->gFilterID),
&(pFilterSpec->FilterSpecGUID),
sizeof(GUID)
);
memcpy(
&(pMMFilterState->gPolicyID),
&(pIpsecISAKMPData->ISAKMPIdentifier),
sizeof(GUID)
);
memcpy(
&(pMMFilterState->gMMAuthID),
&(pIpsecNFAData->NFAIdentifier),
sizeof(GUID)
);
pMMFilterState->hMMFilter = NULL;
pMMFilterState->pNext = NULL;
*ppMMFilterState = pMMFilterState;
return (dwError);
error:
*ppMMFilterState = NULL;
return (dwError);
}
DWORD
PACreateMMFilter(
PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
PIPSEC_NFA_DATA pIpsecNFAData,
PIPSEC_FILTER_SPEC pFilterSpec,
PMM_FILTER * ppSPDMMFilter
)
{
DWORD dwError = 0;
PMM_FILTER pSPDMMFilter = NULL;
WCHAR pszName[512];
dwError = AllocateSPDMemory(
sizeof(MM_FILTER),
&pSPDMMFilter
);
BAIL_ON_WIN32_ERROR(dwError);
memcpy(
&(pSPDMMFilter->gFilterID),
&(pFilterSpec->FilterSpecGUID),
sizeof(GUID)
);
if (pFilterSpec->pszDescription && *(pFilterSpec->pszDescription)) {
dwError = AllocateSPDString(
pFilterSpec->pszDescription,
&(pSPDMMFilter->pszFilterName)
);
BAIL_ON_WIN32_ERROR(dwError);
}
else {
wsprintf(pszName, L"%d", ++gdwMMFilterCounter);
dwError = AllocateSPDString(
pszName,
&(pSPDMMFilter->pszFilterName)
);
BAIL_ON_WIN32_ERROR(dwError);
}
PASetInterfaceType(
pIpsecNFAData->dwInterfaceType,
&(pSPDMMFilter->InterfaceType)
);
pSPDMMFilter->bCreateMirror = (BOOL) pFilterSpec->dwMirrorFlag;
pSPDMMFilter->dwFlags = 0;
if (!(pIpsecNFAData->dwTunnelFlags)) {
PASetAddress(
pFilterSpec->Filter.SrcMask,
pFilterSpec->Filter.SrcAddr,
&(pSPDMMFilter->SrcAddr)
);
PASetAddress(
pFilterSpec->Filter.DestMask,
pFilterSpec->Filter.DestAddr,
&(pSPDMMFilter->DesAddr)
);
}
else {
PASetAddress(
IP_ADDRESS_MASK_NONE,
IP_ADDRESS_ME,
&(pSPDMMFilter->SrcAddr)
);
pSPDMMFilter->bCreateMirror = TRUE;
PASetTunnelAddress(
((ULONG) pIpsecNFAData->dwTunnelIpAddr),
&(pSPDMMFilter->DesAddr)
);
}
pSPDMMFilter->dwDirection = 0;
pSPDMMFilter->dwWeight = 0;
memcpy(
&(pSPDMMFilter->gPolicyID),
&(pIpsecISAKMPData->ISAKMPIdentifier),
sizeof(GUID)
);
memcpy(
&(pSPDMMFilter->gMMAuthID),
&(pIpsecNFAData->NFAIdentifier),
sizeof(GUID)
);
*ppSPDMMFilter = pSPDMMFilter;
return (dwError);
error:
if (pSPDMMFilter) {
PAFreeMMFilter(
pSPDMMFilter
);
}
*ppSPDMMFilter = NULL;
return (dwError);
}
VOID
PASetInterfaceType(
DWORD dwInterfaceType,
PIF_TYPE pInterfaceType
)
{
if (dwInterfaceType == PASTORE_IF_TYPE_DIALUP) {
*pInterfaceType = INTERFACE_TYPE_DIALUP;
}
else if (dwInterfaceType == PASTORE_IF_TYPE_LAN) {
*pInterfaceType = INTERFACE_TYPE_LAN;
}
else {
*pInterfaceType = INTERFACE_TYPE_ALL;
}
}
VOID
PASetAddress(
ULONG uMask,
ULONG uAddr,
PADDR pAddr
)
{
if (uMask == IP_ADDRESS_MASK_NONE) {
pAddr->AddrType = IP_ADDR_UNIQUE;
pAddr->uIpAddr = uAddr;
pAddr->uSubNetMask = uMask;
}
else {
pAddr->AddrType = IP_ADDR_SUBNET;
pAddr->uIpAddr = uAddr;
pAddr->uSubNetMask = uMask;
}
}
VOID
PASetTunnelAddress(
ULONG uAddr,
PADDR pAddr
)
{
if (uAddr == SUBNET_ADDRESS_ANY) {
pAddr->AddrType = IP_ADDR_SUBNET;
pAddr->uIpAddr = uAddr;
pAddr->uSubNetMask = SUBNET_MASK_ANY;
}
else {
pAddr->AddrType = IP_ADDR_UNIQUE;
pAddr->uIpAddr = uAddr;
pAddr->uSubNetMask = IP_ADDRESS_MASK_NONE;
}
}
VOID
PAFreeMMFilter(
PMM_FILTER pSPDMMFilter
)
{
if (pSPDMMFilter) {
if (pSPDMMFilter->pszFilterName) {
FreeSPDString(pSPDMMFilter->pszFilterName);
}
FreeSPDMemory(pSPDMMFilter);
}
return;
}
DWORD
PADeleteAllMMFilters(
)
{
DWORD dwError = 0;
PMMFILTERSTATE pMMFilterState = NULL;
PMMFILTERSTATE pTemp = NULL;
PMMFILTERSTATE pLeftMMFilterState = NULL;
pMMFilterState = gpMMFilterState;
while (pMMFilterState) {
if (pMMFilterState->hMMFilter) {
dwError = DeleteMMFilter(
pMMFilterState->hMMFilter
);
if (!dwError) {
pTemp = pMMFilterState;
pMMFilterState = pMMFilterState->pNext;
FreeSPDMemory(pTemp);
}
else {
pTemp = pMMFilterState;
pMMFilterState = pMMFilterState->pNext;
pTemp->pNext = pLeftMMFilterState;
pLeftMMFilterState = pTemp;
}
}
else {
pTemp = pMMFilterState;
pMMFilterState = pMMFilterState->pNext;
FreeSPDMemory(pTemp);
}
}
gpMMFilterState = pLeftMMFilterState;
return (dwError);
}
VOID
PAFreeMMFilterStateList(
PMMFILTERSTATE pMMFilterState
)
{
PMMFILTERSTATE pTemp = NULL;
while (pMMFilterState) {
pTemp = pMMFilterState;
pMMFilterState = pMMFilterState->pNext;
FreeSPDMemory(pTemp);
}
}
DWORD
PADeleteMMFilters(
PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
PIPSEC_NFA_DATA * ppIpsecNFAData,
DWORD dwNumNFACount
)
{
DWORD dwError = 0;
DWORD i = 0;
for (i = 0; i < dwNumNFACount; i++) {
dwError = PADeleteMMFilterSpecs(
pIpsecISAKMPData,
*(ppIpsecNFAData + i)
);
}
return (dwError);
}
DWORD
PADeleteMMFilterSpecs(
PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
PIPSEC_NFA_DATA pIpsecNFAData
)
{
DWORD dwError = 0;
PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
PIPSEC_FILTER_DATA pIpsecFilterData = NULL;
DWORD dwNumFilterSpecs = 0;
PIPSEC_FILTER_SPEC * ppFilterSpecs = NULL;
DWORD i = 0;
PIPSEC_FILTER_SPEC pFilterSpec = NULL;
pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
if (!memcmp(
&(pIpsecNegPolData->NegPolType),
&(GUID_NEGOTIATION_TYPE_DEFAULT),
sizeof(GUID))) {
dwError = ERROR_SUCCESS;
return (dwError);
}
if (IsClearOnly(pIpsecNegPolData->NegPolAction) ||
IsBlocking(pIpsecNegPolData->NegPolAction)) {
dwError = ERROR_SUCCESS;
return (dwError);
}
pIpsecFilterData = pIpsecNFAData->pIpsecFilterData;
if (!pIpsecFilterData) {
dwError = ERROR_SUCCESS;
return (dwError);
}
dwNumFilterSpecs = pIpsecFilterData->dwNumFilterSpecs;
ppFilterSpecs = pIpsecFilterData->ppFilterSpecs;
for (i = 0; i < dwNumFilterSpecs; i++) {
pFilterSpec = *(ppFilterSpecs + i);
dwError = PADeleteMMFilter(
pFilterSpec->FilterSpecGUID
);
}
return (dwError);
}
DWORD
PADeleteMMFilter(
GUID gFilterID
)
{
DWORD dwError = 0;
PMMFILTERSTATE pMMFilterState = NULL;
pMMFilterState = FindMMFilterState(
gFilterID
);
if (!pMMFilterState) {
dwError = ERROR_SUCCESS;
return (dwError);
}
if (pMMFilterState->hMMFilter) {
dwError = DeleteMMFilter(
pMMFilterState->hMMFilter
);
BAIL_ON_WIN32_ERROR(dwError);
}
PADeleteMMFilterState(pMMFilterState);
error:
return (dwError);
}
VOID
PADeleteMMFilterState(
PMMFILTERSTATE pMMFilterState
)
{
PMMFILTERSTATE * ppTemp = NULL;
ppTemp = &gpMMFilterState;
while (*ppTemp) {
if (*ppTemp == pMMFilterState) {
break;
}
ppTemp = &((*ppTemp)->pNext);
}
if (*ppTemp) {
*ppTemp = pMMFilterState->pNext;
}
FreeSPDMemory(pMMFilterState);
return;
}
PMMFILTERSTATE
FindMMFilterState(
GUID gFilterID
)
{
PMMFILTERSTATE pMMFilterState = NULL;
pMMFilterState = gpMMFilterState;
while (pMMFilterState) {
if (!memcmp(&(pMMFilterState->gFilterID), &gFilterID, sizeof(GUID))) {
return (pMMFilterState);
}
pMMFilterState = pMMFilterState->pNext;
}
return (NULL);
}