611 lines
12 KiB
C
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);
|
|
}
|
|
|