|
|
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
mm-policy.c
Abstract:
Author:
Environment: User Mode
Revision History:
--*/
#include "precomp.h"
#ifdef TRACE_ON
#include "mm-policy.tmh"
#endif
DWORD AddMMPolicyInternal( LPWSTR pServerName, DWORD dwVersion, DWORD dwFlags, DWORD dwSource, PIPSEC_MM_POLICY pMMPolicy, LPVOID pvReserved ) /*++
Routine Description:
This function adds a main mode policy to the SPD.
Arguments:
pServerName - Server on which the main mode policy is to be added.
pMMPolicy - Main mode policy to be added.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/ { DWORD dwError = 0; PINIMMPOLICY pIniMMPolicy = NULL;
//
// Validate the main mode policy.
//
dwError = ValidateMMPolicy( pMMPolicy ); BAIL_ON_WIN32_ERROR(dwError);
ENTER_SPD_SECTION();
dwError = ValidateSecurity( SPD_OBJECT_SERVER, SERVER_ACCESS_ADMINISTER, NULL, NULL ); BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = FindMMPolicy( gpIniMMPolicy, pMMPolicy->pszPolicyName ); if (pIniMMPolicy) { dwError = ERROR_IPSEC_MM_POLICY_EXISTS; BAIL_ON_LOCK_ERROR(dwError); }
pIniMMPolicy = FindMMPolicyByGuid( gpIniMMPolicy, pMMPolicy->gPolicyID ); if (pIniMMPolicy) { dwError = ERROR_IPSEC_MM_POLICY_EXISTS; BAIL_ON_LOCK_ERROR(dwError); }
dwError = CreateIniMMPolicy( pMMPolicy, &pIniMMPolicy ); if (dwError != WARNING_IPSEC_MM_POLICY_PRUNED) { BAIL_ON_LOCK_ERROR(dwError); }
pIniMMPolicy->dwSource = dwSource;
pIniMMPolicy->pNext = gpIniMMPolicy; gpIniMMPolicy = pIniMMPolicy;
if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) { gpIniDefaultMMPolicy = pIniMMPolicy; TRACE( TRC_INFORMATION, (L"Set default MM policy to \"%ls\" (%!guid!)", pMMPolicy->pszPolicyName, &pMMPolicy->gPolicyID) ); } LEAVE_SPD_SECTION();
TRACE( TRC_INFORMATION, (L"Added MM policy \"%ls\"(%!guid!)", pMMPolicy->pszPolicyName, &pMMPolicy->gPolicyID) );
return (dwError);
lock:
LEAVE_SPD_SECTION();
error: #ifdef TRACE_ON
if (pMMPolicy) { TRACE( TRC_ERROR, (L"Failed to add MM policy \"%ls\"(%!guid!): %!winerr!", pMMPolicy->pszPolicyName, &pMMPolicy->gPolicyID, dwError) ); } else { TRACE( TRC_ERROR, (L"Failed to add MM policy. Policy details unavailable since pMMPolicy is null: %!winerr!", dwError) ); } #endif
return (dwError); }
DWORD AddMMPolicy( LPWSTR pServerName, DWORD dwVersion, DWORD dwFlags, PIPSEC_MM_POLICY pMMPolicy, LPVOID pvReserved ) { return AddMMPolicyInternal( pServerName, dwVersion, dwFlags, IPSEC_SOURCE_WINIPSEC, pMMPolicy, pvReserved); }
DWORD ValidateMMPolicy( PIPSEC_MM_POLICY pMMPolicy ) { DWORD dwError = 0;
if (!pMMPolicy) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); }
if (!(pMMPolicy->pszPolicyName) || !(*(pMMPolicy->pszPolicyName))) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); }
dwError = ValidateMMOffers( pMMPolicy->dwOfferCount, pMMPolicy->pOffers ); BAIL_ON_WIN32_ERROR(dwError);
error: #ifdef TRACE_ON
if (dwError) { TRACE(TRC_ERROR, ("Failed MM policy validation: %!winerr!", dwError)); } #endif
return (dwError); }
DWORD ValidateMMOffers( DWORD dwOfferCount, PIPSEC_MM_OFFER pOffers ) { DWORD dwError = 0;
if (!dwOfferCount || !pOffers || dwOfferCount > IPSEC_MAX_MM_OFFERS) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); }
error: #ifdef TRACE_ON
if (dwError) { TRACE(TRC_ERROR, ("Failed MM offers validation: %!winerr!", dwError)); } #endif
return (dwError); }
DWORD ValidateMMOffer( PIPSEC_MM_OFFER pOffer ) { DWORD dwError = 0; if ((pOffer->dwDHGroup != DH_GROUP_1) && (pOffer->dwDHGroup != DH_GROUP_2) && (pOffer->dwDHGroup != DH_GROUP_2048)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } if (pOffer->EncryptionAlgorithm.uAlgoIdentifier >= CONF_ALGO_MAX || pOffer->EncryptionAlgorithm.uAlgoIdentifier == CONF_ALGO_NONE) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } if (pOffer->HashingAlgorithm.uAlgoIdentifier >= AUTH_ALGO_MAX || pOffer->HashingAlgorithm.uAlgoIdentifier == AUTH_ALGO_NONE) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); }
error: #ifdef TRACE_ON
if (dwError) { TRACE(TRC_ERROR, ("Failed a MM offer validation: %!winerr!", dwError)); } #endif
return (dwError); }
DWORD CreateIniMMPolicy( PIPSEC_MM_POLICY pMMPolicy, PINIMMPOLICY * ppIniMMPolicy ) { DWORD dwError = 0; PINIMMPOLICY pIniMMPolicy = NULL;
dwError = AllocateSPDMemory( sizeof(INIMMPOLICY), &pIniMMPolicy ); BAIL_ON_WIN32_ERROR(dwError);
memcpy( &(pIniMMPolicy->gPolicyID), &(pMMPolicy->gPolicyID), sizeof(GUID) );
dwError = AllocateSPDString( pMMPolicy->pszPolicyName, &(pIniMMPolicy->pszPolicyName) ); BAIL_ON_WIN32_ERROR(dwError);
pIniMMPolicy->cRef = 0; pIniMMPolicy->dwSource = 0;
pIniMMPolicy->dwFlags = pMMPolicy->dwFlags; pIniMMPolicy->uSoftExpirationTime = pMMPolicy->uSoftExpirationTime; pIniMMPolicy->pNext = NULL;
dwError = CreateIniMMOffers( pMMPolicy->dwOfferCount, pMMPolicy->pOffers, &(pIniMMPolicy->dwOfferCount), &(pIniMMPolicy->pOffers) ); if (dwError != WARNING_IPSEC_MM_POLICY_PRUNED) { BAIL_ON_WIN32_ERROR(dwError); }
*ppIniMMPolicy = pIniMMPolicy; return (dwError);
error: TRACE(TRC_ERROR, ("Failed to create MM Policy link node: %!winerr!", dwError));
if (pIniMMPolicy) { FreeIniMMPolicy( pIniMMPolicy ); }
*ppIniMMPolicy = NULL; return (dwError); }
DWORD CreateIniMMOffers( DWORD dwInOfferCount, PIPSEC_MM_OFFER pInOffers, PDWORD pdwOfferCount, PIPSEC_MM_OFFER * ppOffers ) { DWORD dwError = 0; PIPSEC_MM_OFFER pOffers = NULL; PIPSEC_MM_OFFER pTemp = NULL; PIPSEC_MM_OFFER pInTempOffer = NULL; DWORD i = 0; DWORD dwOfferCount = 0; DWORD dwCurIndex = 0;
for (i = 0; i < dwInOfferCount; i++) { dwError = ValidateMMOffer(&pInOffers[i]); if (dwError == ERROR_SUCCESS) { dwOfferCount++; } }
if (dwOfferCount == 0) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); }
dwError = AllocateSPDMemory( sizeof(IPSEC_MM_OFFER) * dwOfferCount, &(pOffers) ); BAIL_ON_WIN32_ERROR(dwError);
for (i = 0; i < dwInOfferCount; i++) {
pTemp = &pOffers[dwCurIndex]; pInTempOffer = &pInOffers[i];
dwError = ValidateMMOffer(pInTempOffer); if (dwError) { continue; }
memcpy( &(pTemp->Lifetime), &(pInTempOffer->Lifetime), sizeof(KEY_LIFETIME) ); if (!(pTemp->Lifetime.uKeyExpirationTime)) { pTemp->Lifetime.uKeyExpirationTime = DEFAULT_MM_KEY_EXPIRATION_TIME; }
pTemp->dwFlags = pInTempOffer->dwFlags; pTemp->dwQuickModeLimit = pInTempOffer->dwQuickModeLimit; pTemp->dwDHGroup = pInTempOffer->dwDHGroup;
memcpy( &(pTemp->EncryptionAlgorithm), &(pInTempOffer->EncryptionAlgorithm), sizeof(IPSEC_MM_ALGO) ); memcpy( &(pTemp->HashingAlgorithm), &(pInTempOffer->HashingAlgorithm), sizeof(IPSEC_MM_ALGO) );
dwCurIndex++;
}
*pdwOfferCount = dwOfferCount; *ppOffers = pOffers;
if (dwOfferCount != dwInOfferCount) { TRACE(TRC_WARNING, ("Pruned MM offers node.")); return WARNING_IPSEC_MM_POLICY_PRUNED; } return (ERROR_SUCCESS);
error: TRACE(TRC_ERROR, ("Failed to create MM offers node: %!winerr!", dwError));
if (pOffers) { FreeIniMMOffers( i, pOffers ); }
*pdwOfferCount = 0; *ppOffers = NULL; return (dwError); }
VOID FreeIniMMPolicy( PINIMMPOLICY pIniMMPolicy ) { if (pIniMMPolicy) {
if (pIniMMPolicy->pszPolicyName) { FreeSPDString(pIniMMPolicy->pszPolicyName); }
FreeIniMMOffers( pIniMMPolicy->dwOfferCount, pIniMMPolicy->pOffers );
FreeSPDMemory(pIniMMPolicy);
} }
VOID FreeIniMMOffers( DWORD dwOfferCount, PIPSEC_MM_OFFER pOffers ) { if (pOffers) { FreeSPDMemory(pOffers); } }
PINIMMPOLICY FindMMPolicy( PINIMMPOLICY pIniMMPolicyList, LPWSTR pszPolicyName ) { DWORD dwError = 0; PINIMMPOLICY pTemp = NULL;
pTemp = pIniMMPolicyList;
while (pTemp) {
if (!_wcsicmp(pTemp->pszPolicyName, pszPolicyName)) { return (pTemp); } pTemp = pTemp->pNext;
}
return (NULL); }
DWORD DeleteMMPolicy( LPWSTR pServerName, DWORD dwVersion, LPWSTR pszPolicyName, LPVOID pvReserved ) /*++
Routine Description:
This function deletes a main mode policy from the SPD.
Arguments:
pServerName - Server on which the main mode policy is to be deleted.
pszPolicyName - Main mode policy to be deleted.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/ { DWORD dwError = 0; PINIMMPOLICY pIniMMPolicy = NULL; GUID gPolicyID;
if (!pszPolicyName || !*pszPolicyName) { return (ERROR_INVALID_PARAMETER); }
ENTER_SPD_SECTION();
dwError = ValidateSecurity( SPD_OBJECT_SERVER, SERVER_ACCESS_ADMINISTER, NULL, NULL ); BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = FindMMPolicy( gpIniMMPolicy, pszPolicyName ); if (!pIniMMPolicy) { dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND; BAIL_ON_LOCK_ERROR(dwError); }
if (pIniMMPolicy->cRef) { dwError = ERROR_IPSEC_MM_POLICY_IN_USE; memcpy(&gPolicyID, &pIniMMPolicy->gPolicyID, sizeof(GUID)); BAIL_ON_LOCK_ERROR(dwError); }
memcpy(&gPolicyID, &pIniMMPolicy->gPolicyID, sizeof(GUID));
dwError = DeleteIniMMPolicy( pIniMMPolicy ); BAIL_ON_LOCK_ERROR(dwError);
LEAVE_SPD_SECTION();
if (gbIKENotify) { (VOID) IKENotifyPolicyChange( &(gPolicyID), POLICY_GUID_MM ); }
TRACE( TRC_INFORMATION, ("Deleted MM Policy \"%ls\"(%!guid!)", pszPolicyName, &gPolicyID) ); return (dwError);
lock:
LEAVE_SPD_SECTION();
#ifdef TRACE_ON
if (pIniMMPolicy) { TRACE( TRC_ERROR, (L"Failed to delete MM policy \"%ls\"(%!guid!): %!winerr!", pIniMMPolicy->pszPolicyName, &pIniMMPolicy->gPolicyID, dwError) ); } else { TRACE( TRC_ERROR, (L"Failed to delete MM policy \"%ls\": %!winerr!", pszPolicyName, dwError) ); } #endif
return (dwError); }
DWORD EnumMMPolicies( LPWSTR pServerName, DWORD dwVersion, PIPSEC_MM_POLICY pMMTemplatePolicy, DWORD dwFlags, DWORD dwPreferredNumEntries, PIPSEC_MM_POLICY * ppMMPolicies, LPDWORD pdwNumPolicies, LPDWORD pdwResumeHandle, LPVOID pvReserved ) /*++
Routine Description:
This function enumerates main mode policies from the SPD.
Arguments:
pServerName - Server on which the main mode policies are to be enumerated.
ppMMPolicies - Enumerated main mode policies returned to the caller.
dwPreferredNumEntries - Preferred number of enumeration entries.
pdwNumPolicies - Number of main mode policies actually enumerated.
pdwResumeHandle - Handle to the location in the main mode policy list from which to resume enumeration.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/ { DWORD dwError = 0; DWORD dwResumeHandle = 0; DWORD dwNumToEnum = 0; PINIMMPOLICY pIniMMPolicy = NULL; DWORD i = 0; PINIMMPOLICY pTemp = NULL; DWORD dwNumPolicies = 0; PIPSEC_MM_POLICY pMMPolicies = NULL; PIPSEC_MM_POLICY pMMPolicy = NULL;
dwResumeHandle = *pdwResumeHandle;
if (!dwPreferredNumEntries || (dwPreferredNumEntries > MAX_MMPOLICY_ENUM_COUNT)) { dwNumToEnum = MAX_MMPOLICY_ENUM_COUNT; } else { dwNumToEnum = dwPreferredNumEntries; }
ENTER_SPD_SECTION();
dwError = ValidateSecurity( SPD_OBJECT_SERVER, SERVER_ACCESS_ADMINISTER, NULL, NULL ); BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = gpIniMMPolicy;
for (i = 0; (i < dwResumeHandle) && (pIniMMPolicy != NULL); i++) { pIniMMPolicy = pIniMMPolicy->pNext; }
if (!pIniMMPolicy) { dwError = ERROR_NO_DATA; BAIL_ON_LOCK_ERROR(dwError); }
pTemp = pIniMMPolicy;
while (pTemp && (dwNumPolicies < dwNumToEnum)) { dwNumPolicies++; pTemp = pTemp->pNext; }
dwError = SPDApiBufferAllocate( sizeof(IPSEC_MM_POLICY)*dwNumPolicies, &pMMPolicies ); BAIL_ON_LOCK_ERROR(dwError);
pTemp = pIniMMPolicy; pMMPolicy = pMMPolicies;
for (i = 0; i < dwNumPolicies; i++) {
dwError = CopyMMPolicy( pTemp, pMMPolicy ); BAIL_ON_LOCK_ERROR(dwError);
pTemp = pTemp->pNext; pMMPolicy++;
}
*ppMMPolicies = pMMPolicies; *pdwResumeHandle = dwResumeHandle + dwNumPolicies; *pdwNumPolicies = dwNumPolicies;
LEAVE_SPD_SECTION();
TRACE(TRC_INFORMATION, (L"Enumerated policies.")); return (dwError);
lock:
LEAVE_SPD_SECTION();
if (pMMPolicies) { FreeMMPolicies( i, pMMPolicies ); }
*ppMMPolicies = NULL; *pdwResumeHandle = dwResumeHandle; *pdwNumPolicies = 0;
TRACE(TRC_ERROR, ("Failed to enumerate policies: %!winerr!", dwError)); return (dwError); }
DWORD SetMMPolicy( LPWSTR pServerName, DWORD dwVersion, LPWSTR pszPolicyName, PIPSEC_MM_POLICY pMMPolicy, LPVOID pvReserved ) /*++
Routine Description:
This function updates a main mode policy in the SPD.
Arguments:
pServerName - Server on which the main mode policy is to be updated.
pszPolicyName - Name of the main mode policy to be updated.
pMMPolicy - New main mode policy which will replace the existing policy.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/ { DWORD dwError = 0; PINIMMPOLICY pIniMMPolicy = NULL; DWORD dwStatus = 0;
if (!pszPolicyName || !*pszPolicyName) { return (ERROR_INVALID_PARAMETER); } //
// Validate main mode policy.
//
dwError = ValidateMMPolicy( pMMPolicy ); BAIL_ON_WIN32_ERROR(dwError);
ENTER_SPD_SECTION();
dwError = ValidateSecurity( SPD_OBJECT_SERVER, SERVER_ACCESS_ADMINISTER, NULL, NULL ); BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = FindMMPolicy( gpIniMMPolicy, pszPolicyName ); if (!pIniMMPolicy) { dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND; BAIL_ON_LOCK_ERROR(dwError); }
if (memcmp( &(pIniMMPolicy->gPolicyID), &(pMMPolicy->gPolicyID), sizeof(GUID))) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_LOCK_ERROR(dwError); }
dwError = SetIniMMPolicy( pIniMMPolicy, pMMPolicy ); if (dwError != WARNING_IPSEC_MM_POLICY_PRUNED) { BAIL_ON_LOCK_ERROR(dwError); } else { dwStatus = dwError; }
LEAVE_SPD_SECTION();
(VOID) IKENotifyPolicyChange( &(pMMPolicy->gPolicyID), POLICY_GUID_MM );
TRACE( TRC_INFORMATION, (L"Changed MM Policy \"%ls\" (%!guid!)", pMMPolicy->pszPolicyName, &pMMPolicy->gPolicyID) ); return (dwStatus);
lock:
LEAVE_SPD_SECTION();
error: #ifdef TRACE_ON
if (pIniMMPolicy) { TRACE( TRC_ERROR, (L"Failed to change MM policy \"%ls\"(%!guid!): %!winerr!", pIniMMPolicy->pszPolicyName, &pIniMMPolicy->gPolicyID, dwError) ); } else { TRACE( TRC_ERROR, (L"Failed to change MM policy \"%ls\": %!winerr!", pszPolicyName, dwError) ); } #endif
return (dwError); }
DWORD GetMMPolicy( LPWSTR pServerName, DWORD dwVersion, LPWSTR pszPolicyName, PIPSEC_MM_POLICY * ppMMPolicy, LPVOID pvReserved ) /*++
Routine Description:
This function gets a main mode policy from the SPD.
Arguments:
pServerName - Server from which to get the main mode policy.
pszPolicyName - Name of the main mode policy to get.
ppMMPolicy - Main mode policy found returned to the caller.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/ { DWORD dwError = 0; PINIMMPOLICY pIniMMPolicy = NULL; PIPSEC_MM_POLICY pMMPolicy = NULL;
if (!pszPolicyName || !*pszPolicyName) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); }
ENTER_SPD_SECTION();
dwError = ValidateSecurity( SPD_OBJECT_SERVER, SERVER_ACCESS_ADMINISTER, NULL, NULL ); BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = FindMMPolicy( gpIniMMPolicy, pszPolicyName ); if (!pIniMMPolicy) { dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND; BAIL_ON_LOCK_ERROR(dwError); }
dwError = GetIniMMPolicy( pIniMMPolicy, &pMMPolicy ); BAIL_ON_LOCK_ERROR(dwError);
*ppMMPolicy = pMMPolicy;
LEAVE_SPD_SECTION(); return (dwError);
lock:
LEAVE_SPD_SECTION();
error:
*ppMMPolicy = NULL; return (dwError); }
DWORD SetIniMMPolicy( PINIMMPOLICY pIniMMPolicy, PIPSEC_MM_POLICY pMMPolicy ) { DWORD dwError = 0; DWORD dwOfferCount = 0; PIPSEC_MM_OFFER pOffers = NULL;
dwError = CreateIniMMOffers( pMMPolicy->dwOfferCount, pMMPolicy->pOffers, &dwOfferCount, &pOffers ); if (dwError != WARNING_IPSEC_MM_POLICY_PRUNED) { BAIL_ON_WIN32_ERROR(dwError); }
FreeIniMMOffers( pIniMMPolicy->dwOfferCount, pIniMMPolicy->pOffers ); if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) { gpIniDefaultMMPolicy = NULL; TRACE( TRC_INFORMATION, (L"Cleared default MM policy \"%ls\" (%!guid!)", pIniMMPolicy->pszPolicyName, &pIniMMPolicy->gPolicyID) ); }
pIniMMPolicy->dwFlags = pMMPolicy->dwFlags; pIniMMPolicy->uSoftExpirationTime = pMMPolicy->uSoftExpirationTime; pIniMMPolicy->dwOfferCount = dwOfferCount; pIniMMPolicy->pOffers = pOffers;
if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) { gpIniDefaultMMPolicy = pIniMMPolicy; TRACE( TRC_INFORMATION, (L"Set default MM policy to \"%ls\" (%!guid!)", pIniMMPolicy->pszPolicyName, &pIniMMPolicy->gPolicyID) ); }
error:
return (dwError); }
DWORD GetIniMMPolicy( PINIMMPOLICY pIniMMPolicy, PIPSEC_MM_POLICY * ppMMPolicy ) { DWORD dwError = 0; PIPSEC_MM_POLICY pMMPolicy = NULL;
dwError = SPDApiBufferAllocate( sizeof(IPSEC_MM_POLICY), &pMMPolicy ); BAIL_ON_WIN32_ERROR(dwError);
dwError = CopyMMPolicy( pIniMMPolicy, pMMPolicy ); BAIL_ON_WIN32_ERROR(dwError);
*ppMMPolicy = pMMPolicy; return (dwError);
error:
if (pMMPolicy) { SPDApiBufferFree(pMMPolicy); }
*ppMMPolicy = NULL; return (dwError); }
DWORD CopyMMPolicy( PINIMMPOLICY pIniMMPolicy, PIPSEC_MM_POLICY pMMPolicy ) { DWORD dwError = 0;
memcpy( &(pMMPolicy->gPolicyID), &(pIniMMPolicy->gPolicyID), sizeof(GUID) );
dwError = SPDApiBufferAllocate( wcslen(pIniMMPolicy->pszPolicyName)*sizeof(WCHAR) + sizeof(WCHAR), &(pMMPolicy->pszPolicyName) ); BAIL_ON_WIN32_ERROR(dwError);
wcscpy(pMMPolicy->pszPolicyName, pIniMMPolicy->pszPolicyName); pMMPolicy->dwFlags = pIniMMPolicy->dwFlags; pMMPolicy->uSoftExpirationTime = pIniMMPolicy->uSoftExpirationTime;
dwError = CreateMMOffers( pIniMMPolicy->dwOfferCount, pIniMMPolicy->pOffers, &(pMMPolicy->dwOfferCount), &(pMMPolicy->pOffers) ); BAIL_ON_WIN32_ERROR(dwError);
return (dwError);
error:
if (pMMPolicy->pszPolicyName) { SPDApiBufferFree(pMMPolicy->pszPolicyName); }
return (dwError); }
DWORD CreateMMOffers( DWORD dwInOfferCount, PIPSEC_MM_OFFER pInOffers, PDWORD pdwOfferCount, PIPSEC_MM_OFFER * ppOffers ) { DWORD dwError = 0; PIPSEC_MM_OFFER pOffers = NULL; PIPSEC_MM_OFFER pTemp = NULL; PIPSEC_MM_OFFER pInTempOffer = NULL; DWORD i = 0;
//
// Offer count and the offers themselves have already been validated.
//
dwError = SPDApiBufferAllocate( sizeof(IPSEC_MM_OFFER) * dwInOfferCount, &(pOffers) ); BAIL_ON_WIN32_ERROR(dwError);
pTemp = pOffers; pInTempOffer = pInOffers;
for (i = 0; i < dwInOfferCount; i++) {
memcpy( &(pTemp->Lifetime), &(pInTempOffer->Lifetime), sizeof(KEY_LIFETIME) );
pTemp->dwFlags = pInTempOffer->dwFlags; pTemp->dwQuickModeLimit = pInTempOffer->dwQuickModeLimit; pTemp->dwDHGroup = pInTempOffer->dwDHGroup;
memcpy( &(pTemp->EncryptionAlgorithm), &(pInTempOffer->EncryptionAlgorithm), sizeof(IPSEC_MM_ALGO) ); memcpy( &(pTemp->HashingAlgorithm), &(pInTempOffer->HashingAlgorithm), sizeof(IPSEC_MM_ALGO) );
pInTempOffer++; pTemp++;
}
*pdwOfferCount = dwInOfferCount; *ppOffers = pOffers; return (dwError);
error: TRACE(TRC_ERROR, ("Failed to create MM offers")); if (pOffers) { FreeMMOffers( i, pOffers ); }
*pdwOfferCount = 0; *ppOffers = NULL; return (dwError); }
DWORD DeleteIniMMPolicy( PINIMMPOLICY pIniMMPolicy ) { DWORD dwError = 0; PINIMMPOLICY * ppTemp = NULL;
ppTemp = &gpIniMMPolicy;
while (*ppTemp) {
if (*ppTemp == pIniMMPolicy) { break; } ppTemp = &((*ppTemp)->pNext);
}
if (*ppTemp) { *ppTemp = pIniMMPolicy->pNext; }
if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) { gpIniDefaultMMPolicy = NULL; TRACE( TRC_INFORMATION, (L"Cleared default MM policy \"%ls\" (%!guid!)", pIniMMPolicy->pszPolicyName, &pIniMMPolicy->gPolicyID) ); }
FreeIniMMPolicy(pIniMMPolicy);
return (dwError); }
VOID FreeMMOffers( DWORD dwOfferCount, PIPSEC_MM_OFFER pOffers ) { if (pOffers) { SPDApiBufferFree(pOffers); } }
VOID FreeIniMMPolicyList( PINIMMPOLICY pIniMMPolicyList ) { PINIMMPOLICY pTemp = NULL; PINIMMPOLICY pIniMMPolicy = NULL;
pTemp = pIniMMPolicyList;
while (pTemp) {
pIniMMPolicy = pTemp; pTemp = pTemp->pNext;
FreeIniMMPolicy(pIniMMPolicy);
} }
PINIMMPOLICY FindMMPolicyByGuid( PINIMMPOLICY pIniMMPolicyList, GUID gPolicyID ) { DWORD dwError = 0; PINIMMPOLICY pTemp = NULL;
pTemp = pIniMMPolicyList;
while (pTemp) {
if (!memcmp(&(pTemp->gPolicyID), &gPolicyID, sizeof(GUID))) { return (pTemp); } pTemp = pTemp->pNext;
}
return (NULL); }
VOID FreeMMPolicies( DWORD dwNumMMPolicies, PIPSEC_MM_POLICY pMMPolicies ) { DWORD i = 0;
if (pMMPolicies) {
for (i = 0; i < dwNumMMPolicies; i++) {
if (pMMPolicies[i].pszPolicyName) { SPDApiBufferFree(pMMPolicies[i].pszPolicyName); }
FreeMMOffers( pMMPolicies[i].dwOfferCount, pMMPolicies[i].pOffers );
}
SPDApiBufferFree(pMMPolicies);
}
}
DWORD GetMMPolicyByID( LPWSTR pServerName, DWORD dwVersion, GUID gMMPolicyID, PIPSEC_MM_POLICY * ppMMPolicy, LPVOID pvReserved ) /*++
Routine Description:
This function gets a main mode policy from the SPD.
Arguments:
pServerName - Server from which to get the main mode policy.
gMMPolicyID - Guid of the main mode policy to get.
ppMMPolicy - Main mode policy found returned to the caller.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/ { DWORD dwError = 0; PINIMMPOLICY pIniMMPolicy = NULL; PIPSEC_MM_POLICY pMMPolicy = NULL;
ENTER_SPD_SECTION();
dwError = ValidateSecurity( SPD_OBJECT_SERVER, SERVER_ACCESS_ADMINISTER, NULL, NULL ); BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = FindMMPolicyByGuid( gpIniMMPolicy, gMMPolicyID ); if (!pIniMMPolicy) { dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND; BAIL_ON_LOCK_ERROR(dwError); }
dwError = GetIniMMPolicy( pIniMMPolicy, &pMMPolicy ); BAIL_ON_LOCK_ERROR(dwError);
*ppMMPolicy = pMMPolicy;
LEAVE_SPD_SECTION(); return (dwError);
lock:
LEAVE_SPD_SECTION();
*ppMMPolicy = NULL; return (dwError); }
DWORD LocateMMPolicy( PMM_FILTER pMMFilter, PINIMMPOLICY * ppIniMMPolicy ) { DWORD dwError = 0; PINIMMPOLICY pIniMMPolicy = NULL;
if ((pMMFilter->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
if (!gpIniDefaultMMPolicy) { dwError = ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND; BAIL_ON_WIN32_ERROR(dwError); } pIniMMPolicy = gpIniDefaultMMPolicy;
} else {
pIniMMPolicy = FindMMPolicyByGuid( gpIniMMPolicy, pMMFilter->gPolicyID ); if (!pIniMMPolicy) { dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND; BAIL_ON_WIN32_ERROR(dwError); }
}
*ppIniMMPolicy = pIniMMPolicy; return (dwError);
error:
*ppIniMMPolicy = NULL; return (dwError); }
|