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

611 lines
12 KiB
C

#include "precomp.h"
DWORD
PAAddMMPolicies(
PIPSEC_ISAKMP_DATA * ppIpsecISAKMPData,
DWORD dwNumPolicies
)
{
DWORD dwError = 0;
DWORD i = 0;
PMMPOLICYSTATE pMMPolicyState = NULL;
PIPSEC_MM_POLICY pSPDMMPolicy = NULL;
LPWSTR pServerName = NULL;
DWORD dwPersist = 0;
for (i = 0; i < dwNumPolicies; i++) {
dwError = PACreateMMPolicyState(
*(ppIpsecISAKMPData + i),
&pMMPolicyState
);
if (dwError) {
continue;
}
dwError = PACreateMMPolicy(
*(ppIpsecISAKMPData + i),
pMMPolicyState,
&pSPDMMPolicy
);
if (dwError) {
pMMPolicyState->bInSPD = FALSE;
pMMPolicyState->dwErrorCode = dwError;
pMMPolicyState->pNext = gpMMPolicyState;
gpMMPolicyState = pMMPolicyState;
continue;
}
dwError = AddMMPolicy(
pServerName,
dwPersist,
pSPDMMPolicy
);
if (dwError) {
pMMPolicyState->bInSPD = FALSE;
pMMPolicyState->dwErrorCode = dwError;
}
else {
pMMPolicyState->bInSPD = TRUE;
pMMPolicyState->dwErrorCode = ERROR_SUCCESS;
}
pMMPolicyState->pNext = gpMMPolicyState;
gpMMPolicyState = pMMPolicyState;
PAFreeMMPolicy(pSPDMMPolicy);
}
return (dwError);
}
DWORD
PACreateMMPolicyState(
PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
PMMPOLICYSTATE * ppMMPolicyState
)
{
DWORD dwError = 0;
PMMPOLICYSTATE pMMPolicyState = NULL;
WCHAR pszName[512];
dwError = AllocateSPDMemory(
sizeof(MMPOLICYSTATE),
&pMMPolicyState
);
BAIL_ON_WIN32_ERROR(dwError);
memcpy(
&(pMMPolicyState->gPolicyID),
&(pIpsecISAKMPData->ISAKMPIdentifier),
sizeof(GUID)
);
wsprintf(pszName, L"%d", ++gdwMMPolicyCounter);
dwError = AllocateSPDString(
pszName,
&(pMMPolicyState->pszPolicyName)
);
BAIL_ON_WIN32_ERROR(dwError);
pMMPolicyState->bInSPD = FALSE;
pMMPolicyState->dwErrorCode = 0;
pMMPolicyState->pNext = NULL;
*ppMMPolicyState = pMMPolicyState;
return (dwError);
error:
if (pMMPolicyState) {
PAFreeMMPolicyState(pMMPolicyState);
}
*ppMMPolicyState = NULL;
return (dwError);
}
VOID
PAFreeMMPolicyState(
PMMPOLICYSTATE pMMPolicyState
)
{
if (pMMPolicyState) {
if (pMMPolicyState->pszPolicyName) {
FreeSPDString(pMMPolicyState->pszPolicyName);
}
FreeSPDMemory(pMMPolicyState);
}
}
DWORD
PACreateMMPolicy(
PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
PMMPOLICYSTATE pMMPolicyState,
PIPSEC_MM_POLICY * ppSPDMMPolicy
)
{
DWORD dwError = 0;
PIPSEC_MM_POLICY pSPDMMPolicy = NULL;
dwError = AllocateSPDMemory(
sizeof(IPSEC_MM_POLICY),
&pSPDMMPolicy
);
BAIL_ON_WIN32_ERROR(dwError);
memcpy(
&(pSPDMMPolicy->gPolicyID),
&(pIpsecISAKMPData->ISAKMPIdentifier),
sizeof(GUID)
);
dwError = AllocateSPDString(
pMMPolicyState->pszPolicyName,
&(pSPDMMPolicy->pszPolicyName)
);
BAIL_ON_WIN32_ERROR(dwError);
pSPDMMPolicy->dwFlags = 0;
pSPDMMPolicy->dwFlags |= IPSEC_MM_POLICY_DEFAULT_POLICY;
dwError = PACreateMMOffers(
pIpsecISAKMPData->dwNumISAKMPSecurityMethods,
pIpsecISAKMPData->pSecurityMethods,
&(pSPDMMPolicy->dwOfferCount),
&(pSPDMMPolicy->pOffers)
);
BAIL_ON_WIN32_ERROR(dwError);
pSPDMMPolicy->uSoftSAExpirationTime =
(pSPDMMPolicy->pOffers)->Lifetime.uKeyExpirationTime;
*ppSPDMMPolicy = pSPDMMPolicy;
return (dwError);
error:
if (pSPDMMPolicy) {
PAFreeMMPolicy(
pSPDMMPolicy
);
}
*ppSPDMMPolicy = NULL;
return (dwError);
}
DWORD
PACreateMMOffers(
DWORD dwNumISAKMPSecurityMethods,
PCRYPTO_BUNDLE pSecurityMethods,
PDWORD pdwOfferCount,
PIPSEC_MM_OFFER * ppOffers
)
{
DWORD dwError = 0;
DWORD dwOfferCount = 0;
PIPSEC_MM_OFFER pOffers = NULL;
PIPSEC_MM_OFFER pTempOffer = NULL;
PCRYPTO_BUNDLE pTempBundle = NULL;
DWORD i = 0;
if (!dwNumISAKMPSecurityMethods || !pSecurityMethods) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
if (dwNumISAKMPSecurityMethods > IPSEC_MAX_MM_OFFERS) {
dwOfferCount = IPSEC_MAX_MM_OFFERS;
}
else {
dwOfferCount = dwNumISAKMPSecurityMethods;
}
dwError = AllocateSPDMemory(
sizeof(IPSEC_MM_OFFER)*dwOfferCount,
&(pOffers)
);
BAIL_ON_WIN32_ERROR(dwError);
pTempOffer = pOffers;
pTempBundle = pSecurityMethods;
for (i = 0; i < dwOfferCount; i++) {
PACopyMMOffer(
pTempBundle,
pTempOffer
);
pTempOffer++;
pTempBundle++;
}
*pdwOfferCount = dwOfferCount;
*ppOffers = pOffers;
return (dwError);
error:
if (pOffers) {
PAFreeMMOffers(
i,
pOffers
);
}
*pdwOfferCount = 0;
*ppOffers = NULL;
return (dwError);
}
VOID
PACopyMMOffer(
PCRYPTO_BUNDLE pBundle,
PIPSEC_MM_OFFER pOffer
)
{
pOffer->Lifetime.uKeyExpirationKBytes = pBundle->Lifetime.KBytes;
pOffer->Lifetime.uKeyExpirationTime = pBundle->Lifetime.Seconds;
pOffer->dwFlags = 0;
pOffer->dwQuickModeLimit = pBundle->QuickModeLimit;
pOffer->dwDHGroup = pBundle->OakleyGroup;
if ((pOffer->dwDHGroup != DH_GROUP_1) &&
(pOffer->dwDHGroup != DH_GROUP_2)) {
pOffer->dwDHGroup = DH_GROUP_1;
}
switch (pBundle->EncryptionAlgorithm.AlgorithmIdentifier) {
case IPSEC_ESP_DES:
pOffer->EncryptionAlgorithm.uAlgoIdentifier = IPSEC_DOI_ESP_DES;
break;
case IPSEC_ESP_DES_40:
pOffer->EncryptionAlgorithm.uAlgoIdentifier = IPSEC_DOI_ESP_DES;
break;
case IPSEC_ESP_3_DES:
pOffer->EncryptionAlgorithm.uAlgoIdentifier = IPSEC_DOI_ESP_3_DES;
break;
default:
pOffer->EncryptionAlgorithm.uAlgoIdentifier= IPSEC_DOI_ESP_NONE;
break;
}
pOffer->EncryptionAlgorithm.uAlgoKeyLen =
pBundle->EncryptionAlgorithm.KeySize;
pOffer->EncryptionAlgorithm.uAlgoRounds =
pBundle->EncryptionAlgorithm.Rounds;
switch(pBundle->HashAlgorithm.AlgorithmIdentifier) {
case IPSEC_AH_MD5:
pOffer->HashingAlgorithm.uAlgoIdentifier = IPSEC_DOI_AH_MD5;
break;
case IPSEC_AH_SHA:
pOffer->HashingAlgorithm.uAlgoIdentifier = IPSEC_DOI_AH_SHA1;
break;
default:
pOffer->HashingAlgorithm.uAlgoIdentifier = IPSEC_DOI_AH_NONE;
break;
}
pOffer->HashingAlgorithm.uAlgoKeyLen =
pBundle->HashAlgorithm.KeySize;
pOffer->HashingAlgorithm.uAlgoRounds =
pBundle->HashAlgorithm.Rounds;
}
VOID
PAFreeMMPolicy(
PIPSEC_MM_POLICY pSPDMMPolicy
)
{
if (pSPDMMPolicy) {
if (pSPDMMPolicy->pszPolicyName) {
FreeSPDString(pSPDMMPolicy->pszPolicyName);
}
PAFreeMMOffers(
pSPDMMPolicy->dwOfferCount,
pSPDMMPolicy->pOffers
);
FreeSPDMemory(pSPDMMPolicy);
}
}
VOID
PAFreeMMOffers(
DWORD dwOfferCount,
PIPSEC_MM_OFFER pOffers
)
{
if (pOffers) {
FreeSPDMemory(pOffers);
}
}
DWORD
PADeleteAllMMPolicies(
)
{
DWORD dwError = 0;
PMMPOLICYSTATE pMMPolicyState = NULL;
LPWSTR pServerName = NULL;
PMMPOLICYSTATE pTemp = NULL;
PMMPOLICYSTATE pLeftMMPolicyState = NULL;
pMMPolicyState = gpMMPolicyState;
while (pMMPolicyState) {
if (pMMPolicyState->bInSPD) {
dwError = DeleteMMPolicy(
pServerName,
pMMPolicyState->pszPolicyName
);
if (!dwError) {
pTemp = pMMPolicyState;
pMMPolicyState = pMMPolicyState->pNext;
PAFreeMMPolicyState(pTemp);
}
else {
pMMPolicyState->dwErrorCode = dwError;
pTemp = pMMPolicyState;
pMMPolicyState = pMMPolicyState->pNext;
pTemp->pNext = pLeftMMPolicyState;
pLeftMMPolicyState = pTemp;
}
}
else {
pTemp = pMMPolicyState;
pMMPolicyState = pMMPolicyState->pNext;
PAFreeMMPolicyState(pTemp);
}
}
gpMMPolicyState = pLeftMMPolicyState;
return (dwError);
}
VOID
PAFreeMMPolicyStateList(
PMMPOLICYSTATE pMMPolicyState
)
{
PMMPOLICYSTATE pTemp = NULL;
while (pMMPolicyState) {
pTemp = pMMPolicyState;
pMMPolicyState = pMMPolicyState->pNext;
PAFreeMMPolicyState(pTemp);
}
}
PMMPOLICYSTATE
FindMMPolicyState(
GUID gPolicyID
)
{
PMMPOLICYSTATE pMMPolicyState = NULL;
pMMPolicyState = gpMMPolicyState;
while (pMMPolicyState) {
if (!memcmp(&(pMMPolicyState->gPolicyID), &gPolicyID, sizeof(GUID))) {
return (pMMPolicyState);
}
pMMPolicyState = pMMPolicyState->pNext;
}
return (NULL);
}
DWORD
PADeleteMMPolicies(
PIPSEC_ISAKMP_DATA * ppIpsecISAKMPData,
DWORD dwNumPolicies
)
{
DWORD dwError = 0;
DWORD i = 0;
PIPSEC_ISAKMP_DATA pIpsecISAKMPData = NULL;
for (i = 0; i < dwNumPolicies; i++) {
pIpsecISAKMPData = *(ppIpsecISAKMPData + i);
dwError = PADeleteMMPolicy(
pIpsecISAKMPData->ISAKMPIdentifier
);
}
return (dwError);
}
DWORD
PADeleteMMPolicy(
GUID gPolicyID
)
{
DWORD dwError = 0;
PMMPOLICYSTATE pMMPolicyState = NULL;
LPWSTR pServerName = NULL;
pMMPolicyState = FindMMPolicyState(
gPolicyID
);
if (!pMMPolicyState) {
dwError = ERROR_SUCCESS;
return (dwError);
}
if (pMMPolicyState->bInSPD) {
dwError = DeleteMMPolicy(
pServerName,
pMMPolicyState->pszPolicyName
);
if (dwError) {
pMMPolicyState->dwErrorCode = dwError;
}
BAIL_ON_WIN32_ERROR(dwError);
}
PADeleteMMPolicyState(pMMPolicyState);
error:
return (dwError);
}
VOID
PADeleteMMPolicyState(
PMMPOLICYSTATE pMMPolicyState
)
{
PMMPOLICYSTATE * ppTemp = NULL;
ppTemp = &gpMMPolicyState;
while (*ppTemp) {
if (*ppTemp == pMMPolicyState) {
break;
}
ppTemp = &((*ppTemp)->pNext);
}
if (*ppTemp) {
*ppTemp = pMMPolicyState->pNext;
}
PAFreeMMPolicyState(pMMPolicyState);
return;
}
DWORD
PADeleteInUseMMPolicies(
)
{
DWORD dwError = 0;
PMMPOLICYSTATE pMMPolicyState = NULL;
LPWSTR pServerName = NULL;
PMMPOLICYSTATE pTemp = NULL;
PMMPOLICYSTATE pLeftMMPolicyState = NULL;
pMMPolicyState = gpMMPolicyState;
while (pMMPolicyState) {
if (pMMPolicyState->bInSPD &&
(pMMPolicyState->dwErrorCode == ERROR_IPSEC_MM_POLICY_IN_USE)) {
dwError = DeleteMMPolicy(
pServerName,
pMMPolicyState->pszPolicyName
);
if (!dwError) {
pTemp = pMMPolicyState;
pMMPolicyState = pMMPolicyState->pNext;
PAFreeMMPolicyState(pTemp);
}
else {
pTemp = pMMPolicyState;
pMMPolicyState = pMMPolicyState->pNext;
pTemp->pNext = pLeftMMPolicyState;
pLeftMMPolicyState = pTemp;
}
}
else {
pTemp = pMMPolicyState;
pMMPolicyState = pMMPolicyState->pNext;
pTemp->pNext = pLeftMMPolicyState;
pLeftMMPolicyState = pTemp;
}
}
gpMMPolicyState = pLeftMMPolicyState;
return (dwError);
}