windows-nt/Source/XPSP1/NT/net/ipsec/polstore/validate.c
2020-09-26 16:20:57 +08:00

767 lines
17 KiB
C

#include "precomp.h"
extern LPWSTR PolicyDNAttributes[];
DWORD
ValidateISAKMPData(
PIPSEC_ISAKMP_DATA pIpsecISAKMPData
)
{
DWORD dwError = 0;
if (!pIpsecISAKMPData) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
if (!(pIpsecISAKMPData->pSecurityMethods) ||
!(pIpsecISAKMPData->dwNumISAKMPSecurityMethods)) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
error:
return (dwError);
}
DWORD
ValidateNegPolData(
PIPSEC_NEGPOL_DATA pIpsecNegPolData
)
{
DWORD dwError = 0;
if (!pIpsecNegPolData) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
if (!IsClearOnly(pIpsecNegPolData->NegPolAction) &&
!IsBlocking(pIpsecNegPolData->NegPolAction)) {
if (!(pIpsecNegPolData->pIpsecSecurityMethods) ||
!(pIpsecNegPolData->dwSecurityMethodCount)) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
}
error:
return (dwError);
}
BOOL
IsClearOnly(
GUID gNegPolAction
)
{
if (!memcmp(
&gNegPolAction,
&(GUID_NEGOTIATION_ACTION_NO_IPSEC),
sizeof(GUID))) {
return (TRUE);
}
else {
return (FALSE);
}
}
BOOL
IsBlocking(
GUID gNegPolAction
)
{
if (!memcmp(
&gNegPolAction,
&(GUID_NEGOTIATION_ACTION_BLOCK),
sizeof(GUID))) {
return (TRUE);
}
else {
return (FALSE);
}
}
DWORD
ValidateISAKMPDataDeletion(
HANDLE hPolicyStore,
GUID ISAKMPIdentifier
)
{
DWORD dwError = 0;
PIPSEC_POLICY_STORE pPolicyStore = NULL;
LPWSTR pszIpsecISAKMPReference = NULL;
DWORD dwRootPathLen = 0;
LPWSTR pszRelativeName = NULL;
LPWSTR * ppszIpsecPolicyReferences = NULL;
DWORD dwNumReferences = 0;
pPolicyStore = (PIPSEC_POLICY_STORE) hPolicyStore;
switch (pPolicyStore->dwProvider) {
case IPSEC_REGISTRY_PROVIDER:
dwError = ConvertGuidToISAKMPString(
ISAKMPIdentifier,
pPolicyStore->pszIpsecRootContainer,
&pszIpsecISAKMPReference
);
BAIL_ON_WIN32_ERROR(dwError);
dwRootPathLen = wcslen(pPolicyStore->pszIpsecRootContainer);
pszRelativeName = pszIpsecISAKMPReference + dwRootPathLen + 1;
dwError = RegGetPolicyReferencesForISAKMP(
pPolicyStore->hRegistryKey,
pPolicyStore->pszIpsecRootContainer,
pszRelativeName,
&ppszIpsecPolicyReferences,
&dwNumReferences
);
break;
case IPSEC_DIRECTORY_PROVIDER:
dwError = DirGetPolicyReferencesForISAKMP(
pPolicyStore->hLdapBindHandle,
pPolicyStore->pszIpsecRootContainer,
ISAKMPIdentifier,
&ppszIpsecPolicyReferences,
&dwNumReferences
);
break;
default:
dwError = ERROR_INVALID_PARAMETER;
return (dwError);
break;
}
if (!dwNumReferences) {
dwError = ERROR_SUCCESS;
}
else {
dwError = ERROR_INVALID_DATA;
}
error:
if (pszIpsecISAKMPReference) {
FreePolStr(pszIpsecISAKMPReference);
}
if (ppszIpsecPolicyReferences) {
FreeNFAReferences(
ppszIpsecPolicyReferences,
dwNumReferences
);
}
return (dwError);
}
DWORD
ValidateNegPolDataDeletion(
HANDLE hPolicyStore,
GUID NegPolIdentifier
)
{
DWORD dwError = 0;
PIPSEC_POLICY_STORE pPolicyStore = NULL;
LPWSTR pszIpsecNegPolReference = NULL;
DWORD dwRootPathLen = 0;
LPWSTR pszRelativeName = NULL;
LPWSTR * ppszIpsecNFAReferences = NULL;
DWORD dwNumReferences = 0;
pPolicyStore = (PIPSEC_POLICY_STORE) hPolicyStore;
switch (pPolicyStore->dwProvider) {
case IPSEC_REGISTRY_PROVIDER:
dwError = ConvertGuidToNegPolString(
NegPolIdentifier,
pPolicyStore->pszIpsecRootContainer,
&pszIpsecNegPolReference
);
BAIL_ON_WIN32_ERROR(dwError);
dwRootPathLen = wcslen(pPolicyStore->pszIpsecRootContainer);
pszRelativeName = pszIpsecNegPolReference + dwRootPathLen + 1;
dwError = RegGetNFAReferencesForNegPol(
pPolicyStore->hRegistryKey,
pPolicyStore->pszIpsecRootContainer,
pszRelativeName,
&ppszIpsecNFAReferences,
&dwNumReferences
);
break;
case IPSEC_DIRECTORY_PROVIDER:
dwError = DirGetNFAReferencesForNegPol(
pPolicyStore->hLdapBindHandle,
pPolicyStore->pszIpsecRootContainer,
NegPolIdentifier,
&ppszIpsecNFAReferences,
&dwNumReferences
);
break;
default:
dwError = ERROR_INVALID_PARAMETER;
return (dwError);
break;
}
if (!dwNumReferences) {
dwError = ERROR_SUCCESS;
}
else {
dwError = ERROR_INVALID_DATA;
}
error:
if (pszIpsecNegPolReference) {
FreePolStr(pszIpsecNegPolReference);
}
if (ppszIpsecNFAReferences) {
FreeNFAReferences(
ppszIpsecNFAReferences,
dwNumReferences
);
}
return (dwError);
}
DWORD
ValidateFilterDataDeletion(
HANDLE hPolicyStore,
GUID FilterIdentifier
)
{
DWORD dwError = 0;
PIPSEC_POLICY_STORE pPolicyStore = NULL;
LPWSTR pszIpsecFilterReference = NULL;
DWORD dwRootPathLen = 0;
LPWSTR pszRelativeName = NULL;
LPWSTR * ppszIpsecNFAReferences = NULL;
DWORD dwNumReferences = 0;
pPolicyStore = (PIPSEC_POLICY_STORE) hPolicyStore;
switch (pPolicyStore->dwProvider) {
case IPSEC_REGISTRY_PROVIDER:
dwError = ConvertGuidToFilterString(
FilterIdentifier,
pPolicyStore->pszIpsecRootContainer,
&pszIpsecFilterReference
);
BAIL_ON_WIN32_ERROR(dwError);
dwRootPathLen = wcslen(pPolicyStore->pszIpsecRootContainer);
pszRelativeName = pszIpsecFilterReference + dwRootPathLen + 1;
dwError = RegGetNFAReferencesForFilter(
pPolicyStore->hRegistryKey,
pPolicyStore->pszIpsecRootContainer,
pszRelativeName,
&ppszIpsecNFAReferences,
&dwNumReferences
);
break;
case IPSEC_DIRECTORY_PROVIDER:
dwError = DirGetNFAReferencesForFilter(
pPolicyStore->hLdapBindHandle,
pPolicyStore->pszIpsecRootContainer,
FilterIdentifier,
&ppszIpsecNFAReferences,
&dwNumReferences
);
break;
default:
dwError = ERROR_INVALID_PARAMETER;
return (dwError);
break;
}
if (!dwNumReferences) {
dwError = ERROR_SUCCESS;
}
else {
dwError = ERROR_INVALID_DATA;
}
error:
if (pszIpsecFilterReference) {
FreePolStr(pszIpsecFilterReference);
}
if (ppszIpsecNFAReferences) {
FreeNFAReferences(
ppszIpsecNFAReferences,
dwNumReferences
);
}
return (dwError);
}
DWORD
ValidatePolicyDataDeletion(
HANDLE hPolicyStore,
PIPSEC_POLICY_DATA pIpsecPolicyData
)
{
DWORD dwError = 0;
PIPSEC_POLICY_STORE pPolicyStore = NULL;
LPWSTR pszIpsecPolicyReference = NULL;
DWORD dwRootPathLen = 0;
LPWSTR pszRelativeName = NULL;
LPWSTR * ppszIpsecNFAReferences = NULL;
DWORD dwNumReferences = 0;
pPolicyStore = (PIPSEC_POLICY_STORE) hPolicyStore;
switch (pPolicyStore->dwProvider) {
case IPSEC_REGISTRY_PROVIDER:
dwError = ConvertGuidToPolicyString(
pIpsecPolicyData->PolicyIdentifier,
pPolicyStore->pszIpsecRootContainer,
&pszIpsecPolicyReference
);
BAIL_ON_WIN32_ERROR(dwError);
dwRootPathLen = wcslen(pPolicyStore->pszIpsecRootContainer);
pszRelativeName = pszIpsecPolicyReference + dwRootPathLen + 1;
dwError = RegGetNFAReferencesForPolicy(
pPolicyStore->hRegistryKey,
pPolicyStore->pszIpsecRootContainer,
pszRelativeName,
&ppszIpsecNFAReferences,
&dwNumReferences
);
break;
case IPSEC_DIRECTORY_PROVIDER:
dwError = GenerateSpecificPolicyQuery(
pIpsecPolicyData->PolicyIdentifier,
&pszIpsecPolicyReference
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = DirGetNFADNsForPolicy(
pPolicyStore->hLdapBindHandle,
pPolicyStore->pszIpsecRootContainer,
pszIpsecPolicyReference,
&ppszIpsecNFAReferences,
&dwNumReferences
);
break;
default:
dwError = ERROR_INVALID_PARAMETER;
return (dwError);
break;
}
if (!dwNumReferences) {
dwError = ERROR_SUCCESS;
}
else {
dwError = ERROR_INVALID_DATA;
}
error:
if (pszIpsecPolicyReference) {
FreePolStr(pszIpsecPolicyReference);
}
if (ppszIpsecNFAReferences) {
FreeNFAReferences(
ppszIpsecNFAReferences,
dwNumReferences
);
}
return (dwError);
}
DWORD
ValidatePolicyData(
HANDLE hPolicyStore,
PIPSEC_POLICY_DATA pIpsecPolicyData
)
{
DWORD dwError = 0;
PIPSEC_ISAKMP_DATA pIpsecISAKMPData = NULL;
dwError = IPSecGetISAKMPData(
hPolicyStore,
pIpsecPolicyData->ISAKMPIdentifier,
&pIpsecISAKMPData
);
BAIL_ON_WIN32_ERROR(dwError);
error:
if (pIpsecISAKMPData) {
FreeIpsecISAKMPData(
pIpsecISAKMPData
);
}
return (dwError);
}
DWORD
ValidateNFAData(
HANDLE hPolicyStore,
GUID PolicyIdentifier,
PIPSEC_NFA_DATA pIpsecNFAData
)
{
DWORD dwError = 0;
PIPSEC_FILTER_DATA pIpsecFilterData = NULL;
PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
GUID gZeroGUID;
memset(&gZeroGUID, 0, sizeof(GUID));
if (memcmp(
&gZeroGUID,
&pIpsecNFAData->FilterIdentifier,
sizeof(GUID))) {
dwError = IPSecGetFilterData(
hPolicyStore,
pIpsecNFAData->FilterIdentifier,
&pIpsecFilterData
);
BAIL_ON_WIN32_ERROR(dwError);
}
dwError = IPSecGetNegPolData(
hPolicyStore,
pIpsecNFAData->NegPolIdentifier,
&pIpsecNegPolData
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = VerifyPolicyDataExistence(
hPolicyStore,
PolicyIdentifier
);
BAIL_ON_WIN32_ERROR(dwError);
error:
if (pIpsecFilterData) {
FreeIpsecFilterData(
pIpsecFilterData
);
}
if (pIpsecNegPolData) {
FreeIpsecNegPolData(
pIpsecNegPolData
);
}
return (dwError);
}
DWORD
VerifyPolicyDataExistence(
HANDLE hPolicyStore,
GUID PolicyIdentifier
)
{
DWORD dwError = 0;
PIPSEC_POLICY_STORE pPolicyStore = NULL;
pPolicyStore = (PIPSEC_POLICY_STORE) hPolicyStore;
switch (pPolicyStore->dwProvider) {
case IPSEC_REGISTRY_PROVIDER:
dwError = RegVerifyPolicyDataExistence(
pPolicyStore->hRegistryKey,
pPolicyStore->pszIpsecRootContainer,
PolicyIdentifier
);
break;
case IPSEC_DIRECTORY_PROVIDER:
dwError = DirVerifyPolicyDataExistence(
pPolicyStore->hLdapBindHandle,
pPolicyStore->pszIpsecRootContainer,
PolicyIdentifier
);
break;
default:
dwError = ERROR_INVALID_PARAMETER;
break;
}
return (dwError);
}
DWORD
RegGetNFAReferencesForPolicy(
HKEY hRegistryKey,
LPWSTR pszIpsecRootContainer,
LPWSTR pszIpsecRelPolicyName,
LPWSTR ** pppszIpsecNFANames,
PDWORD pdwNumNFANames
)
{
DWORD dwError = 0;
HKEY hRegKey = 0;
LPWSTR pszIpsecNFAReference = NULL;
DWORD dwSize = 0;
LPWSTR pszTemp = NULL;
DWORD dwCount = 0;
LPWSTR * ppszIpsecNFANames = NULL;
LPWSTR pszString = NULL;
DWORD i = 0;
dwError = RegOpenKeyExW(
hRegistryKey,
pszIpsecRelPolicyName,
0,
KEY_ALL_ACCESS,
&hRegKey
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = RegstoreQueryValue(
hRegKey,
L"ipsecNFAReference",
REG_MULTI_SZ,
(LPBYTE *)&pszIpsecNFAReference,
&dwSize
);
BAIL_ON_WIN32_ERROR(dwError);
pszTemp = pszIpsecNFAReference;
while (*pszTemp != L'\0') {
pszTemp += wcslen(pszTemp) + 1;
dwCount++;
}
if (!dwCount) {
dwError = ERROR_NO_DATA;
BAIL_ON_WIN32_ERROR(dwError);
}
ppszIpsecNFANames = (LPWSTR *)AllocPolMem(
sizeof(LPWSTR)*dwCount
);
if (!ppszIpsecNFANames) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
pszTemp = pszIpsecNFAReference;
for (i = 0; i < dwCount; i++) {
pszString = AllocPolStr(pszTemp);
if (!pszString) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
*(ppszIpsecNFANames + i) = pszString;
pszTemp += wcslen(pszTemp) + 1; //for the null terminator;
}
*pppszIpsecNFANames = ppszIpsecNFANames;
*pdwNumNFANames = dwCount;
dwError = ERROR_SUCCESS;
cleanup:
if (hRegKey) {
RegCloseKey(hRegKey);
}
if (pszIpsecNFAReference) {
FreePolStr(pszIpsecNFAReference);
}
return(dwError);
error:
if (ppszIpsecNFANames) {
FreeNFAReferences(
ppszIpsecNFANames,
dwCount
);
}
*pppszIpsecNFANames = NULL;
*pdwNumNFANames = 0;
goto cleanup;
}
DWORD
RegVerifyPolicyDataExistence(
HKEY hRegistryKey,
LPWSTR pszIpsecRootContainer,
GUID PolicyGUID
)
{
DWORD dwError = 0;
WCHAR szIpsecPolicyName[MAX_PATH];
LPWSTR pszPolicyName = NULL;
HKEY hRegKey = NULL;
szIpsecPolicyName[0] = L'\0';
wcscpy(szIpsecPolicyName, L"ipsecPolicy");
dwError = UuidToString(&PolicyGUID, &pszPolicyName);
BAIL_ON_WIN32_ERROR(dwError);
wcscat(szIpsecPolicyName, L"{");
wcscat(szIpsecPolicyName, pszPolicyName);
wcscat(szIpsecPolicyName, L"}");
dwError = RegOpenKeyExW(
hRegistryKey,
szIpsecPolicyName,
0,
KEY_ALL_ACCESS,
&hRegKey
);
BAIL_ON_WIN32_ERROR(dwError);
error:
if (pszPolicyName) {
RpcStringFree(&pszPolicyName);
}
if (hRegKey) {
RegCloseKey(hRegKey);
}
return (dwError);
}
DWORD
DirVerifyPolicyDataExistence(
HLDAP hLdapBindHandle,
LPWSTR pszIpsecRootContainer,
GUID PolicyGUID
)
{
DWORD dwError = 0;
LPWSTR pszPolicyString = NULL;
LDAPMessage * res = NULL;
DWORD dwCount = 0;
dwError = GenerateSpecificPolicyQuery(
PolicyGUID,
&pszPolicyString
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = LdapSearchST(
hLdapBindHandle,
pszIpsecRootContainer,
LDAP_SCOPE_ONELEVEL,
pszPolicyString,
PolicyDNAttributes,
0,
NULL,
&res
);
BAIL_ON_WIN32_ERROR(dwError);
dwCount = LdapCountEntries(
hLdapBindHandle,
res
);
if (!dwCount) {
dwError = ERROR_DS_NO_ATTRIBUTE_OR_VALUE;
BAIL_ON_WIN32_ERROR(dwError);
}
error:
if (pszPolicyString) {
FreePolStr(pszPolicyString);
}
if (res) {
LdapMsgFree(res);
}
return (dwError);
}