|
|
#include "precomp.h"
DWORD PAAddQMPolicies( PIPSEC_NFA_DATA * ppIpsecNFAData, DWORD dwNumNFACount ) { DWORD dwError = 0; DWORD i = 0; PIPSEC_NFA_DATA pIpsecNFAData = NULL; PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL; PQMPOLICYSTATE pQMPolicyState = NULL; PIPSEC_QM_POLICY pSPDQMPolicy = NULL; LPWSTR pServerName = NULL; DWORD dwPersist = 0;
for (i = 0; i < dwNumNFACount; i++) {
pIpsecNFAData = *(ppIpsecNFAData + i); pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
pQMPolicyState = FindQMPolicyState( pIpsecNegPolData->NegPolIdentifier ); if (pQMPolicyState) { pQMPolicyState->cRef++; continue; }
dwError = PACreateQMPolicyState( *(ppIpsecNFAData + i), &pQMPolicyState ); if (dwError) { continue; }
if (IsClearOnly(pQMPolicyState->gNegPolAction) || IsBlocking(pQMPolicyState->gNegPolAction)) {
pQMPolicyState->bInSPD = FALSE; pQMPolicyState->dwErrorCode = 0;
pQMPolicyState->pNext = gpQMPolicyState; gpQMPolicyState = pQMPolicyState;
continue;
}
dwError = PACreateQMPolicy( *(ppIpsecNFAData + i), pQMPolicyState, &pSPDQMPolicy ); if (dwError) {
pQMPolicyState->bInSPD = FALSE; pQMPolicyState->dwErrorCode = dwError;
pQMPolicyState->pNext = gpQMPolicyState; gpQMPolicyState = pQMPolicyState;
continue;
}
dwError = AddQMPolicy( pServerName, dwPersist, pSPDQMPolicy ); if (dwError) { pQMPolicyState->bInSPD = FALSE; pQMPolicyState->dwErrorCode = dwError; } else { pQMPolicyState->bInSPD = TRUE; pQMPolicyState->dwErrorCode = ERROR_SUCCESS; }
pQMPolicyState->pNext = gpQMPolicyState; gpQMPolicyState = pQMPolicyState;
PAFreeQMPolicy(pSPDQMPolicy);
}
return (dwError); }
DWORD PACreateQMPolicyState( PIPSEC_NFA_DATA pIpsecNFAData, PQMPOLICYSTATE * ppQMPolicyState ) { DWORD dwError = 0; PQMPOLICYSTATE pQMPolicyState = NULL; PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL; WCHAR pszName[512];
dwError = AllocateSPDMemory( sizeof(QMPOLICYSTATE), &pQMPolicyState ); BAIL_ON_WIN32_ERROR(dwError);
pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
memcpy( &(pQMPolicyState->gPolicyID), &(pIpsecNegPolData->NegPolIdentifier), sizeof(GUID) );
if (pIpsecNegPolData->pszIpsecName && *(pIpsecNegPolData->pszIpsecName)) {
dwError = AllocateSPDString( pIpsecNegPolData->pszIpsecName, &(pQMPolicyState->pszPolicyName) ); BAIL_ON_WIN32_ERROR(dwError);
} else {
wsprintf(pszName, L"%d", ++gdwQMPolicyCounter);
dwError = AllocateSPDString( pszName, &(pQMPolicyState->pszPolicyName) ); BAIL_ON_WIN32_ERROR(dwError);
}
memcpy( &(pQMPolicyState->gNegPolType), &(pIpsecNegPolData->NegPolType), sizeof(GUID) );
memcpy( &(pQMPolicyState->gNegPolAction), &(pIpsecNegPolData->NegPolAction), sizeof(GUID) );
pQMPolicyState->bAllowsSoft = FALSE;
pQMPolicyState->cRef = 1;
pQMPolicyState->bInSPD = FALSE; pQMPolicyState->dwErrorCode = 0;
pQMPolicyState->pNext = NULL;
*ppQMPolicyState = pQMPolicyState;
return (dwError);
error:
if (pQMPolicyState) { PAFreeQMPolicyState(pQMPolicyState); }
*ppQMPolicyState = NULL;
return (dwError); }
VOID PAFreeQMPolicyState( PQMPOLICYSTATE pQMPolicyState ) { if (pQMPolicyState) { if (pQMPolicyState->pszPolicyName) { FreeSPDString(pQMPolicyState->pszPolicyName); } FreeSPDMemory(pQMPolicyState); } }
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); } }
BOOL IsInboundPassThru( GUID gNegPolAction ) { if (!memcmp( &gNegPolAction, &(GUID_NEGOTIATION_ACTION_INBOUND_PASSTHRU), sizeof(GUID))) { return (TRUE); } else { return (FALSE); } }
DWORD PACreateQMPolicy( PIPSEC_NFA_DATA pIpsecNFAData, PQMPOLICYSTATE pQMPolicyState, PIPSEC_QM_POLICY * ppSPDQMPolicy ) { DWORD dwError = 0; PIPSEC_QM_POLICY pSPDQMPolicy = NULL; PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
dwError = AllocateSPDMemory( sizeof(IPSEC_QM_POLICY), &pSPDQMPolicy ); BAIL_ON_WIN32_ERROR(dwError);
memcpy( &(pSPDQMPolicy->gPolicyID), &(pIpsecNegPolData->NegPolIdentifier), sizeof(GUID) );
dwError = AllocateSPDString( pQMPolicyState->pszPolicyName, &(pSPDQMPolicy->pszPolicyName) ); BAIL_ON_WIN32_ERROR(dwError); dwError = PACreateQMOffers( pIpsecNegPolData->dwSecurityMethodCount, pIpsecNegPolData->pIpsecSecurityMethods, pQMPolicyState, &(pSPDQMPolicy->dwOfferCount), &(pSPDQMPolicy->pOffers) ); BAIL_ON_WIN32_ERROR(dwError);
pSPDQMPolicy->dwFlags = 0;
if (!memcmp( &(pIpsecNegPolData->NegPolType), &(GUID_NEGOTIATION_TYPE_DEFAULT), sizeof(GUID))) { pSPDQMPolicy->dwFlags |= IPSEC_QM_POLICY_DEFAULT_POLICY; }
if (pIpsecNFAData->dwTunnelFlags) { pSPDQMPolicy->dwFlags |= IPSEC_QM_POLICY_TUNNEL_MODE; }
if (pQMPolicyState->bAllowsSoft) { pSPDQMPolicy->dwFlags |= IPSEC_QM_POLICY_ALLOW_SOFT; }
*ppSPDQMPolicy = pSPDQMPolicy;
return (dwError);
error:
if (pSPDQMPolicy) { PAFreeQMPolicy( pSPDQMPolicy ); }
*ppSPDQMPolicy = NULL;
return (dwError); }
DWORD PACreateQMOffers( DWORD dwSecurityMethodCount, PIPSEC_SECURITY_METHOD pIpsecSecurityMethods, PQMPOLICYSTATE pQMPolicyState, PDWORD pdwOfferCount, PIPSEC_QM_OFFER * ppOffers ) { DWORD dwError = 0; DWORD dwTempOfferCount = 0; PIPSEC_SECURITY_METHOD pTempMethod = NULL; BOOL bAllowsSoft = FALSE; DWORD i = 0; DWORD dwOfferCount = 0; PIPSEC_QM_OFFER pOffers = NULL; PIPSEC_QM_OFFER pTempOffer = NULL;
if (!dwSecurityMethodCount || !pIpsecSecurityMethods) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); }
if (dwSecurityMethodCount > IPSEC_MAX_QM_OFFERS) { dwTempOfferCount = IPSEC_MAX_QM_OFFERS; } else { dwTempOfferCount = dwSecurityMethodCount; }
pTempMethod = pIpsecSecurityMethods; for (i = 0; i < dwTempOfferCount; i++) {
if (pTempMethod->Count == 0) { bAllowsSoft = TRUE; } else { dwOfferCount++; }
pTempMethod++;
}
if (!dwOfferCount) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); }
dwError = AllocateSPDMemory( sizeof(IPSEC_QM_OFFER)*dwOfferCount, &(pOffers) ); BAIL_ON_WIN32_ERROR(dwError);
pTempOffer = pOffers; pTempMethod = pIpsecSecurityMethods; i = 0;
while (i < dwOfferCount) {
if (pTempMethod->Count) {
PACopyQMOffers( pTempMethod, pTempOffer );
i++; pTempOffer++;
}
pTempMethod++;
}
pQMPolicyState->bAllowsSoft = bAllowsSoft;
*pdwOfferCount = dwOfferCount; *ppOffers = pOffers; return (dwError);
error:
if (pOffers) { PAFreeQMOffers( i, pOffers ); }
*pdwOfferCount = 0; *ppOffers = NULL; return (dwError); }
VOID PACopyQMOffers( PIPSEC_SECURITY_METHOD pMethod, PIPSEC_QM_OFFER pOffer ) { DWORD i = 0; DWORD j = 0; DWORD k = 0;
pOffer->Lifetime.uKeyExpirationKBytes = pMethod->Lifetime.KeyExpirationBytes; pOffer->Lifetime.uKeyExpirationTime = pMethod->Lifetime.KeyExpirationTime;
pOffer->dwFlags = pMethod->Flags;
pOffer->bPFSRequired = pMethod->PfsQMRequired;
if (pMethod->PfsQMRequired) { pOffer->dwPFSGroup = PFS_GROUP_MM; } else { pOffer->dwPFSGroup = PFS_GROUP_NONE; }
i = 0;
for (j = 0; (j < pMethod->Count) && (i < QM_MAX_ALGOS) ; j++) {
switch (pMethod->Algos[j].operation) {
case Auth:
switch (pMethod->Algos[j].algoIdentifier) {
case IPSEC_AH_MD5: pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_AH_MD5; break;
case IPSEC_AH_SHA: pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_AH_SHA1; break;
default: pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_AH_NONE; break;
}
pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_NONE; pOffer->Algos[i].Operation = AUTHENTICATION; pOffer->Algos[i].uAlgoKeyLen = pMethod->Algos[j].algoKeylen; pOffer->Algos[i].uAlgoRounds = pMethod->Algos[j].algoRounds; pOffer->Algos[i].MySpi = 0; pOffer->Algos[i].PeerSpi = 0;
i++; break;
case Encrypt:
switch (pMethod->Algos[j].algoIdentifier) {
case IPSEC_ESP_DES: pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_DES; break;
case IPSEC_ESP_DES_40: pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_DES; break;
case IPSEC_ESP_3_DES: pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_3_DES; break;
default: pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_NONE; break;
}
switch (pMethod->Algos[j].secondaryAlgoIdentifier) {
case IPSEC_AH_MD5: pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_MD5; break;
case IPSEC_AH_SHA: pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_SHA1; break;
default: pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_NONE; break;
}
pOffer->Algos[i].Operation = ENCRYPTION; pOffer->Algos[i].uAlgoKeyLen = pMethod->Algos[j].algoKeylen; pOffer->Algos[i].uAlgoRounds = pMethod->Algos[j].algoRounds; pOffer->Algos[i].MySpi = 0; pOffer->Algos[i].PeerSpi = 0;
i++; break;
case None: case Compress: default: break;
}
}
for (k = i; k < QM_MAX_ALGOS; k++) { memset(&(pOffer->Algos[k]), 0, sizeof(IPSEC_QM_ALGO)); }
pOffer->dwNumAlgos = i; }
VOID PAFreeQMPolicy( PIPSEC_QM_POLICY pSPDQMPolicy ) { if (pSPDQMPolicy) {
if (pSPDQMPolicy->pszPolicyName) { FreeSPDString(pSPDQMPolicy->pszPolicyName); }
PAFreeQMOffers( pSPDQMPolicy->dwOfferCount, pSPDQMPolicy->pOffers );
FreeSPDMemory(pSPDQMPolicy);
} }
VOID PAFreeQMOffers( DWORD dwOfferCount, PIPSEC_QM_OFFER pOffers ) { if (pOffers) { FreeSPDMemory(pOffers); } }
DWORD PADeleteAllQMPolicies( ) { DWORD dwError = 0; PQMPOLICYSTATE pQMPolicyState = NULL; LPWSTR pServerName = NULL; PQMPOLICYSTATE pTemp = NULL; PQMPOLICYSTATE pLeftQMPolicyState = NULL;
pQMPolicyState = gpQMPolicyState;
while (pQMPolicyState) {
if (pQMPolicyState->bInSPD) {
dwError = DeleteQMPolicy( pServerName, pQMPolicyState->pszPolicyName ); if (!dwError) { pTemp = pQMPolicyState; pQMPolicyState = pQMPolicyState->pNext; PAFreeQMPolicyState(pTemp); } else { pQMPolicyState->dwErrorCode = dwError;
pTemp = pQMPolicyState; pQMPolicyState = pQMPolicyState->pNext;
pTemp->pNext = pLeftQMPolicyState; pLeftQMPolicyState = pTemp; }
} else {
pTemp = pQMPolicyState; pQMPolicyState = pQMPolicyState->pNext; PAFreeQMPolicyState(pTemp);
}
}
gpQMPolicyState = pLeftQMPolicyState;
return (dwError); }
VOID PAFreeQMPolicyStateList( PQMPOLICYSTATE pQMPolicyState ) { PQMPOLICYSTATE pTemp = NULL;
while (pQMPolicyState) {
pTemp = pQMPolicyState; pQMPolicyState = pQMPolicyState->pNext; PAFreeQMPolicyState(pTemp);
} }
PQMPOLICYSTATE FindQMPolicyState( GUID gPolicyID ) { PQMPOLICYSTATE pQMPolicyState = NULL;
pQMPolicyState = gpQMPolicyState;
while (pQMPolicyState) {
if (!memcmp(&(pQMPolicyState->gPolicyID), &gPolicyID, sizeof(GUID))) { return (pQMPolicyState); }
pQMPolicyState = pQMPolicyState->pNext;
}
return (NULL); }
DWORD PADeleteQMPolicies( PIPSEC_NFA_DATA * ppIpsecNFAData, DWORD dwNumNFACount ) { DWORD dwError = 0; DWORD i = 0; PIPSEC_NFA_DATA pIpsecNFAData = NULL; PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
for (i = 0; i < dwNumNFACount; i++) {
pIpsecNFAData = *(ppIpsecNFAData + i);
pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
dwError = PADeleteQMPolicy( pIpsecNegPolData->NegPolIdentifier );
}
return (dwError); }
DWORD PADeleteQMPolicy( GUID gPolicyID ) { DWORD dwError = 0; PQMPOLICYSTATE pQMPolicyState = NULL; LPWSTR pServerName = NULL;
pQMPolicyState = FindQMPolicyState( gPolicyID ); if (!pQMPolicyState) { dwError = ERROR_SUCCESS; return (dwError); }
pQMPolicyState->cRef--; if (pQMPolicyState->cRef > 0) { dwError = ERROR_SUCCESS; return (dwError); }
if (pQMPolicyState->bInSPD) {
dwError = DeleteQMPolicy( pServerName, pQMPolicyState->pszPolicyName ); if (dwError) { pQMPolicyState->cRef++; pQMPolicyState->dwErrorCode = dwError; } BAIL_ON_WIN32_ERROR(dwError);
}
PADeleteQMPolicyState(pQMPolicyState);
error:
return (dwError); }
VOID PADeleteQMPolicyState( PQMPOLICYSTATE pQMPolicyState ) { PQMPOLICYSTATE * ppTemp = NULL;
ppTemp = &gpQMPolicyState;
while (*ppTemp) {
if (*ppTemp == pQMPolicyState) { break; } ppTemp = &((*ppTemp)->pNext);
}
if (*ppTemp) { *ppTemp = pQMPolicyState->pNext; }
PAFreeQMPolicyState(pQMPolicyState);
return; }
DWORD PADeleteInUseQMPolicies( ) { DWORD dwError = 0; PQMPOLICYSTATE pQMPolicyState = NULL; LPWSTR pServerName = NULL; PQMPOLICYSTATE pTemp = NULL; PQMPOLICYSTATE pLeftQMPolicyState = NULL;
pQMPolicyState = gpQMPolicyState;
while (pQMPolicyState) {
if (pQMPolicyState->bInSPD && (pQMPolicyState->dwErrorCode == ERROR_IPSEC_QM_POLICY_IN_USE)) {
dwError = DeleteQMPolicy( pServerName, pQMPolicyState->pszPolicyName ); if (!dwError) { pTemp = pQMPolicyState; pQMPolicyState = pQMPolicyState->pNext; PAFreeQMPolicyState(pTemp); } else { pTemp = pQMPolicyState; pQMPolicyState = pQMPolicyState->pNext;
pTemp->pNext = pLeftQMPolicyState; pLeftQMPolicyState = pTemp; }
} else {
pTemp = pQMPolicyState; pQMPolicyState = pQMPolicyState->pNext;
pTemp->pNext = pLeftQMPolicyState; pLeftQMPolicyState = pTemp;
}
}
gpQMPolicyState = pLeftQMPolicyState;
return (dwError); }
|