mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1052 lines
37 KiB
1052 lines
37 KiB
|
|
|
|
|
|
#include "ipseccmd.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
IPSECPolicyToStorage::IPSECPolicyToStorage():
|
|
myPolicyStorage(NULL),
|
|
myIPSECPolicy(NULL),
|
|
mybIsOpen(false),
|
|
mybPolicyExists(false)
|
|
{
|
|
}
|
|
|
|
IPSECPolicyToStorage::~IPSECPolicyToStorage()
|
|
{
|
|
|
|
// if (myIPSECPolicy) IPSecFreePolicyData(myIPSECPolicy);
|
|
// polstore AVs if something inside the policy is missing
|
|
|
|
if (myPolicyStorage)
|
|
{
|
|
IPSecClosePolicyStore(myPolicyStorage);
|
|
}
|
|
}
|
|
|
|
// this small function will attempt to CreateIpsecPolicyData, and if it succeeds, it'll mark that object is created in the storage
|
|
// so that next time we'll use Set routine, not Create
|
|
void
|
|
IPSECPolicyToStorage::TryToCreatePolicy()
|
|
{
|
|
if (IPSecCreatePolicyData(myPolicyStorage, myIPSECPolicy) == ERROR_SUCCESS)
|
|
{
|
|
mybPolicyExists = true;
|
|
}
|
|
}
|
|
|
|
// opens storage an initializes policy
|
|
// pass name as NULL for local storage or if you want
|
|
// the DS to be located
|
|
// szPolicyName is required
|
|
// szDescription is optional
|
|
HRESULT
|
|
IPSECPolicyToStorage::Open(
|
|
IN DWORD location,
|
|
IN LPTSTR name,
|
|
IN LPTSTR szPolicyName,
|
|
IN LPTSTR szDescription,
|
|
IN time_t tPollingInterval,
|
|
IN bool bUseExisting)
|
|
|
|
{
|
|
HRESULT hrReturnCode = S_OK;
|
|
RPC_STATUS RpcStat;
|
|
|
|
// need to do error checking
|
|
if (!szPolicyName || (szPolicyName[0] == TEXT('\0')) )
|
|
{
|
|
hrReturnCode = P2STORE_MISSING_NAME;
|
|
}
|
|
else
|
|
{
|
|
if (myPolicyStorage)
|
|
{
|
|
IPSecClosePolicyStore(myPolicyStorage);
|
|
myPolicyStorage = NULL;
|
|
}
|
|
hrReturnCode = IPSecOpenPolicyStore(name, location, NULL, &myPolicyStorage);
|
|
if (hrReturnCode == ERROR_SUCCESS)
|
|
{
|
|
mybIsOpen = true;
|
|
if (myIPSECPolicy)
|
|
{
|
|
IPSecFreePolicyData(myIPSECPolicy);
|
|
myIPSECPolicy = NULL;
|
|
}
|
|
if (bUseExisting)
|
|
{
|
|
// try to find existing policy cause user requested us to
|
|
// myIPSECPolicy will be NULL if we haven't found it
|
|
PIPSEC_POLICY_DATA *ppPolicyEnum = NULL;
|
|
DWORD dwNumPolicies = 0;
|
|
|
|
|
|
hrReturnCode = IPSecEnumPolicyData(myPolicyStorage, &ppPolicyEnum, &dwNumPolicies);
|
|
if (hrReturnCode == ERROR_SUCCESS && dwNumPolicies > 0 && ppPolicyEnum != NULL)
|
|
{
|
|
// we have something in the storage, let's go through it
|
|
int i;
|
|
|
|
for (i = 0; i < (int) dwNumPolicies; i++)
|
|
{
|
|
if (wcscmp(ppPolicyEnum[i]->pszIpsecName, szPolicyName) == 0)
|
|
{
|
|
// we found it
|
|
// make a copy in myIPSECPolicy and update description and polling interval
|
|
hrReturnCode = IPSecCopyPolicyData(ppPolicyEnum[i], &myIPSECPolicy);
|
|
mybPolicyExists = true;
|
|
if (hrReturnCode == ERROR_SUCCESS)
|
|
{
|
|
hrReturnCode = IPSecEnumNFAData(myPolicyStorage, myIPSECPolicy->PolicyIdentifier
|
|
, &(myIPSECPolicy->ppIpsecNFAData), &(myIPSECPolicy->dwNumNFACount));
|
|
}
|
|
if (hrReturnCode == ERROR_SUCCESS)
|
|
{
|
|
int i;
|
|
|
|
// also get other parts of the policy, no error checks here
|
|
IPSecGetISAKMPData(myPolicyStorage, myIPSECPolicy->ISAKMPIdentifier, &(myIPSECPolicy->pIpsecISAKMPData));
|
|
for (i = 0; i < (int) myIPSECPolicy->dwNumNFACount; i++)
|
|
{
|
|
if (!UuidIsNil(&(myIPSECPolicy->ppIpsecNFAData[i]->NegPolIdentifier), &RpcStat))
|
|
{
|
|
IPSecGetNegPolData(myPolicyStorage,
|
|
myIPSECPolicy->ppIpsecNFAData[i]->NegPolIdentifier,
|
|
&(myIPSECPolicy->ppIpsecNFAData[i]->pIpsecNegPolData));
|
|
}
|
|
if (!UuidIsNil(&(myIPSECPolicy->ppIpsecNFAData[i]->FilterIdentifier), &RpcStat))
|
|
{
|
|
IPSecGetFilterData(myPolicyStorage,
|
|
myIPSECPolicy->ppIpsecNFAData[i]->FilterIdentifier,
|
|
&(myIPSECPolicy->ppIpsecNFAData[i]->pIpsecFilterData));
|
|
}
|
|
}
|
|
|
|
if (myIPSECPolicy->pszDescription == NULL && szDescription != NULL)
|
|
{
|
|
// we've got description to set
|
|
myIPSECPolicy->pszDescription = IPSecAllocPolStr(szDescription);
|
|
}
|
|
// set Polling Interval
|
|
if (tPollingInterval >= 0)
|
|
{
|
|
myIPSECPolicy->dwPollingInterval = (DWORD) tPollingInterval;
|
|
}
|
|
// commit
|
|
hrReturnCode = IPSecSetPolicyData(myPolicyStorage, myIPSECPolicy);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hrReturnCode = ERROR_SUCCESS;
|
|
}
|
|
|
|
// clean it up
|
|
if (dwNumPolicies > 0 && ppPolicyEnum != NULL)
|
|
{
|
|
IPSecFreeMulPolicyData(ppPolicyEnum, dwNumPolicies);
|
|
}
|
|
}
|
|
|
|
// this is executed only when no bUseExisting was specified or existing policy wasn't found
|
|
if (!bUseExisting || myIPSECPolicy == NULL)
|
|
{
|
|
// create
|
|
mybPolicyExists = false;
|
|
myIPSECPolicy = (PIPSEC_POLICY_DATA) IPSecAllocPolMem(sizeof(IPSEC_POLICY_DATA));
|
|
if (myIPSECPolicy == NULL)
|
|
{
|
|
hrReturnCode = GetLastError();
|
|
}
|
|
else
|
|
{
|
|
myIPSECPolicy->pszIpsecName = IPSecAllocPolStr(szPolicyName);
|
|
if (szDescription)
|
|
{
|
|
myIPSECPolicy->pszDescription = IPSecAllocPolStr(szDescription);
|
|
}
|
|
else
|
|
{
|
|
myIPSECPolicy->pszDescription = NULL;
|
|
}
|
|
myIPSECPolicy->dwPollingInterval = (DWORD) tPollingInterval;
|
|
RpcStat = UuidCreate(&(myIPSECPolicy->PolicyIdentifier));
|
|
assert(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY);
|
|
|
|
// now init other stuff somehow
|
|
myIPSECPolicy->pIpsecISAKMPData = NULL;
|
|
myIPSECPolicy->ppIpsecNFAData = NULL;
|
|
myIPSECPolicy->dwNumNFACount = 0;
|
|
myIPSECPolicy->dwWhenChanged = 0;
|
|
UuidCreateNil(&(myIPSECPolicy->ISAKMPIdentifier));
|
|
|
|
// TryToCreatePolicy();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return hrReturnCode;
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
IPSECPolicyToStorage::AddRule(
|
|
IN IPSEC_IKE_POLICY IpsecIkePol,
|
|
PSTORAGE_INFO pStorageInfo)
|
|
{
|
|
HRESULT hrReturn = S_OK;
|
|
PIPSEC_NFA_DATA pRule = MakeRule(IpsecIkePol, pStorageInfo);
|
|
int i;
|
|
|
|
if (!IsOpen())
|
|
{
|
|
return ERROR_ACCESS_DENIED;
|
|
}
|
|
// form policy data structures
|
|
myIPSECPolicy->dwNumNFACount++;
|
|
myIPSECPolicy->ppIpsecNFAData = (PIPSEC_NFA_DATA *) ReallocPolMem(myIPSECPolicy->ppIpsecNFAData
|
|
, (myIPSECPolicy->dwNumNFACount-1)*sizeof(PIPSEC_NFA_DATA)
|
|
, (myIPSECPolicy->dwNumNFACount)*sizeof(PIPSEC_NFA_DATA));
|
|
myIPSECPolicy->ppIpsecNFAData[myIPSECPolicy->dwNumNFACount-1] = pRule;
|
|
|
|
// commit everything
|
|
// start from qm policy
|
|
if (!pRule->pIpsecFilterData)
|
|
{
|
|
// fix up neg pol
|
|
pRule->pIpsecNegPolData->NegPolType = GUID_NEGOTIATION_TYPE_DEFAULT;
|
|
}
|
|
hrReturn = IPSecCreateNegPolData(myPolicyStorage, pRule->pIpsecNegPolData);
|
|
if (hrReturn != ERROR_SUCCESS)
|
|
{
|
|
return hrReturn;
|
|
}
|
|
|
|
// filter
|
|
if (pRule->pIpsecFilterData)
|
|
{
|
|
hrReturn = IPSecCreateFilterData(myPolicyStorage, pRule->pIpsecFilterData);
|
|
if (hrReturn != ERROR_SUCCESS)
|
|
{
|
|
return hrReturn;
|
|
}
|
|
}
|
|
|
|
// NFA
|
|
IPSecCreateNFAData(myPolicyStorage, myIPSECPolicy->PolicyIdentifier, pRule);
|
|
// policy
|
|
if (IsPolicyInStorage())
|
|
{
|
|
IPSecSetPolicyData(myPolicyStorage, myIPSECPolicy);
|
|
}
|
|
else
|
|
{
|
|
TryToCreatePolicy();
|
|
}
|
|
|
|
return hrReturn;
|
|
}
|
|
|
|
// Add default response rule to the policy
|
|
HRESULT IPSECPolicyToStorage::AddDefaultResponseRule ( )
|
|
{
|
|
HRESULT hrReturn = S_OK;
|
|
PIPSEC_NFA_DATA pRule = MakeDefaultResponseRule();
|
|
int i;
|
|
|
|
if (!IsOpen())
|
|
{
|
|
return ERROR_ACCESS_DENIED;
|
|
}
|
|
// form policy data structures
|
|
myIPSECPolicy->dwNumNFACount++;
|
|
myIPSECPolicy->ppIpsecNFAData = (PIPSEC_NFA_DATA *) ReallocPolMem(myIPSECPolicy->ppIpsecNFAData
|
|
, (myIPSECPolicy->dwNumNFACount-1)*sizeof(PIPSEC_NFA_DATA)
|
|
, (myIPSECPolicy->dwNumNFACount)*sizeof(PIPSEC_NFA_DATA));
|
|
myIPSECPolicy->ppIpsecNFAData[myIPSECPolicy->dwNumNFACount-1] = pRule;
|
|
|
|
// commit everything
|
|
// start from qm policy
|
|
// fix up neg pol
|
|
pRule->pIpsecNegPolData->NegPolType = GUID_NEGOTIATION_TYPE_DEFAULT;
|
|
hrReturn = IPSecCreateNegPolData(myPolicyStorage, pRule->pIpsecNegPolData);
|
|
if (hrReturn != ERROR_SUCCESS)
|
|
{
|
|
return hrReturn;
|
|
}
|
|
|
|
// NFA
|
|
IPSecCreateNFAData(myPolicyStorage, myIPSECPolicy->PolicyIdentifier, pRule);
|
|
// policy
|
|
if (IsPolicyInStorage())
|
|
{
|
|
IPSecSetPolicyData(myPolicyStorage, myIPSECPolicy);
|
|
}
|
|
else
|
|
{
|
|
TryToCreatePolicy();
|
|
}
|
|
|
|
return hrReturn;
|
|
}
|
|
|
|
|
|
// this will update a rule:
|
|
// if there are filters, all the filters from the current NFA
|
|
// are removed and the ones passed in are added
|
|
// same thing goes for negotiation policies and authinfos
|
|
|
|
HRESULT
|
|
IPSECPolicyToStorage::UpdateRule(
|
|
IN PIPSEC_NFA_DATA pRule,
|
|
IN IPSEC_IKE_POLICY IpsecIkePol,
|
|
IN PSTORAGE_INFO pStorageInfo)
|
|
{
|
|
RPC_STATUS RpcStat;
|
|
T2P_FILTER *pFilterList;
|
|
IF_TYPE Interface;
|
|
WCHAR wszRuleName[POTF_MAX_STRLEN];
|
|
HRESULT hrReturn = S_OK;
|
|
int i;
|
|
GUID oldFilter, oldNegPol;
|
|
|
|
if (pRule == NULL || !IsOpen())
|
|
{
|
|
return ERROR_ACCESS_DENIED;
|
|
}
|
|
|
|
// first, remove filter and policy data
|
|
oldFilter = pRule->FilterIdentifier;
|
|
if (pRule->pIpsecFilterData)
|
|
{
|
|
IPSecFreeFilterData(pRule->pIpsecFilterData);
|
|
}
|
|
oldNegPol = pRule->NegPolIdentifier;
|
|
if (pRule->pIpsecNegPolData)
|
|
{
|
|
IPSecFreeNegPolData(pRule->pIpsecNegPolData);
|
|
}
|
|
// free auth methods
|
|
if (pRule->ppAuthMethods)
|
|
{
|
|
for (i = 0; i < (int) pRule->dwAuthMethodCount; i++)
|
|
{
|
|
if (pRule->ppAuthMethods[i]->pszAuthMethod)
|
|
{
|
|
IPSecFreePolMem(pRule->ppAuthMethods[i]->pszAuthMethod);
|
|
}
|
|
if (pRule->ppAuthMethods[i]->dwAltAuthLen && pRule->ppAuthMethods[i]->pAltAuthMethod)
|
|
{
|
|
IPSecFreePolMem(pRule->ppAuthMethods[i]->pAltAuthMethod);
|
|
}
|
|
IPSecFreePolMem(pRule->ppAuthMethods[i]);
|
|
}
|
|
}
|
|
IPSecFreePolMem(pRule->ppAuthMethods);
|
|
// free strings
|
|
if (pRule->pszIpsecName)
|
|
{
|
|
IPSecFreePolStr(pRule->pszIpsecName);
|
|
}
|
|
if (pRule->pszInterfaceName)
|
|
{
|
|
IPSecFreePolStr(pRule->pszInterfaceName);
|
|
}
|
|
if (pRule->pszEndPointName)
|
|
{
|
|
IPSecFreePolStr(pRule->pszEndPointName);
|
|
}
|
|
if (pRule->pszDescription)
|
|
{
|
|
IPSecFreePolStr(pRule->pszDescription);
|
|
}
|
|
|
|
// now make a rule
|
|
pRule->pszIpsecName = pRule->pszDescription = pRule->pszInterfaceName = pRule->pszEndPointName = NULL;
|
|
if (pStorageInfo)
|
|
{
|
|
pRule->pszIpsecName = IPSecAllocPolStr(pStorageInfo->szRuleName);
|
|
}
|
|
pRule->dwWhenChanged = 0;
|
|
|
|
// filters
|
|
if (IpsecIkePol.QMFilterType == QM_TRANSPORT_FILTER
|
|
&& IpsecIkePol.pTransportFilters[0].SrcAddr.AddrType == IP_ADDR_UNIQUE
|
|
&& IpsecIkePol.pTransportFilters[0].SrcAddr.uIpAddr == IP_ADDRESS_ME
|
|
&& IpsecIkePol.pTransportFilters[0].DesAddr.AddrType == IP_ADDR_UNIQUE
|
|
&& IpsecIkePol.pTransportFilters[0].DesAddr.uIpAddr == IP_ADDRESS_ME
|
|
&& IpsecIkePol.pTransportFilters[0].InboundFilterFlag == (FILTER_FLAG) POTF_DEFAULT_RESPONSE_FLAG
|
|
&& IpsecIkePol.pTransportFilters[0].OutboundFilterFlag == (FILTER_FLAG) POTF_DEFAULT_RESPONSE_FLAG)
|
|
{
|
|
pRule->pIpsecFilterData = NULL;
|
|
UuidCreateNil(&(pRule->FilterIdentifier));
|
|
}
|
|
else
|
|
{
|
|
pFilterList = new T2P_FILTER[IpsecIkePol.dwNumFilters];
|
|
for (i = 0; i < (int) IpsecIkePol.dwNumFilters; i++)
|
|
{
|
|
if (IpsecIkePol.QMFilterType == QM_TRANSPORT_FILTER)
|
|
{
|
|
pFilterList[i].QMFilterType = QM_TRANSPORT_FILTER;
|
|
pFilterList[i].TransportFilter = IpsecIkePol.pTransportFilters[i];
|
|
}
|
|
else
|
|
{
|
|
// tunnel
|
|
pFilterList[i].QMFilterType = QM_TUNNEL_FILTER;
|
|
pFilterList[i].TunnelFilter = IpsecIkePol.pTunnelFilters[i];
|
|
}
|
|
}
|
|
if (pStorageInfo)
|
|
{
|
|
pRule->pIpsecFilterData = MakeFilters(pFilterList, IpsecIkePol.dwNumFilters, pStorageInfo->szRuleName);
|
|
}
|
|
else
|
|
{
|
|
pRule->pIpsecFilterData = MakeFilters(pFilterList, IpsecIkePol.dwNumFilters, L"");
|
|
}
|
|
pRule->FilterIdentifier = pRule->pIpsecFilterData->FilterIdentifier;
|
|
delete[] pFilterList;
|
|
}
|
|
|
|
// filter action
|
|
if (pStorageInfo)
|
|
{
|
|
pRule->pIpsecNegPolData = MakeNegotiationPolicy(IpsecIkePol.IpsPol, pStorageInfo->szRuleName);
|
|
}
|
|
else
|
|
{
|
|
pRule->pIpsecNegPolData = MakeNegotiationPolicy(IpsecIkePol.IpsPol, L"");
|
|
}
|
|
pRule->NegPolIdentifier = pRule->pIpsecNegPolData->NegPolIdentifier;
|
|
if (pStorageInfo && pStorageInfo->guidNegPolAction != GUID_NEGOTIATION_ACTION_NORMAL_IPSEC)
|
|
{
|
|
pRule->pIpsecNegPolData->NegPolAction = pStorageInfo->guidNegPolAction;
|
|
}
|
|
|
|
// tunnel address
|
|
pRule->dwTunnelFlags = 0;
|
|
if (IpsecIkePol.QMFilterType == QM_TUNNEL_FILTER)
|
|
{
|
|
pRule->dwTunnelFlags = 1;
|
|
pRule->dwTunnelIpAddr = IpsecIkePol.pTunnelFilters[0].DesTunnelAddr.uIpAddr;
|
|
}
|
|
|
|
// interface type
|
|
Interface = (IpsecIkePol.QMFilterType == QM_TRANSPORT_FILTER) ? IpsecIkePol.pTransportFilters[0].InterfaceType : IpsecIkePol.pTunnelFilters[0].InterfaceType;
|
|
if (Interface == INTERFACE_TYPE_ALL)
|
|
{
|
|
pRule->dwInterfaceType = PAS_INTERFACE_TYPE_ALL;
|
|
}
|
|
else if (Interface == INTERFACE_TYPE_LAN)
|
|
{
|
|
pRule->dwInterfaceType = PAS_INTERFACE_TYPE_LAN;
|
|
}
|
|
else if (Interface == INTERFACE_TYPE_DIALUP)
|
|
{
|
|
pRule->dwInterfaceType = PAS_INTERFACE_TYPE_DIALUP;
|
|
}
|
|
else
|
|
{
|
|
pRule->dwInterfaceType = PAS_INTERFACE_TYPE_NONE;
|
|
}
|
|
|
|
// active flag
|
|
pRule->dwActiveFlag = TRUE;
|
|
|
|
// auth methods
|
|
pRule->dwAuthMethodCount = IpsecIkePol.AuthInfos.dwNumAuthInfos;
|
|
pRule->ppAuthMethods = (PIPSEC_AUTH_METHOD *) IPSecAllocPolMem(pRule->dwAuthMethodCount * sizeof(PIPSEC_AUTH_METHOD));
|
|
for (i = 0; i < (int) pRule->dwAuthMethodCount; i++)
|
|
{
|
|
pRule->ppAuthMethods[i] = (PIPSEC_AUTH_METHOD) IPSecAllocPolMem(sizeof(IPSEC_AUTH_METHOD));
|
|
pRule->ppAuthMethods[i]->dwAuthType = IpsecIkePol.AuthInfos.pAuthenticationInfo[i].AuthMethod;
|
|
if (pRule->ppAuthMethods[i]->dwAuthType == IKE_SSPI)
|
|
{
|
|
pRule->ppAuthMethods[i]->dwAuthLen = 0;
|
|
pRule->ppAuthMethods[i]->pszAuthMethod = NULL;
|
|
pRule->ppAuthMethods[i]->dwAltAuthLen = 0;
|
|
pRule->ppAuthMethods[i]->pAltAuthMethod = 0;
|
|
}
|
|
else if (pRule->ppAuthMethods[i]->dwAuthType == IKE_RSA_SIGNATURE)
|
|
{
|
|
LPTSTR pTemp = NULL;
|
|
pRule->ppAuthMethods[i]->dwAltAuthLen = IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize;
|
|
pRule->ppAuthMethods[i]->pAltAuthMethod = (PBYTE) IPSecAllocPolMem(IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize);
|
|
memcpy(pRule->ppAuthMethods[i]->pAltAuthMethod, IpsecIkePol.AuthInfos.pAuthenticationInfo[i].pAuthInfo, IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize);
|
|
|
|
hrReturn = CM_DecodeName(pRule->ppAuthMethods[i]->pAltAuthMethod, pRule->ppAuthMethods[i]->dwAltAuthLen, &pTemp);
|
|
assert(hrReturn == ERROR_SUCCESS);
|
|
pRule->ppAuthMethods[i]->pszAuthMethod = IPSecAllocPolStr(pTemp);
|
|
pRule->ppAuthMethods[i]->dwAuthLen = wcslen(pRule->ppAuthMethods[i]->pszAuthMethod);
|
|
delete[] pTemp;
|
|
}
|
|
else
|
|
{
|
|
pRule->ppAuthMethods[i]->dwAuthLen = IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize / sizeof(WCHAR);
|
|
pRule->ppAuthMethods[i]->pszAuthMethod = (LPWSTR) IPSecAllocPolMem(IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize + sizeof(WCHAR));
|
|
memcpy(pRule->ppAuthMethods[i]->pszAuthMethod, IpsecIkePol.AuthInfos.pAuthenticationInfo[i].pAuthInfo, IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize);
|
|
// add trailing '\0' - this is requirement for the polstore
|
|
pRule->ppAuthMethods[i]->pszAuthMethod[pRule->ppAuthMethods[i]->dwAuthLen] = 0;
|
|
|
|
pRule->ppAuthMethods[i]->dwAltAuthLen = 0;
|
|
pRule->ppAuthMethods[i]->pAltAuthMethod = 0;
|
|
}
|
|
}
|
|
|
|
// plumb it
|
|
if (!pRule->pIpsecFilterData)
|
|
{
|
|
// fix up neg pol
|
|
pRule->pIpsecNegPolData->NegPolType = GUID_NEGOTIATION_TYPE_DEFAULT;
|
|
}
|
|
hrReturn = IPSecCreateNegPolData(myPolicyStorage, pRule->pIpsecNegPolData);
|
|
if (hrReturn != ERROR_SUCCESS)
|
|
{
|
|
return hrReturn;
|
|
}
|
|
|
|
// filter
|
|
if (pRule->pIpsecFilterData)
|
|
{
|
|
hrReturn = IPSecCreateFilterData(myPolicyStorage, pRule->pIpsecFilterData);
|
|
if (hrReturn != ERROR_SUCCESS)
|
|
{
|
|
return hrReturn;
|
|
}
|
|
}
|
|
|
|
// NFA
|
|
IPSecSetNFAData(myPolicyStorage, myIPSECPolicy->PolicyIdentifier, pRule);
|
|
// policy
|
|
if (IsPolicyInStorage())
|
|
{
|
|
IPSecSetPolicyData(myPolicyStorage, myIPSECPolicy);
|
|
}
|
|
else
|
|
{
|
|
TryToCreatePolicy();
|
|
}
|
|
|
|
if (!UuidIsNil(&oldFilter, &RpcStat))
|
|
{
|
|
IPSecDeleteFilterData(myPolicyStorage, oldFilter);
|
|
}
|
|
IPSecDeleteNegPolData(myPolicyStorage, oldNegPol);
|
|
return hrReturn;
|
|
}
|
|
|
|
// forms a rule but doesn't commit it
|
|
PIPSEC_NFA_DATA
|
|
IPSECPolicyToStorage::MakeRule(IN IPSEC_IKE_POLICY IpsecIkePol, IN PSTORAGE_INFO pStorageInfo)
|
|
{
|
|
RPC_STATUS RpcStat;
|
|
T2P_FILTER *pFilterList;
|
|
IF_TYPE Interface;
|
|
int i;
|
|
WCHAR wszRuleName[POTF_MAX_STRLEN];
|
|
PIPSEC_NFA_DATA pRule = (PIPSEC_NFA_DATA) IPSecAllocPolMem(sizeof(IPSEC_NFA_DATA));
|
|
HRESULT hrReturn = S_OK;
|
|
|
|
assert(pRule);
|
|
pRule->pszIpsecName = pRule->pszDescription = pRule->pszInterfaceName = pRule->pszEndPointName = NULL;
|
|
if (pStorageInfo)
|
|
{
|
|
pRule->pszIpsecName = IPSecAllocPolStr(pStorageInfo->szRuleName);
|
|
}
|
|
RpcStat = UuidCreate(&(pRule->NFAIdentifier));
|
|
assert(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY);
|
|
pRule->dwWhenChanged = 0;
|
|
|
|
// filters
|
|
if (IpsecIkePol.QMFilterType == QM_TRANSPORT_FILTER
|
|
&& IpsecIkePol.pTransportFilters[0].SrcAddr.AddrType == IP_ADDR_UNIQUE
|
|
&& IpsecIkePol.pTransportFilters[0].SrcAddr.uIpAddr == IP_ADDRESS_ME
|
|
&& IpsecIkePol.pTransportFilters[0].DesAddr.AddrType == IP_ADDR_UNIQUE
|
|
&& IpsecIkePol.pTransportFilters[0].DesAddr.uIpAddr == IP_ADDRESS_ME
|
|
&& IpsecIkePol.pTransportFilters[0].InboundFilterFlag == (FILTER_FLAG) POTF_DEFAULT_RESPONSE_FLAG
|
|
&& IpsecIkePol.pTransportFilters[0].OutboundFilterFlag == (FILTER_FLAG) POTF_DEFAULT_RESPONSE_FLAG)
|
|
{
|
|
pRule->pIpsecFilterData = NULL;
|
|
UuidCreateNil(&(pRule->FilterIdentifier));
|
|
}
|
|
else
|
|
{
|
|
pFilterList = new T2P_FILTER[IpsecIkePol.dwNumFilters];
|
|
for (i = 0; i < (int) IpsecIkePol.dwNumFilters; i++)
|
|
{
|
|
if (IpsecIkePol.QMFilterType == QM_TRANSPORT_FILTER)
|
|
{
|
|
pFilterList[i].QMFilterType = QM_TRANSPORT_FILTER;
|
|
pFilterList[i].TransportFilter = IpsecIkePol.pTransportFilters[i];
|
|
}
|
|
else
|
|
{
|
|
// tunnel
|
|
pFilterList[i].QMFilterType = QM_TUNNEL_FILTER;
|
|
pFilterList[i].TunnelFilter = IpsecIkePol.pTunnelFilters[i];
|
|
}
|
|
}
|
|
if (pStorageInfo)
|
|
{
|
|
pRule->pIpsecFilterData = MakeFilters(pFilterList, IpsecIkePol.dwNumFilters, pStorageInfo->szRuleName);
|
|
}
|
|
else
|
|
{
|
|
pRule->pIpsecFilterData = MakeFilters(pFilterList, IpsecIkePol.dwNumFilters, L"");
|
|
}
|
|
pRule->FilterIdentifier = pRule->pIpsecFilterData->FilterIdentifier;
|
|
delete[] pFilterList;
|
|
}
|
|
|
|
// filter action
|
|
if (pStorageInfo)
|
|
{
|
|
pRule->pIpsecNegPolData = MakeNegotiationPolicy(IpsecIkePol.IpsPol, pStorageInfo->szRuleName);
|
|
}
|
|
else
|
|
{
|
|
pRule->pIpsecNegPolData = MakeNegotiationPolicy(IpsecIkePol.IpsPol, L"");
|
|
}
|
|
pRule->NegPolIdentifier = pRule->pIpsecNegPolData->NegPolIdentifier;
|
|
if (pStorageInfo && pStorageInfo->guidNegPolAction != GUID_NEGOTIATION_ACTION_NORMAL_IPSEC)
|
|
{
|
|
pRule->pIpsecNegPolData->NegPolAction = pStorageInfo->guidNegPolAction;
|
|
}
|
|
|
|
// tunnel address
|
|
pRule->dwTunnelFlags = 0;
|
|
if (IpsecIkePol.QMFilterType == QM_TUNNEL_FILTER)
|
|
{
|
|
pRule->dwTunnelFlags = 1;
|
|
pRule->dwTunnelIpAddr = IpsecIkePol.pTunnelFilters[0].DesTunnelAddr.uIpAddr;
|
|
}
|
|
|
|
// interface type
|
|
Interface = (IpsecIkePol.QMFilterType == QM_TRANSPORT_FILTER) ? IpsecIkePol.pTransportFilters[0].InterfaceType : IpsecIkePol.pTunnelFilters[0].InterfaceType;
|
|
if (Interface == INTERFACE_TYPE_ALL)
|
|
{
|
|
pRule->dwInterfaceType = PAS_INTERFACE_TYPE_ALL;
|
|
}
|
|
else if (Interface == INTERFACE_TYPE_LAN)
|
|
{
|
|
pRule->dwInterfaceType = PAS_INTERFACE_TYPE_LAN;
|
|
}
|
|
else if (Interface == INTERFACE_TYPE_DIALUP)
|
|
{
|
|
pRule->dwInterfaceType = PAS_INTERFACE_TYPE_DIALUP;
|
|
}
|
|
else
|
|
{
|
|
pRule->dwInterfaceType = PAS_INTERFACE_TYPE_NONE;
|
|
}
|
|
|
|
// active flag
|
|
pRule->dwActiveFlag = TRUE;
|
|
|
|
// auth methods
|
|
pRule->dwAuthMethodCount = IpsecIkePol.AuthInfos.dwNumAuthInfos;
|
|
pRule->ppAuthMethods = (PIPSEC_AUTH_METHOD *) IPSecAllocPolMem(pRule->dwAuthMethodCount * sizeof(PIPSEC_AUTH_METHOD));
|
|
for (i = 0; i < (int) pRule->dwAuthMethodCount; i++)
|
|
{
|
|
pRule->ppAuthMethods[i] = (PIPSEC_AUTH_METHOD) IPSecAllocPolMem(sizeof(IPSEC_AUTH_METHOD));
|
|
pRule->ppAuthMethods[i]->dwAuthType = IpsecIkePol.AuthInfos.pAuthenticationInfo[i].AuthMethod;
|
|
if (pRule->ppAuthMethods[i]->dwAuthType == IKE_SSPI)
|
|
{
|
|
pRule->ppAuthMethods[i]->dwAuthLen = 0;
|
|
pRule->ppAuthMethods[i]->pszAuthMethod = NULL;
|
|
pRule->ppAuthMethods[i]->dwAltAuthLen = 0;
|
|
pRule->ppAuthMethods[i]->pAltAuthMethod = 0;
|
|
}
|
|
else if (pRule->ppAuthMethods[i]->dwAuthType == IKE_RSA_SIGNATURE)
|
|
{
|
|
LPTSTR pTemp = NULL;
|
|
pRule->ppAuthMethods[i]->dwAltAuthLen = IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize;
|
|
pRule->ppAuthMethods[i]->pAltAuthMethod = (PBYTE) IPSecAllocPolMem(IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize);
|
|
memcpy(pRule->ppAuthMethods[i]->pAltAuthMethod, IpsecIkePol.AuthInfos.pAuthenticationInfo[i].pAuthInfo, IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize);
|
|
|
|
hrReturn = CM_DecodeName(pRule->ppAuthMethods[i]->pAltAuthMethod, pRule->ppAuthMethods[i]->dwAltAuthLen, &pTemp);
|
|
assert(hrReturn == ERROR_SUCCESS);
|
|
pRule->ppAuthMethods[i]->pszAuthMethod = IPSecAllocPolStr(pTemp);
|
|
pRule->ppAuthMethods[i]->dwAuthLen = wcslen(pRule->ppAuthMethods[i]->pszAuthMethod);
|
|
delete[] pTemp;
|
|
}
|
|
else
|
|
{
|
|
pRule->ppAuthMethods[i]->dwAuthLen = IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize / sizeof(WCHAR);
|
|
pRule->ppAuthMethods[i]->pszAuthMethod = (LPWSTR) IPSecAllocPolMem(IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize + sizeof(WCHAR));
|
|
memcpy(pRule->ppAuthMethods[i]->pszAuthMethod, IpsecIkePol.AuthInfos.pAuthenticationInfo[i].pAuthInfo, IpsecIkePol.AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize);
|
|
// add trailing '\0' - this is requirement for the polstore
|
|
pRule->ppAuthMethods[i]->pszAuthMethod[pRule->ppAuthMethods[i]->dwAuthLen] = 0;
|
|
|
|
pRule->ppAuthMethods[i]->dwAltAuthLen = 0;
|
|
pRule->ppAuthMethods[i]->pAltAuthMethod = 0;
|
|
}
|
|
}
|
|
|
|
return pRule;
|
|
}
|
|
|
|
// does not commit it to the storage
|
|
// it is assumed that action is NEGOTIATE_SECURITY. If that's not true, it'll be corrected in MakeRule call
|
|
// Soft SA flag is handled here
|
|
PIPSEC_NEGPOL_DATA
|
|
IPSECPolicyToStorage::MakeNegotiationPolicy(IPSEC_QM_POLICY IpsPol,
|
|
LPWSTR Name)
|
|
{
|
|
RPC_STATUS RpcStat;
|
|
int i;
|
|
PIPSEC_NEGPOL_DATA pNegPol = (PIPSEC_NEGPOL_DATA) IPSecAllocPolMem(sizeof(IPSEC_NEGPOL_DATA));
|
|
BOOL bPFS = FALSE;
|
|
WCHAR pFAName[POTF_MAX_STRLEN];
|
|
|
|
RpcStat = UuidCreate(&(pNegPol->NegPolIdentifier));
|
|
assert(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY);
|
|
pNegPol->NegPolAction = GUID_NEGOTIATION_ACTION_NORMAL_IPSEC;
|
|
pNegPol->NegPolType = GUID_NEGOTIATION_TYPE_STANDARD;
|
|
pNegPol->dwSecurityMethodCount = IpsPol.dwOfferCount;
|
|
if (IpsPol.dwFlags & IPSEC_QM_POLICY_ALLOW_SOFT)
|
|
{
|
|
// we need to add one more offer with no security algorithms
|
|
pNegPol->dwSecurityMethodCount++;
|
|
}
|
|
|
|
// allocate sec.methods
|
|
pNegPol->pIpsecSecurityMethods = (IPSEC_SECURITY_METHOD *) IPSecAllocPolMem(pNegPol->dwSecurityMethodCount * sizeof(IPSEC_SECURITY_METHOD));
|
|
// fix up PFS, in storage it is the property of the filter action, not individual offer
|
|
for (i = 0; i < (int) IpsPol.dwOfferCount; i++)
|
|
{
|
|
if (IpsPol.pOffers[i].bPFSRequired)
|
|
{
|
|
bPFS = TRUE;
|
|
}
|
|
}
|
|
|
|
// handle sec.methods
|
|
for (i = 0; i < (int) IpsPol.dwOfferCount; i++)
|
|
{
|
|
int j;
|
|
|
|
pNegPol->pIpsecSecurityMethods[i].Lifetime.KeyExpirationBytes = IpsPol.pOffers[i].Lifetime.uKeyExpirationKBytes;
|
|
pNegPol->pIpsecSecurityMethods[i].Lifetime.KeyExpirationTime = IpsPol.pOffers[i].Lifetime.uKeyExpirationTime;
|
|
pNegPol->pIpsecSecurityMethods[i].Flags = 0;
|
|
pNegPol->pIpsecSecurityMethods[i].PfsQMRequired = bPFS;
|
|
pNegPol->pIpsecSecurityMethods[i].Count = IpsPol.pOffers[i].dwNumAlgos;
|
|
for (j = 0; j < (int) pNegPol->pIpsecSecurityMethods[i].Count && j < QM_MAX_ALGOS; j++)
|
|
{
|
|
pNegPol->pIpsecSecurityMethods[i].Algos[j].algoIdentifier = IpsPol.pOffers[i].Algos[j].uAlgoIdentifier;
|
|
pNegPol->pIpsecSecurityMethods[i].Algos[j].secondaryAlgoIdentifier = IpsPol.pOffers[i].Algos[j].uSecAlgoIdentifier;
|
|
pNegPol->pIpsecSecurityMethods[i].Algos[j].algoKeylen = IpsPol.pOffers[i].Algos[j].uAlgoKeyLen;
|
|
pNegPol->pIpsecSecurityMethods[i].Algos[j].algoRounds = IpsPol.pOffers[i].Algos[j].uAlgoRounds;
|
|
switch (IpsPol.pOffers[i].Algos[j].Operation)
|
|
{
|
|
case AUTHENTICATION:
|
|
pNegPol->pIpsecSecurityMethods[i].Algos[j].operation = Auth;
|
|
break;
|
|
case ENCRYPTION:
|
|
pNegPol->pIpsecSecurityMethods[i].Algos[j].operation = Encrypt;
|
|
break;
|
|
default:
|
|
pNegPol->pIpsecSecurityMethods[i].Algos[j].operation = None;
|
|
}
|
|
}
|
|
}
|
|
// add soft
|
|
if (IpsPol.dwFlags & IPSEC_QM_POLICY_ALLOW_SOFT)
|
|
{
|
|
// set Count (and everything) to 0
|
|
memset(&(pNegPol->pIpsecSecurityMethods[pNegPol->dwSecurityMethodCount - 1]), 0, sizeof(IPSEC_SECURITY_METHOD));
|
|
}
|
|
|
|
// name
|
|
swprintf(pFAName, TEXT("%s filter action"), Name);
|
|
pNegPol->pszIpsecName = IPSecAllocPolStr(pFAName);
|
|
pNegPol->pszDescription = NULL;
|
|
return pNegPol;
|
|
}
|
|
|
|
|
|
PIPSEC_FILTER_DATA
|
|
IPSECPolicyToStorage::MakeFilters(
|
|
T2P_FILTER *Filters,
|
|
UINT NumFilters,
|
|
LPWSTR Name)
|
|
{
|
|
RPC_STATUS RpcStat;
|
|
PIPSEC_FILTER_DATA pFilter = (PIPSEC_FILTER_DATA) IPSecAllocPolMem(sizeof(IPSEC_FILTER_DATA));
|
|
int i;
|
|
WCHAR pFLName[POTF_MAX_STRLEN];
|
|
|
|
RpcStat = UuidCreate(&(pFilter->FilterIdentifier));
|
|
assert(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY);
|
|
|
|
pFilter->dwNumFilterSpecs = NumFilters;
|
|
pFilter->ppFilterSpecs = (PIPSEC_FILTER_SPEC *) IPSecAllocPolMem(NumFilters*sizeof(PIPSEC_FILTER_SPEC));
|
|
assert(pFilter->ppFilterSpecs);
|
|
|
|
for (i = 0; i < (int) NumFilters; i++)
|
|
{
|
|
pFilter->ppFilterSpecs[i] = (PIPSEC_FILTER_SPEC) IPSecAllocPolMem(sizeof(IPSEC_FILTER_SPEC));
|
|
assert(pFilter->ppFilterSpecs[i]);
|
|
ConvertFilter(Filters[i], *(pFilter->ppFilterSpecs[i]));
|
|
}
|
|
|
|
pFilter->dwWhenChanged = 0;
|
|
swprintf(pFLName, TEXT("%s filter list"), Name);
|
|
pFilter->pszIpsecName = IPSecAllocPolStr(pFLName);
|
|
pFilter->pszDescription = NULL;
|
|
|
|
return pFilter;
|
|
}
|
|
|
|
HRESULT
|
|
IPSECPolicyToStorage::SetISAKMPPolicy(IPSEC_MM_POLICY IkePol)
|
|
{
|
|
HRESULT hrReturn = S_OK;
|
|
RPC_STATUS RpcStat;
|
|
GUID oldISAKMP;
|
|
int i;
|
|
|
|
if (!IsOpen())
|
|
{
|
|
return ERROR_ACCESS_DENIED;
|
|
}
|
|
|
|
oldISAKMP = myIPSECPolicy->ISAKMPIdentifier;
|
|
if (myIPSECPolicy->pIpsecISAKMPData)
|
|
{
|
|
IPSecFreeISAKMPData(myIPSECPolicy->pIpsecISAKMPData);
|
|
}
|
|
|
|
RpcStat = UuidCreate(&(myIPSECPolicy->ISAKMPIdentifier));
|
|
assert(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY);
|
|
|
|
myIPSECPolicy->pIpsecISAKMPData = (PIPSEC_ISAKMP_DATA) IPSecAllocPolMem(sizeof(IPSEC_ISAKMP_DATA));
|
|
|
|
myIPSECPolicy->pIpsecISAKMPData->ISAKMPIdentifier = myIPSECPolicy->ISAKMPIdentifier;
|
|
myIPSECPolicy->pIpsecISAKMPData->dwWhenChanged = 0;
|
|
|
|
// sec methods stuff
|
|
myIPSECPolicy->pIpsecISAKMPData->dwNumISAKMPSecurityMethods = IkePol.dwOfferCount;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods = (PCRYPTO_BUNDLE) IPSecAllocPolMem(sizeof(CRYPTO_BUNDLE)*IkePol.dwOfferCount);
|
|
for (i = 0; i < (int) IkePol.dwOfferCount; i++)
|
|
{
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].MajorVersion = 0;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].MinorVersion = 0;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].AuthenticationMethod = 0;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].PseudoRandomFunction.AlgorithmIdentifier = 0;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].PseudoRandomFunction.KeySize = 0;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].PseudoRandomFunction.Rounds = 0;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].PfsIdentityRequired = (IkePol.pOffers[i].dwQuickModeLimit == 1);
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].EncryptionAlgorithm.AlgorithmIdentifier = IkePol.pOffers[i].EncryptionAlgorithm.uAlgoIdentifier;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].EncryptionAlgorithm.KeySize = IkePol.pOffers[i].EncryptionAlgorithm.uAlgoKeyLen;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].EncryptionAlgorithm.Rounds = IkePol.pOffers[i].EncryptionAlgorithm.uAlgoRounds;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].HashAlgorithm.AlgorithmIdentifier = IkePol.pOffers[i].HashingAlgorithm.uAlgoIdentifier;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].HashAlgorithm.KeySize = IkePol.pOffers[i].HashingAlgorithm.uAlgoKeyLen;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].HashAlgorithm.Rounds = IkePol.pOffers[i].HashingAlgorithm.uAlgoRounds;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].OakleyGroup = IkePol.pOffers[i].dwDHGroup;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].QuickModeLimit = IkePol.pOffers[i].dwQuickModeLimit;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].Lifetime.KBytes = IkePol.pOffers[i].Lifetime.uKeyExpirationKBytes;
|
|
myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[i].Lifetime.Seconds = IkePol.pOffers[i].Lifetime.uKeyExpirationTime;
|
|
}
|
|
|
|
// now for other stuff - ISAKMPPolicy
|
|
myIPSECPolicy->pIpsecISAKMPData->ISAKMPPolicy.PolicyId = myIPSECPolicy->ISAKMPIdentifier;
|
|
myIPSECPolicy->pIpsecISAKMPData->ISAKMPPolicy.IdentityProtectionRequired = 0;
|
|
myIPSECPolicy->pIpsecISAKMPData->ISAKMPPolicy.PfsIdentityRequired = myIPSECPolicy->pIpsecISAKMPData->pSecurityMethods[0].PfsIdentityRequired;
|
|
|
|
// save it
|
|
hrReturn = IPSecCreateISAKMPData(myPolicyStorage, myIPSECPolicy->pIpsecISAKMPData);
|
|
if (hrReturn != ERROR_SUCCESS)
|
|
{
|
|
return hrReturn;
|
|
}
|
|
|
|
if (IsPolicyInStorage())
|
|
{
|
|
IPSecSetPolicyData(myPolicyStorage, myIPSECPolicy);
|
|
}
|
|
else
|
|
{
|
|
TryToCreatePolicy();
|
|
}
|
|
|
|
IPSecDeleteISAKMPData(myPolicyStorage, oldISAKMP);
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
LPVOID
|
|
IPSECPolicyToStorage::ReallocPolMem(
|
|
LPVOID pOldMem,
|
|
DWORD cbOld,
|
|
DWORD cbNew
|
|
)
|
|
{
|
|
LPVOID pNewMem;
|
|
|
|
pNewMem=IPSecAllocPolMem(cbNew);
|
|
|
|
if (pOldMem && pNewMem) {
|
|
memcpy(pNewMem, pOldMem, min(cbNew, cbOld));
|
|
IPSecFreePolMem(pOldMem);
|
|
}
|
|
|
|
return pNewMem;
|
|
}
|
|
|
|
// forms a rule but doesn't commit it
|
|
// forms default response rule
|
|
PIPSEC_NFA_DATA
|
|
IPSECPolicyToStorage::MakeDefaultResponseRule ()
|
|
{
|
|
RPC_STATUS RpcStat;
|
|
PIPSEC_NFA_DATA pRule = (PIPSEC_NFA_DATA) IPSecAllocPolMem(sizeof(IPSEC_NFA_DATA));
|
|
|
|
assert(pRule);
|
|
pRule->pszIpsecName = pRule->pszDescription = pRule->pszInterfaceName = pRule->pszEndPointName = NULL;
|
|
RpcStat = UuidCreate(&(pRule->NFAIdentifier));
|
|
assert(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY);
|
|
pRule->dwWhenChanged = 0;
|
|
|
|
// filter list
|
|
pRule->pIpsecFilterData = NULL;
|
|
UuidCreateNil(&(pRule->FilterIdentifier));
|
|
|
|
// filter action
|
|
pRule->pIpsecNegPolData = MakeDefaultResponseNegotiationPolicy ();
|
|
|
|
pRule->NegPolIdentifier = pRule->pIpsecNegPolData->NegPolIdentifier;
|
|
|
|
// tunnel address
|
|
pRule->dwTunnelFlags = 0;
|
|
|
|
// interface type
|
|
pRule->dwInterfaceType = PAS_INTERFACE_TYPE_ALL;
|
|
|
|
// active flag
|
|
pRule->dwActiveFlag = FALSE;
|
|
|
|
// auth methods
|
|
pRule->dwAuthMethodCount = 1;
|
|
pRule->ppAuthMethods = (PIPSEC_AUTH_METHOD *) IPSecAllocPolMem(pRule->dwAuthMethodCount * sizeof(PIPSEC_AUTH_METHOD));
|
|
assert(pRule->ppAuthMethods);
|
|
pRule->ppAuthMethods[0] = (PIPSEC_AUTH_METHOD) IPSecAllocPolMem(sizeof(IPSEC_AUTH_METHOD));
|
|
pRule->ppAuthMethods[0]->dwAuthType = IKE_SSPI;
|
|
pRule->ppAuthMethods[0]->dwAuthLen = 0;
|
|
pRule->ppAuthMethods[0]->pszAuthMethod = NULL;
|
|
|
|
return pRule;
|
|
}
|
|
|
|
// does not commit it to the storage
|
|
PIPSEC_NEGPOL_DATA
|
|
IPSECPolicyToStorage::MakeDefaultResponseNegotiationPolicy ( )
|
|
{
|
|
RPC_STATUS RpcStat;
|
|
int i;
|
|
PIPSEC_NEGPOL_DATA pNegPol = (PIPSEC_NEGPOL_DATA) IPSecAllocPolMem(sizeof(IPSEC_NEGPOL_DATA));
|
|
WCHAR pFAName[POTF_MAX_STRLEN];
|
|
|
|
RpcStat = UuidCreate(&(pNegPol->NegPolIdentifier));
|
|
assert(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY);
|
|
pNegPol->NegPolAction = GUID_NEGOTIATION_ACTION_NORMAL_IPSEC;
|
|
pNegPol->NegPolType = GUID_NEGOTIATION_TYPE_DEFAULT;
|
|
pNegPol->dwSecurityMethodCount = 6;
|
|
|
|
// allocate sec.methods
|
|
pNegPol->pIpsecSecurityMethods = (IPSEC_SECURITY_METHOD *) IPSecAllocPolMem(pNegPol->dwSecurityMethodCount * sizeof(IPSEC_SECURITY_METHOD));
|
|
|
|
// method 0 - ESP[3DES, SHA1]
|
|
pNegPol->pIpsecSecurityMethods[0].Lifetime.KeyExpirationBytes = 0;
|
|
pNegPol->pIpsecSecurityMethods[0].Lifetime.KeyExpirationTime = 0;
|
|
pNegPol->pIpsecSecurityMethods[0].Flags = 0;
|
|
pNegPol->pIpsecSecurityMethods[0].PfsQMRequired = FALSE;
|
|
pNegPol->pIpsecSecurityMethods[0].Count = 1;
|
|
pNegPol->pIpsecSecurityMethods[0].Algos[0].algoIdentifier = IPSEC_DOI_ESP_3_DES;
|
|
pNegPol->pIpsecSecurityMethods[0].Algos[0].secondaryAlgoIdentifier = IPSEC_DOI_AH_SHA1;
|
|
pNegPol->pIpsecSecurityMethods[0].Algos[0].algoKeylen = 0;
|
|
pNegPol->pIpsecSecurityMethods[0].Algos[0].algoRounds = 0;
|
|
pNegPol->pIpsecSecurityMethods[0].Algos[0].operation = Encrypt;
|
|
|
|
// method 1 - ESP[3DES, MD5]
|
|
pNegPol->pIpsecSecurityMethods[1].Lifetime.KeyExpirationBytes = 0;
|
|
pNegPol->pIpsecSecurityMethods[1].Lifetime.KeyExpirationTime = 0;
|
|
pNegPol->pIpsecSecurityMethods[1].Flags = 0;
|
|
pNegPol->pIpsecSecurityMethods[1].PfsQMRequired = FALSE;
|
|
pNegPol->pIpsecSecurityMethods[1].Count = 1;
|
|
pNegPol->pIpsecSecurityMethods[1].Algos[0].algoIdentifier = IPSEC_DOI_ESP_3_DES;
|
|
pNegPol->pIpsecSecurityMethods[1].Algos[0].secondaryAlgoIdentifier = IPSEC_DOI_AH_MD5;
|
|
pNegPol->pIpsecSecurityMethods[1].Algos[0].algoKeylen = 0;
|
|
pNegPol->pIpsecSecurityMethods[1].Algos[0].algoRounds = 0;
|
|
pNegPol->pIpsecSecurityMethods[1].Algos[0].operation = Encrypt;
|
|
|
|
// method 2 - ESP[DES, SHA1]
|
|
pNegPol->pIpsecSecurityMethods[2].Lifetime.KeyExpirationBytes = 0;
|
|
pNegPol->pIpsecSecurityMethods[2].Lifetime.KeyExpirationTime = 0;
|
|
pNegPol->pIpsecSecurityMethods[2].Flags = 0;
|
|
pNegPol->pIpsecSecurityMethods[2].PfsQMRequired = FALSE;
|
|
pNegPol->pIpsecSecurityMethods[2].Count = 1;
|
|
pNegPol->pIpsecSecurityMethods[2].Algos[0].algoIdentifier = IPSEC_DOI_ESP_DES;
|
|
pNegPol->pIpsecSecurityMethods[2].Algos[0].secondaryAlgoIdentifier = IPSEC_DOI_AH_SHA1;
|
|
pNegPol->pIpsecSecurityMethods[2].Algos[0].algoKeylen = 0;
|
|
pNegPol->pIpsecSecurityMethods[2].Algos[0].algoRounds = 0;
|
|
pNegPol->pIpsecSecurityMethods[2].Algos[0].operation = Encrypt;
|
|
|
|
// method 3 - ESP[DES, MD5]
|
|
pNegPol->pIpsecSecurityMethods[3].Lifetime.KeyExpirationBytes = 0;
|
|
pNegPol->pIpsecSecurityMethods[3].Lifetime.KeyExpirationTime = 0;
|
|
pNegPol->pIpsecSecurityMethods[3].Flags = 0;
|
|
pNegPol->pIpsecSecurityMethods[3].PfsQMRequired = FALSE;
|
|
pNegPol->pIpsecSecurityMethods[3].Count = 1;
|
|
pNegPol->pIpsecSecurityMethods[3].Algos[0].algoIdentifier = IPSEC_DOI_ESP_DES;
|
|
pNegPol->pIpsecSecurityMethods[3].Algos[0].secondaryAlgoIdentifier = IPSEC_DOI_AH_MD5;
|
|
pNegPol->pIpsecSecurityMethods[3].Algos[0].algoKeylen = 0;
|
|
pNegPol->pIpsecSecurityMethods[3].Algos[0].algoRounds = 0;
|
|
pNegPol->pIpsecSecurityMethods[3].Algos[0].operation = Encrypt;
|
|
|
|
// method 4 - AH[SHA1]
|
|
pNegPol->pIpsecSecurityMethods[4].Lifetime.KeyExpirationBytes = 0;
|
|
pNegPol->pIpsecSecurityMethods[4].Lifetime.KeyExpirationTime = 0;
|
|
pNegPol->pIpsecSecurityMethods[4].Flags = 0;
|
|
pNegPol->pIpsecSecurityMethods[4].PfsQMRequired = FALSE;
|
|
pNegPol->pIpsecSecurityMethods[4].Count = 1;
|
|
pNegPol->pIpsecSecurityMethods[4].Algos[0].algoIdentifier = IPSEC_DOI_AH_SHA1;
|
|
pNegPol->pIpsecSecurityMethods[4].Algos[0].secondaryAlgoIdentifier = IPSEC_DOI_AH_NONE;
|
|
pNegPol->pIpsecSecurityMethods[4].Algos[0].algoKeylen = 0;
|
|
pNegPol->pIpsecSecurityMethods[4].Algos[0].algoRounds = 0;
|
|
pNegPol->pIpsecSecurityMethods[4].Algos[0].operation = Auth;
|
|
|
|
// method 5 - AH[MD5]
|
|
pNegPol->pIpsecSecurityMethods[5].Lifetime.KeyExpirationBytes = 0;
|
|
pNegPol->pIpsecSecurityMethods[5].Lifetime.KeyExpirationTime = 0;
|
|
pNegPol->pIpsecSecurityMethods[5].Flags = 0;
|
|
pNegPol->pIpsecSecurityMethods[5].PfsQMRequired = FALSE;
|
|
pNegPol->pIpsecSecurityMethods[5].Count = 1;
|
|
pNegPol->pIpsecSecurityMethods[5].Algos[0].algoIdentifier = IPSEC_DOI_AH_MD5;
|
|
pNegPol->pIpsecSecurityMethods[5].Algos[0].secondaryAlgoIdentifier = IPSEC_DOI_AH_NONE;
|
|
pNegPol->pIpsecSecurityMethods[5].Algos[0].algoKeylen = 0;
|
|
pNegPol->pIpsecSecurityMethods[5].Algos[0].algoRounds = 0;
|
|
pNegPol->pIpsecSecurityMethods[5].Algos[0].operation = Auth;
|
|
|
|
// name
|
|
swprintf(pFAName, TEXT(""));
|
|
pNegPol->pszIpsecName = IPSecAllocPolStr(pFAName);
|
|
pNegPol->pszDescription = NULL;
|
|
return pNegPol;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|