Leaked source code of windows server 2003
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.
 
 
 
 
 
 

4430 lines
122 KiB

////////////////////////////////////////////////////////////
// Module : Static/Staticadd.cpp
//
// Purpose : Static Add Implementation.
//
// Developers Name : Surya
//
// History :
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
#include "nshipsec.h"
extern HINSTANCE g_hModule;
extern CNshPolStore g_NshPolStoreHandle;
extern STORAGELOCATION g_StorageLocation;
extern CNshPolNegFilData g_NshPolNegFilData;
////////////////////////////////////////////////////////////
//
//Function: HandleStaticAddPolicy()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN LPCWSTR pwszMachine,
// IN OUT LPWSTR *ppwcArguments,
// IN DWORD dwCurrentIndex,
// IN DWORD dwArgCount,
// IN DWORD dwFlags,
// IN LPCVOID pvData,
// OUT BOOL *pbDone
//
//Return: DWORD
//
//Description:
// Implementation for the command "Add Policy"
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD WINAPI
HandleStaticAddPolicy(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
LPTSTR pszMachineName=NULL;
DWORD dwReturn=ERROR_SUCCESS;
DWORD dwReturnCode = ERROR_SHOW_USAGE;
PPOLICYDATA pPolicyData=NULL;
PARSER_PKT parser;
ZeroMemory(&parser, sizeof(parser));
const TAG_TYPE vcmdStaticAddPolicy[] =
{
{ CMD_TOKEN_STR_NAME, NS_REQ_PRESENT, FALSE },
{ CMD_TOKEN_STR_DESCR, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_MMPFS, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_QMPERMM, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_MMLIFETIME, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_ACTIVATEDEFRULE,NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_PI, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_ASSIGN, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_MMSECMETHODS, NS_REQ_ZERO, FALSE }
};
const TOKEN_VALUE vtokStaticAddPolicy[] =
{
{ CMD_TOKEN_STR_NAME, CMD_TOKEN_NAME },
{ CMD_TOKEN_STR_DESCR, CMD_TOKEN_DESCR },
{ CMD_TOKEN_STR_MMPFS, CMD_TOKEN_MMPFS },
{ CMD_TOKEN_STR_QMPERMM, CMD_TOKEN_QMPERMM },
{ CMD_TOKEN_STR_MMLIFETIME, CMD_TOKEN_MMLIFETIME },
{ CMD_TOKEN_STR_ACTIVATEDEFRULE,CMD_TOKEN_ACTIVATEDEFRULE },
{ CMD_TOKEN_STR_PI, CMD_TOKEN_PI },
{ CMD_TOKEN_STR_ASSIGN, CMD_TOKEN_ASSIGN },
{ CMD_TOKEN_STR_MMSECMETHODS, CMD_TOKEN_MMSECMETHODS }
};
//if the user asked for usage, delegate the responsibility to netsh
if(dwArgCount <= 3)
{
dwReturnCode = ERROR_SHOW_USAGE;
BAIL_OUT;
}
parser.ValidTok = vtokStaticAddPolicy;
parser.MaxTok = SIZEOF_TOKEN_VALUE(vtokStaticAddPolicy);
parser.ValidCmd = vcmdStaticAddPolicy;
parser.MaxCmd = SIZEOF_TAG_TYPE(vcmdStaticAddPolicy);
dwReturnCode = Parser(pwszMachine,ppwcArguments,dwCurrentIndex,dwArgCount,&parser);
if(dwReturnCode != ERROR_SUCCESS)
{
CleanUp();
if (dwReturnCode == RETURN_NO_ERROR)
{
dwReturnCode = ERROR_SUCCESS;
}
BAIL_OUT;
}
//Get the User specified info into local structure
dwReturn = FillAddPolicyInfo(&pPolicyData,parser,vtokStaticAddPolicy);
if(dwReturn==ERROR_OUTOFMEMORY)
{
PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
dwReturnCode=ERROR_SUCCESS;
BAIL_OUT;
}
if (!pPolicyData->pszPolicyName || (pPolicyData->pszPolicyName[0] == TEXT('\0')) )
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_POLICY_MISSING_POL_NAME);
dwReturnCode=ERROR_SHOW_USAGE;
BAIL_OUT;
}
// check the limits of variables
if(pPolicyData->bPollIntervalSpecified && !IsWithinLimit(pPolicyData->dwPollInterval/60,POLLING_Min_MIN,POLLING_Min_MAX))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_POLICY_POLL_INTERVAL_MSG,POLLING_Min_MIN,POLLING_Min_MAX);
dwReturnCode=ERROR_SUCCESS;
BAIL_OUT;
}
if(pPolicyData->bQMLimitSpecified && !IsWithinLimit(pPolicyData->dwQMLimit,QMPERMM_MIN,QMPERMM_MAX))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_POLICY_QMPERMM_MSG,QMPERMM_MIN,QMPERMM_MAX);
dwReturnCode=ERROR_SUCCESS;
BAIL_OUT;
}
if(pPolicyData->bLifeTimeInsecondsSpecified && !IsWithinLimit(pPolicyData->LifeTimeInSeconds/60,P1_Min_LIFE_MIN,P1_Min_LIFE_MAX))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_POLICY_LIFETIME_LIMIT_MSG,P1_Min_LIFE_MIN,P1_Min_LIFE_MAX);
dwReturnCode=ERROR_SUCCESS;
BAIL_OUT;
}
if(pPolicyData)
{
dwReturnCode = CreateNewPolicy(pPolicyData);
if(dwReturnCode == ERROR_OUTOFMEMORY)
{
PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
}
else if (dwReturnCode == ERROR_INVALID_PARAMETER)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_STATIC_INTERNAL_ERROR);
}
dwReturnCode=ERROR_SUCCESS;
}
error:
//clean up
CleanUpLocalPolicyDataStructure(pPolicyData);
if (pszMachineName)
{
delete [] pszMachineName;
}
return dwReturnCode;
}
/////////////////////////////////////////////////////////////
//
//Function: CreateNewPolicy()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN PPOLICYDATA pPolicyData
//
//Return: DWORD
//
//Description:
// Creates new policy data structure and calls the API
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
CreateNewPolicy(
IN PPOLICYDATA pPolicyData
)
{
HANDLE hPolicyStorage = NULL;
LPTSTR pszMachineName=NULL;
DWORD dwReturnCode = ERROR_SUCCESS;
PIPSEC_POLICY_DATA pPolicy=NULL,pActive=NULL;
RPC_STATUS RpcStat =RPC_S_OK;
BOOL bExists=FALSE;
// if no offer , fill defaults
if(pPolicyData->dwOfferCount==0)
{
dwReturnCode = LoadIkeDefaults(pPolicyData,&(pPolicyData->pIpSecMMOffer));
BAIL_ON_WIN32_ERROR(dwReturnCode);
}
if(pPolicyData->bPFSSpecified && pPolicyData->bPFS)
{
pPolicyData->dwQMLimit=MMPFS_QM_LIMIT;
}
if(!pPolicyData->bLifeTimeInsecondsSpecified)
{
pPolicyData->LifeTimeInSeconds= P2STORE_DEFAULT_LIFETIME;
}
if(!pPolicyData->bPollIntervalSpecified)
{
pPolicyData->dwPollInterval=P2STORE_DEFAULT_POLLINT;
}
if (pPolicyData->dwOfferCount != 0)
{
for(DWORD i=0;i<pPolicyData->dwOfferCount;i++)
{
pPolicyData->pIpSecMMOffer[i].Lifetime.uKeyExpirationTime=pPolicyData->LifeTimeInSeconds;
pPolicyData->pIpSecMMOffer[i].dwQuickModeLimit=pPolicyData->dwQMLimit;
}
}
if(pPolicyData->pszGPOName)
{
if (g_StorageLocation.dwLocation != IPSEC_DIRECTORY_PROVIDER)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_SET_STATIC_POLICY_GPO_SPECIFIED_ON_NODOMAIN_POLICY);
dwReturnCode= ERROR_SHOW_USAGE;
BAIL_OUT;
}
}
// this wrapper function is for cache
dwReturnCode = OpenPolicyStore(&hPolicyStorage);
if (dwReturnCode != ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_FAILED_POLSTORE_OPEN);
dwReturnCode = ERROR_SUCCESS;
BAIL_OUT;
}
//check whether the policy exists in cache
if(g_NshPolStoreHandle.GetBatchmodeStatus() && g_NshPolNegFilData.CheckPolicyInCacheByName(pPolicyData->pszPolicyName))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_CRNEWPOL_1,pPolicyData->pszPolicyName);
dwReturnCode=ERROR_INVALID_DATA;
bExists=TRUE;
}
else if (CheckPolicyExistance(hPolicyStorage,pPolicyData->pszPolicyName))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_CRNEWPOL_1,pPolicyData->pszPolicyName);
dwReturnCode=ERROR_INVALID_DATA;
bExists=TRUE;
}
if(!bExists) // if policy not exists, process further
{
pPolicy = (PIPSEC_POLICY_DATA) IPSecAllocPolMem(sizeof(IPSEC_POLICY_DATA));
if (pPolicy == NULL)
{
dwReturnCode=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
pPolicy->pszIpsecName = IPSecAllocPolStr(pPolicyData->pszPolicyName);
if (pPolicy->pszIpsecName == NULL)
{
dwReturnCode=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
if (pPolicyData->pszDescription)
{
pPolicy->pszDescription = IPSecAllocPolStr(pPolicyData->pszDescription);
if (pPolicy->pszDescription == NULL)
{
dwReturnCode=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
}
else
{
pPolicy->pszDescription = NULL;
}
pPolicy->dwPollingInterval = pPolicyData->dwPollInterval;
RpcStat = UuidCreate(&(pPolicy->PolicyIdentifier));
if (!(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY))
{
dwReturnCode=ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
pPolicy->pIpsecISAKMPData = NULL;
pPolicy->ppIpsecNFAData = NULL;
pPolicy->dwNumNFACount = 0;
pPolicy->dwWhenChanged = 0;
RpcStat = UuidCreate(&(pPolicy->ISAKMPIdentifier));
if (!(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY))
{
dwReturnCode=ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
//deal with ISAKMP details
pPolicy->pIpsecISAKMPData = (PIPSEC_ISAKMP_DATA) IPSecAllocPolMem(sizeof(IPSEC_ISAKMP_DATA));
if(pPolicy->pIpsecISAKMPData==NULL)
{
dwReturnCode=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pPolicy->pIpsecISAKMPData,0,sizeof(IPSEC_ISAKMP_DATA));
pPolicy->pIpsecISAKMPData->ISAKMPIdentifier = pPolicy->ISAKMPIdentifier;
pPolicy->pIpsecISAKMPData->dwWhenChanged = 0;
// sec methods details
pPolicy->pIpsecISAKMPData->dwNumISAKMPSecurityMethods = pPolicyData->dwOfferCount;
pPolicy->pIpsecISAKMPData->pSecurityMethods = (PCRYPTO_BUNDLE) IPSecAllocPolMem(sizeof(CRYPTO_BUNDLE)*pPolicyData->dwOfferCount);
if(pPolicy->pIpsecISAKMPData->pSecurityMethods==NULL)
{
dwReturnCode=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
// fill the sec methods
for (DWORD i = 0; i < pPolicyData->dwOfferCount; i++)
{
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].MajorVersion = 0;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].MinorVersion = 0;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].AuthenticationMethod = 0;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].PseudoRandomFunction.AlgorithmIdentifier = 0;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].PseudoRandomFunction.KeySize = 0;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].PseudoRandomFunction.Rounds = 0;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].PfsIdentityRequired = pPolicyData->bPFS;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].EncryptionAlgorithm.AlgorithmIdentifier = pPolicyData->pIpSecMMOffer[i].EncryptionAlgorithm.uAlgoIdentifier;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].EncryptionAlgorithm.KeySize = pPolicyData->pIpSecMMOffer[i].EncryptionAlgorithm.uAlgoKeyLen;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].EncryptionAlgorithm.Rounds = pPolicyData->pIpSecMMOffer[i].EncryptionAlgorithm.uAlgoRounds;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].HashAlgorithm.AlgorithmIdentifier = pPolicyData->pIpSecMMOffer[i].HashingAlgorithm.uAlgoIdentifier;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].HashAlgorithm.KeySize = pPolicyData->pIpSecMMOffer[i].HashingAlgorithm.uAlgoKeyLen;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].HashAlgorithm.Rounds = pPolicyData->pIpSecMMOffer[i].HashingAlgorithm.uAlgoRounds;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].OakleyGroup = pPolicyData->pIpSecMMOffer[i].dwDHGroup;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].QuickModeLimit = pPolicyData->pIpSecMMOffer[i].dwQuickModeLimit;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].Lifetime.KBytes = 0;
pPolicy->pIpsecISAKMPData->pSecurityMethods[i].Lifetime.Seconds = pPolicyData->pIpSecMMOffer[i].Lifetime.uKeyExpirationTime;
}
// now for other details for ISAKMPPolicy
pPolicy->pIpsecISAKMPData->ISAKMPPolicy.PolicyId = pPolicy->ISAKMPIdentifier;
pPolicy->pIpsecISAKMPData->ISAKMPPolicy.IdentityProtectionRequired = 0;
pPolicy->pIpsecISAKMPData->ISAKMPPolicy.PfsIdentityRequired = pPolicy->pIpsecISAKMPData->pSecurityMethods[0].PfsIdentityRequired;
//call the APIs
dwReturnCode = IPSecCreateISAKMPData(hPolicyStorage, pPolicy->pIpsecISAKMPData);
if (dwReturnCode == ERROR_SUCCESS)
{
//add default rule
dwReturnCode=AddDefaultResponseRule(pPolicy,hPolicyStorage,pPolicyData->bActivateDefaultRule,pPolicyData->bActivateDefaultRuleSpecified);
if (dwReturnCode != ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_CRNEWPOL_2);
}
if ( dwReturnCode==ERROR_SUCCESS && pPolicyData->bAssign && (g_StorageLocation.dwLocation!=IPSEC_DIRECTORY_PROVIDER))
{
dwReturnCode = IPSecGetAssignedPolicyData(hPolicyStorage, &pActive);
if ((dwReturnCode == ERROR_SUCCESS)||(dwReturnCode ==ERROR_FILE_NOT_FOUND))
{
dwReturnCode = pActive ? IPSecUnassignPolicy(hPolicyStorage, pActive->PolicyIdentifier) : 0,
IPSecAssignPolicy(hPolicyStorage, pPolicy->PolicyIdentifier);
}
if (pActive)
{
IPSecFreePolicyData(pActive);
}
dwReturnCode = ERROR_SUCCESS;
}
if(dwReturnCode != ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_CRNEWPOL_4,pPolicy->pszIpsecName);
}
}
else
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_CRNEWPOL_4,pPolicy->pszIpsecName);
}
}
if (hPolicyStorage)
{
ClosePolicyStore(hPolicyStorage);
}
if(pPolicy)
{
FreePolicyData(pPolicy);
}
if(pszMachineName)
{
delete [] pszMachineName;
}
error:
if(dwReturnCode == ERROR_OUTOFMEMORY)
{
CleanUpPolicy(pPolicy);
}
return dwReturnCode;
}
////////////////////////////////////////////////////////////
//
//Function: FillAddPolicyInfo( )
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// OUT PPOLICYDATA* ppFilter,
// IN PARSER_PKT & parser,
// IN const TOKEN_VALUE *vtokStaticAddPolicy
//
//Return: DWORD
//
//Description:
// This function fills the local structure with the information got from the parser.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
FillAddPolicyInfo(
OUT PPOLICYDATA* ppPolicyData,
IN PARSER_PKT & parser,
IN const TOKEN_VALUE *vtokStaticAddPolicy
)
{
DWORD dwCount=0,dwReturn=ERROR_SUCCESS, dwStrLength = 0;
PPOLICYDATA pPolicyData=new POLICYDATA;
if(pPolicyData == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pPolicyData,0,sizeof(POLICYDATA));
for(dwCount=0;dwCount<parser.MaxTok;dwCount++)
{
switch(vtokStaticAddPolicy[parser.Cmd[dwCount].dwCmdToken].dwValue)
{
case CMD_TOKEN_NAME :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pPolicyData->pszPolicyName = new _TCHAR[dwStrLength+1];
if(pPolicyData->pszPolicyName == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pPolicyData->pszPolicyName, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_DESCR :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pPolicyData->pszDescription = new _TCHAR[dwStrLength+1];
if(pPolicyData->pszDescription == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pPolicyData->pszDescription, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_MMPFS :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pPolicyData->bPFSSpecified=TRUE;
pPolicyData->bPFS = *(BOOL *)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_ACTIVATEDEFRULE :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pPolicyData->bActivateDefaultRule = *(BOOL *)parser.Cmd[dwCount].pArg;
pPolicyData->bActivateDefaultRuleSpecified=TRUE;
}
break;
case CMD_TOKEN_ASSIGN :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pPolicyData->bAssign = *(BOOL *)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_MMLIFETIME :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pPolicyData->LifeTimeInSeconds= *(ULONG *)parser.Cmd[dwCount].pArg * 60;
pPolicyData->bLifeTimeInsecondsSpecified=TRUE;
}
break;
case CMD_TOKEN_QMPERMM :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pPolicyData->dwQMLimit= *(DWORD *)parser.Cmd[dwCount].pArg;
pPolicyData->bQMLimitSpecified=TRUE;
}
break;
case CMD_TOKEN_PI :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pPolicyData->dwPollInterval= *(DWORD *)parser.Cmd[dwCount].pArg * 60;
pPolicyData->bPollIntervalSpecified=TRUE;
}
break;
case CMD_TOKEN_CERTTOMAP :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pPolicyData->bCertToAccMappingSpecified = TRUE;
pPolicyData->bCertToAccMapping = *(BOOL *)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_MMSECMETHODS :
if (parser.Cmd[dwCount].dwStatus > 0)
{
pPolicyData->dwOfferCount=parser.Cmd[dwCount].dwStatus;
pPolicyData->pIpSecMMOffer = new IPSEC_MM_OFFER[pPolicyData->dwOfferCount];
if(pPolicyData->pIpSecMMOffer == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pPolicyData->pIpSecMMOffer, 0, sizeof(IPSEC_MM_OFFER) * pPolicyData->dwOfferCount);
for(DWORD j=0;j<(parser.Cmd[dwCount].dwStatus);j++)
{
if ( ((IPSEC_MM_OFFER **)parser.Cmd[dwCount].pArg)[j] )
{
memcpy( &(pPolicyData->pIpSecMMOffer[j]),((IPSEC_MM_OFFER **)parser.Cmd[dwCount].pArg)[j],sizeof(IPSEC_MM_OFFER));
}
}
}
break;
default :
break;
}
}
error:
*ppPolicyData=pPolicyData;
CleanUp();
return dwReturn;
}
////////////////////////////////////////////////////////////
//
//Function: HandleStaticAddFilterList()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN LPCWSTR pwszMachine,
// IN OUT LPWSTR *ppwcArguments,
// IN DWORD dwCurrentIndex,
// IN DWORD dwArgCount,
// IN DWORD dwFlags,
// IN LPCVOID pvData,
// OUT BOOL *pbDone
//
//Return: DWORD
//
//Description:
// Implementation for the command "Add FilterList"
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD WINAPI
HandleStaticAddFilterList(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
LPTSTR pszFLName=NULL,pszFLDescription=NULL;
DWORD dwCount=0,dwRet = ERROR_SHOW_USAGE, dwStrLength = 0;
HANDLE hPolicyStorage = NULL;
BOOL bFilterExists=FALSE;
DWORD dwReturnCode = ERROR_SHOW_USAGE;
PARSER_PKT parser;
ZeroMemory(&parser, sizeof(parser));
const TAG_TYPE vcmdStaticAddFilterList[] =
{
{ CMD_TOKEN_STR_NAME, NS_REQ_PRESENT, FALSE },
{ CMD_TOKEN_STR_DESCR, NS_REQ_ZERO, FALSE }
};
const TOKEN_VALUE vtokStaticAddFilterList[] =
{
{ CMD_TOKEN_STR_NAME, CMD_TOKEN_NAME },
{ CMD_TOKEN_STR_DESCR, CMD_TOKEN_DESCR }
};
//if the user asked for usage, delegate the responsibility to netsh
if(dwArgCount <= 3)
{
dwReturnCode = ERROR_SHOW_USAGE;
BAIL_OUT;
}
parser.ValidTok = vtokStaticAddFilterList;
parser.MaxTok = SIZEOF_TOKEN_VALUE(vtokStaticAddFilterList);
parser.ValidCmd = vcmdStaticAddFilterList;
parser.MaxCmd = SIZEOF_TAG_TYPE(vcmdStaticAddFilterList);
//call the parser to parse the user input
dwReturnCode = Parser(pwszMachine,ppwcArguments,dwCurrentIndex,dwArgCount,&parser);
if(dwReturnCode != ERROR_SUCCESS)
{
CleanUp();
if (dwReturnCode==RETURN_NO_ERROR)
{
dwReturnCode = ERROR_SUCCESS;
}
BAIL_OUT;
}
// get the parsed input
for(dwCount=0;dwCount<parser.MaxTok;dwCount++)
{
switch(vtokStaticAddFilterList[parser.Cmd[dwCount].dwCmdToken].dwValue)
{
case CMD_TOKEN_NAME :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pszFLName = new _TCHAR[dwStrLength+1];
if(pszFLName == NULL)
{
dwRet=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pszFLName, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_DESCR :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pszFLDescription = new _TCHAR[dwStrLength+1];
if(pszFLDescription == NULL)
{
dwRet=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pszFLDescription, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
default :
break;
}
}
CleanUp();
//in no name , bail out
if(!pszFLName)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTERLIST_1);
BAIL_OUT;
}
dwReturnCode = OpenPolicyStore(&hPolicyStorage);
if (dwReturnCode != ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_FAILED_POLSTORE_OPEN);
dwReturnCode=ERROR_SUCCESS;
BAIL_OUT;
}
//check if policy already exists
if(g_NshPolStoreHandle.GetBatchmodeStatus() && g_NshPolNegFilData.CheckFilterListInCacheByName(pszFLName))
{
bFilterExists=TRUE;
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTERLIST_2,pszFLName);
}
else
{
bFilterExists = CheckFilterListExistance(hPolicyStorage,pszFLName);
if(bFilterExists)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTERLIST_2,pszFLName);
}
}
if(!bFilterExists) //if not exists , proceed further
{
dwReturnCode=CreateNewFilterList(hPolicyStorage,pszFLName,pszFLDescription);
if (dwReturnCode == ERROR_INVALID_PARAMETER)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_STATIC_INTERNAL_ERROR);
dwReturnCode=ERROR_SUCCESS;
}
else if(dwReturnCode != ERROR_OUTOFMEMORY)
{
dwReturnCode=ERROR_SUCCESS;
}
}
ClosePolicyStore(hPolicyStorage);
error: //clean up routines
if(dwReturnCode == ERROR_OUTOFMEMORY)
{
dwReturnCode = ERROR_SUCCESS;
PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
}
if (pszFLName)
{
delete [] pszFLName;
}
if (pszFLDescription)
{
delete [] pszFLDescription;
}
return dwReturnCode;
}
////////////////////////////////////////////////////////////
//
//Function: CreateNewFilterList()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN HANDLE hPolicyStorage,
// IN LPTSTR pszFLName,
// IN LPTSTR pszFLDescription
//
//Return: DWORD
//
//Description:
// This function creates a new empty filter list
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
CreateNewFilterList(
IN HANDLE hPolicyStorage,
IN LPTSTR pszFLName,
IN LPTSTR pszFLDescription
)
{
DWORD dwReturnCode = ERROR_SUCCESS;
RPC_STATUS RpcStat =RPC_S_OK;
PIPSEC_FILTER_DATA pFilterData = (PIPSEC_FILTER_DATA) IPSecAllocPolMem(sizeof(IPSEC_FILTER_DATA));
if(pFilterData==NULL)
{
dwReturnCode = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
RpcStat = UuidCreate(&(pFilterData->FilterIdentifier));
if (!(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY))
{
dwReturnCode=ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
pFilterData->dwNumFilterSpecs = 0;
pFilterData->ppFilterSpecs = NULL;
pFilterData->dwWhenChanged = 0;
//fill the name and desc
if(pszFLName)
{
pFilterData->pszIpsecName = IPSecAllocPolStr(pszFLName);
if(pFilterData->pszIpsecName==NULL)
{
dwReturnCode = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
}
if(pszFLDescription)
{
pFilterData->pszDescription = IPSecAllocPolStr(pszFLDescription);
if(pFilterData->pszDescription==NULL)
{
dwReturnCode = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
}
//call the API and report if any error
if (pFilterData)
{
dwReturnCode = CreateFilterData(hPolicyStorage, pFilterData);
}
if (dwReturnCode != ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTERLIST_3,pszFLName);
}
if (pFilterData)
{
FreeFilterData(pFilterData);
}
error:
return dwReturnCode;
}
////////////////////////////////////////////////////////////
//
//Function: HandleStaticAddFilter()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN LPCWSTR pwszMachine,
// IN OUT LPWSTR *ppwcArguments,
// IN DWORD dwCurrentIndex,
// IN DWORD dwArgCount,
// IN DWORD dwFlags,
// IN LPCVOID pvData,
// OUT BOOL *pbDone
//
//Return: DWORD
//
//Description:
// Implementation for the command "Add Filter"
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD WINAPI
HandleStaticAddFilter(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
DWORD dwReturnCode = ERROR_SUCCESS;
PIPSEC_FILTER_DATA pFilterData=NULL;
DWORD LoopIndex=0;
HANDLE hPolicyStorage = NULL;
BOOL bFilterExists=FALSE,bFilterInFLExists=FALSE;
RPC_STATUS RpcStat =RPC_S_OK;
PFILTERDATA pFilter=NULL;
PARSER_PKT parser;
ZeroMemory(&parser, sizeof(parser));
const TAG_TYPE vcmdStaticAddFilter[] =
{
{ CMD_TOKEN_STR_FILTERLIST, NS_REQ_PRESENT, FALSE },
{ CMD_TOKEN_STR_SRCADDR, NS_REQ_PRESENT, FALSE },
{ CMD_TOKEN_STR_DSTADDR, NS_REQ_PRESENT, FALSE },
{ CMD_TOKEN_STR_DESCR, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_PROTO, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_MIRROR, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_SRCMASK, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_DSTMASK, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_SRCPORT, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_DSTPORT, NS_REQ_ZERO, FALSE }
};
const TOKEN_VALUE vtokStaticAddFilter[] =
{
{ CMD_TOKEN_STR_FILTERLIST, CMD_TOKEN_FILTERLIST },
{ CMD_TOKEN_STR_SRCADDR, CMD_TOKEN_SRCADDR },
{ CMD_TOKEN_STR_DSTADDR, CMD_TOKEN_DSTADDR },
{ CMD_TOKEN_STR_DESCR, CMD_TOKEN_DESCR },
{ CMD_TOKEN_STR_PROTO, CMD_TOKEN_PROTO },
{ CMD_TOKEN_STR_MIRROR, CMD_TOKEN_MIRROR },
{ CMD_TOKEN_STR_SRCMASK, CMD_TOKEN_SRCMASK },
{ CMD_TOKEN_STR_DSTMASK, CMD_TOKEN_DSTMASK },
{ CMD_TOKEN_STR_SRCPORT, CMD_TOKEN_SRCPORT },
{ CMD_TOKEN_STR_DSTPORT, CMD_TOKEN_DSTPORT }
};
//if the user asked for usage, delegate the responsibility to netsh
if(dwArgCount <= 3)
{
dwReturnCode = ERROR_SHOW_USAGE;
BAIL_OUT;
}
parser.ValidTok = vtokStaticAddFilter;
parser.MaxTok = SIZEOF_TOKEN_VALUE(vtokStaticAddFilter);
parser.ValidCmd = vcmdStaticAddFilter;
parser.MaxCmd = SIZEOF_TAG_TYPE(vcmdStaticAddFilter);
dwReturnCode = Parser(pwszMachine,ppwcArguments,dwCurrentIndex,dwArgCount,&parser);
if(dwReturnCode != ERROR_SUCCESS)
{
CleanUp();
if (dwReturnCode==RETURN_NO_ERROR)
{
dwReturnCode = ERROR_SUCCESS;
}
BAIL_OUT;
}
//get the parsed user input
dwReturnCode = FillAddFilterInfo(&pFilter,parser,vtokStaticAddFilter);
BAIL_ON_WIN32_ERROR(dwReturnCode);
if(!pFilter->pszFLName)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTERLIST_1);
BAIL_OUT;
}
//validate the user specified filter details
dwReturnCode =ValidateFilterSpec(pFilter);
BAIL_ON_WIN32_ERROR(dwReturnCode);
dwReturnCode = OpenPolicyStore(&hPolicyStorage);
if (dwReturnCode != ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_FAILED_POLSTORE_OPEN);
dwReturnCode=ERROR_SUCCESS;
BAIL_OUT;
}
//get the filterlist specified to which the filter is to be added
if(g_NshPolStoreHandle.GetBatchmodeStatus())
{
bFilterExists=g_NshPolNegFilData.GetFilterListFromCacheByName(pFilter->pszFLName,&pFilterData);
}
if(!bFilterExists)
{
bFilterExists=GetFilterListFromStore(&pFilterData,pFilter->pszFLName,hPolicyStorage,bFilterInFLExists);
}
if(!bFilterExists)
{
// if not exists create the filterlist
dwReturnCode=CreateNewFilterList(hPolicyStorage,pFilter->pszFLName,NULL);
BAIL_ON_WIN32_ERROR(dwReturnCode);
if(g_NshPolStoreHandle.GetBatchmodeStatus())
{
bFilterExists=g_NshPolNegFilData.GetFilterListFromCacheByName(pFilter->pszFLName,&pFilterData);
}
if(!bFilterExists)
{
bFilterExists=GetFilterListFromStore(&pFilterData,pFilter->pszFLName,hPolicyStorage,bFilterInFLExists);
}
}
if(!bFilterExists)
{
// if creation also failed, bail out
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTERLIST_3,pFilter->pszFLName);
dwReturnCode = ERROR_SUCCESS;
BAIL_OUT;
}
//check readonly flag
if(pFilterData->dwFlags & POLSTORE_READONLY )
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_SET_FL_READ_ONLY_OBJECT,pFilterData->pszIpsecName);
BAIL_OUT;
}
// this for loop is for multiple DNS resolved IPs
for(DWORD i=0;i < pFilter->SourceAddr.dwNumIpAddresses;i++)
{
for(DWORD j=0;j < pFilter->DestnAddr.dwNumIpAddresses;j++)
{
RpcStat = UuidCreate(&(pFilter->FilterSpecGUID));
if (!(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY))
{
dwReturnCode=ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
pFilterData->dwNumFilterSpecs++;
LoopIndex = pFilterData->dwNumFilterSpecs-1;
// call realloc , to make room for another filter
pFilterData->ppFilterSpecs = ReAllocFilterSpecMem(pFilterData->ppFilterSpecs,LoopIndex,LoopIndex+1);
if(pFilterData->ppFilterSpecs==NULL)
{
dwReturnCode=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
pFilterData->ppFilterSpecs[LoopIndex] = (PIPSEC_FILTER_SPEC) IPSecAllocPolMem(sizeof(IPSEC_FILTER_SPEC));
if(pFilterData->ppFilterSpecs[LoopIndex]==NULL)
{
dwReturnCode=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pFilterData->ppFilterSpecs[LoopIndex],0,sizeof(IPSEC_FILTER_SPEC));
//src & dst DNS name
if(pFilter->SourceAddr.pszDomainName)
{
pFilterData->ppFilterSpecs[LoopIndex]->pszSrcDNSName=IPSecAllocPolStr(pFilter->SourceAddr.pszDomainName);
if(pFilterData->ppFilterSpecs[LoopIndex]->pszSrcDNSName==NULL)
{
dwReturnCode=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
}
else
{
pFilterData->ppFilterSpecs[LoopIndex]->pszSrcDNSName=0;
}
if(pFilter->DestnAddr.pszDomainName)
{
pFilterData->ppFilterSpecs[LoopIndex]->pszDestDNSName = IPSecAllocPolStr(pFilter->DestnAddr.pszDomainName);
if(pFilterData->ppFilterSpecs[LoopIndex]->pszDestDNSName==NULL)
{
dwReturnCode=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
}
else
{
pFilterData->ppFilterSpecs[LoopIndex]->pszDestDNSName = 0;
}
//desc
if(pFilter->pszDescription)
{
pFilterData->ppFilterSpecs[LoopIndex]->pszDescription = IPSecAllocPolStr(pFilter->pszDescription);
if(pFilterData->ppFilterSpecs[LoopIndex]->pszDescription==NULL)
{
dwReturnCode=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
}
else
{
pFilterData->ppFilterSpecs[LoopIndex]->pszDescription = NULL;
}
if (((pFilter->dwProtocol != PROT_ID_TCP) && (pFilter->dwProtocol != PROT_ID_UDP)) &&
((pFilter->SourPort != 0) || (pFilter->DestPort != 0)))
{
dwReturnCode = ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
//other details like mirrored, protocol etc
pFilterData->ppFilterSpecs[LoopIndex]->dwMirrorFlag = pFilter->bMirrored;
pFilterData->ppFilterSpecs[LoopIndex]->FilterSpecGUID = pFilter->FilterSpecGUID;
pFilterData->ppFilterSpecs[LoopIndex]->Filter.SrcAddr = pFilter->SourceAddr.puIpAddr[i];
pFilterData->ppFilterSpecs[LoopIndex]->Filter.SrcMask = pFilter->SourMask;
pFilterData->ppFilterSpecs[LoopIndex]->Filter.DestAddr = pFilter->DestnAddr.puIpAddr[j];
pFilterData->ppFilterSpecs[LoopIndex]->Filter.DestMask = pFilter->DestMask;
pFilterData->ppFilterSpecs[LoopIndex]->Filter.TunnelAddr = 0;
pFilterData->ppFilterSpecs[LoopIndex]->Filter.Protocol = pFilter->dwProtocol;
pFilterData->ppFilterSpecs[LoopIndex]->Filter.SrcPort = pFilter->SourPort;
pFilterData->ppFilterSpecs[LoopIndex]->Filter.DestPort = pFilter->DestPort;
pFilterData->ppFilterSpecs[LoopIndex]->Filter.TunnelFilter = FALSE;
pFilterData->ppFilterSpecs[LoopIndex]->Filter.ExType = pFilter->ExType;
}
}
//once filling the parameters are over , call the respective API
if (pFilterData)
{
// Wrapper API is called to update cache also if required
dwReturnCode = SetFilterData(hPolicyStorage, pFilterData);
}
if (dwReturnCode != ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTER_2);
}
if(pFilterData)
{
FreeFilterData(pFilterData);
}
ClosePolicyStore(hPolicyStorage);
error: //cleanup and error printing
if(dwReturnCode == ERROR_OUTOFMEMORY || dwReturnCode == ERROR_INVALID_PARAMETER)
{
if(dwReturnCode == ERROR_OUTOFMEMORY)
{
PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
}
else
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_INVALID_ARGS);
}
if(pFilterData) // if allocation failed somewhere, free
{
if(pFilterData->ppFilterSpecs)
{
for (DWORD cnt=0; cnt< pFilterData->dwNumFilterSpecs;cnt++)
{
if(pFilterData->ppFilterSpecs[cnt])
{
IPSecFreePolMem(pFilterData->ppFilterSpecs[cnt]);
}
}
IPSecFreePolMem(pFilterData->ppFilterSpecs);
}
IPSecFreePolMem(pFilterData);
pFilterData = NULL;
}
}
CleanUpLocalFilterDataStructure(pFilter);
if(dwReturnCode != ERROR_SHOW_USAGE)
{
dwReturnCode = ERROR_SUCCESS;
}
return dwReturnCode;
}
////////////////////////////////////////////////////////////
//
//Function: FillAddFilterInfo( )
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// OUT PFILTERDATA* ppFilterData,
// IN PARSER_PKT & parser,
// IN const TOKEN_VALUE *vtokStaticAddFilter
//
//Return: DWORD
//
//Description:
// This function fills the local structure with the information got from the parser.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
FillAddFilterInfo(
OUT PFILTERDATA* ppFilterData,
IN PARSER_PKT & parser,
IN const TOKEN_VALUE *vtokStaticAddFilter
)
{
DWORD dwCount=0,dwReturn=ERROR_SUCCESS,dwStrLength = 0;
PFILTERDATA pFilterData=new FILTERDATA;
if(pFilterData==NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pFilterData,0,sizeof(FILTERDATA));
pFilterData->bMirrored=TRUE;
pFilterData->DestPort= pFilterData->SourPort=PORT_ANY;
pFilterData->dwProtocol=PROTOCOL_ANY;
pFilterData->TunnFiltExists=FALSE;
pFilterData->SourMask = pFilterData->DestMask = MASK_ME;
for(dwCount=0;dwCount<parser.MaxTok;dwCount++)
{
switch(vtokStaticAddFilter[parser.Cmd[dwCount].dwCmdToken].dwValue)
{
case CMD_TOKEN_FILTERLIST :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pFilterData->pszFLName = new _TCHAR[dwStrLength+1];
if(pFilterData->pszFLName==NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pFilterData->pszFLName, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_DESCR :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pFilterData->pszDescription = new _TCHAR[dwStrLength+1];
if(pFilterData->pszDescription==NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pFilterData->pszDescription, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_MIRROR :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pFilterData->bMirrored = *(BOOL *)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_PROTO :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pFilterData->dwProtocol = *(DWORD *)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_SRCPORT :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pFilterData->SourPort = *(WORD *)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_DSTPORT :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pFilterData->DestPort = *(WORD *)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_SRCADDR :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pFilterData->bSrcAddrSpecified=TRUE;
if(((DNSIPADDR *)parser.Cmd[dwCount].pArg)->pszDomainName)
{
dwStrLength = _tcslen(((DNSIPADDR *)parser.Cmd[dwCount].pArg)->pszDomainName);
pFilterData->SourceAddr.pszDomainName = new _TCHAR[dwStrLength+1];
if(pFilterData->SourceAddr.pszDomainName==NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pFilterData->SourceAddr.pszDomainName,((DNSIPADDR *)parser.Cmd[dwCount].pArg)->pszDomainName,dwStrLength+1);
}
pFilterData->SourceAddr.dwNumIpAddresses = ((DNSIPADDR *)parser.Cmd[dwCount].pArg)->dwNumIpAddresses;
pFilterData->SourceAddr.puIpAddr= new ULONG[pFilterData->SourceAddr.dwNumIpAddresses];
if(pFilterData->SourceAddr.puIpAddr==NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
for(DWORD n=0;n < pFilterData->SourceAddr.dwNumIpAddresses;n++)
{
memcpy( &(pFilterData->SourceAddr.puIpAddr[n]),&(((DNSIPADDR *)parser.Cmd[dwCount].pArg)->puIpAddr[n]),sizeof(ULONG));
}
}
else
{
//look for special server type
if(parser.Cmd[dwCount].dwStatus == SERVER_DNS)
{
pFilterData->bSrcServerSpecified=TRUE;
pFilterData->ExType=EXT_DNS_SERVER;
}
else if(parser.Cmd[dwCount].dwStatus == SERVER_WINS)
{
pFilterData->bSrcServerSpecified=TRUE;
pFilterData->ExType=EXT_WINS_SERVER;
}
else if(parser.Cmd[dwCount].dwStatus == SERVER_DHCP)
{
pFilterData->bSrcServerSpecified=TRUE;
pFilterData->ExType=EXT_DHCP_SERVER;
}
else if(parser.Cmd[dwCount].dwStatus == SERVER_GATEWAY)
{
pFilterData->bSrcServerSpecified=TRUE;
pFilterData->ExType=EXT_DEFAULT_GATEWAY;
}
else if (parser.Cmd[dwCount].dwStatus == IP_ME)
{
pFilterData->bSrcMeSpecified=TRUE;
}
else if (parser.Cmd[dwCount].dwStatus == IP_ANY)
{
pFilterData->bSrcAnySpecified=TRUE;
}
}
break;
case CMD_TOKEN_SRCMASK :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pFilterData->bSrcMaskSpecified=TRUE;
pFilterData->SourMask = *(DWORD *)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_DSTADDR :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pFilterData->bDstAddrSpecified=TRUE;
if(((DNSIPADDR *)parser.Cmd[dwCount].pArg)->pszDomainName)
{
dwStrLength = _tcslen(((DNSIPADDR *)parser.Cmd[dwCount].pArg)->pszDomainName);
pFilterData->DestnAddr.pszDomainName = new _TCHAR[dwStrLength+1];
if(pFilterData->DestnAddr.pszDomainName == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pFilterData->DestnAddr.pszDomainName,((DNSIPADDR *)parser.Cmd[dwCount].pArg)->pszDomainName,dwStrLength+1);
}
pFilterData->DestnAddr.dwNumIpAddresses = ((DNSIPADDR *)parser.Cmd[dwCount].pArg)->dwNumIpAddresses;
pFilterData->DestnAddr.puIpAddr= new ULONG[pFilterData->DestnAddr.dwNumIpAddresses];
if(pFilterData->DestnAddr.puIpAddr == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
for(DWORD n=0;n < pFilterData->DestnAddr.dwNumIpAddresses;n++)
{
memcpy( &(pFilterData->DestnAddr.puIpAddr[n]),(&((DNSIPADDR *)parser.Cmd[dwCount].pArg)->puIpAddr[n]),sizeof(ULONG));
}
}
else
{
//look for special server type
if(parser.Cmd[dwCount].dwStatus == SERVER_DNS)
{
pFilterData->bDstServerSpecified=TRUE;
pFilterData->ExType=EXT_DNS_SERVER | EXT_DEST;
}
else if(parser.Cmd[dwCount].dwStatus == SERVER_WINS)
{
pFilterData->bDstServerSpecified=TRUE;
pFilterData->ExType=EXT_WINS_SERVER | EXT_DEST;
}
else if(parser.Cmd[dwCount].dwStatus == SERVER_DHCP)
{
pFilterData->bDstServerSpecified=TRUE;
pFilterData->ExType=EXT_DHCP_SERVER | EXT_DEST;
}
else if(parser.Cmd[dwCount].dwStatus == SERVER_GATEWAY)
{
pFilterData->bDstServerSpecified=TRUE;
pFilterData->ExType=EXT_DEFAULT_GATEWAY | EXT_DEST;
}
else if (parser.Cmd[dwCount].dwStatus == IP_ME)
{
pFilterData->bDstMeSpecified=TRUE;
}
else if (parser.Cmd[dwCount].dwStatus == IP_ANY)
{
pFilterData->bDstAnySpecified=TRUE;
}
}
break;
case CMD_TOKEN_DSTMASK :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pFilterData->bDstMaskSpecified=TRUE;
pFilterData->DestMask = *(DWORD *)parser.Cmd[dwCount].pArg;
}
break;
default :
break;
}
}
// take care of me and any here
if(pFilterData->bSrcMeSpecified)
{
if (pFilterData->bDstMeSpecified)
{
dwReturn = ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
pFilterData->SourceAddr.dwNumIpAddresses = 1;
pFilterData->SourceAddr.puIpAddr= new ULONG[pFilterData->SourceAddr.dwNumIpAddresses];
if(pFilterData->SourceAddr.puIpAddr == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
*(pFilterData->SourceAddr.puIpAddr)=ADDR_ME;
pFilterData->SourMask = MASK_ME;
}
else
{
ADDR srcAddr, dstAddr;
if(pFilterData->bSrcAnySpecified)
{
pFilterData->SourceAddr.dwNumIpAddresses = 1;
pFilterData->SourceAddr.puIpAddr= new ULONG[pFilterData->SourceAddr.dwNumIpAddresses];
if(pFilterData->SourceAddr.puIpAddr == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
*(pFilterData->SourceAddr.puIpAddr)=ADDR_ME;
pFilterData->SourMask = ADDR_ME;
}
if (pFilterData->bDstAddrSpecified)
{
dstAddr.uIpAddr = ntohl(*(pFilterData->DestnAddr.puIpAddr));
if (pFilterData->bDstMaskSpecified)
{
dstAddr.uSubNetMask = ntohl(pFilterData->DestMask);
}
else
{
dstAddr.uSubNetMask = 0;
}
if (IsBroadcastAddress(&dstAddr) || IsMulticastAddress(&dstAddr))
{
dwReturn = ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
}
if (pFilterData->bSrcAddrSpecified)
{
srcAddr.uIpAddr = ntohl(*(pFilterData->SourceAddr.puIpAddr));
if (pFilterData->bSrcMaskSpecified)
{
srcAddr.uSubNetMask = ntohl(pFilterData->SourMask);
}
else
{
srcAddr.uSubNetMask = 0;
}
if (IsBroadcastAddress(&srcAddr) || IsMulticastAddress(&srcAddr))
{
dwReturn = ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
}
if (pFilterData->bSrcAddrSpecified && pFilterData->bDstAddrSpecified)
{
// if <ip> - <same IP> reject
if (!IsValidSubnet(&srcAddr) && !IsValidSubnet(&dstAddr) && (srcAddr.uIpAddr == dstAddr.uIpAddr))
{
dwReturn = ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
}
}
if (pFilterData->bMirrored)
{
if (pFilterData->bSrcAddrSpecified)
{
ADDR addr;
addr.uIpAddr = ntohl(*(pFilterData->SourceAddr.puIpAddr));
addr.uSubNetMask = 0;
if (IsBroadcastAddress(&addr) || IsMulticastAddress(&addr))
{
dwReturn = ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
}
}
else
{
// reject if any<->any and not mirrored
if (pFilterData->bSrcAnySpecified && pFilterData->bDstAnySpecified)
{
dwReturn = ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
if (pFilterData->SourceAddr.puIpAddr && pFilterData->DestnAddr.puIpAddr)
{
// reject subnetx-subnetx if not mirrored
ADDR srcAddr;
ADDR dstAddr;
srcAddr.uIpAddr = ntohl(*(pFilterData->SourceAddr.puIpAddr));
srcAddr.uSubNetMask = ntohl(pFilterData->SourMask);
dstAddr.uIpAddr = ntohl(*(pFilterData->DestnAddr.puIpAddr));
dstAddr.uSubNetMask = ntohl(pFilterData->DestMask);
if (IsValidSubnet(&srcAddr) && IsValidSubnet(&dstAddr) && (srcAddr.uIpAddr == dstAddr.uIpAddr))
{
dwReturn = ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
}
}
if(pFilterData->bDstMeSpecified)
{
pFilterData->DestnAddr.dwNumIpAddresses = 1;
pFilterData->DestnAddr.puIpAddr= new ULONG[pFilterData->DestnAddr.dwNumIpAddresses];
if(pFilterData->DestnAddr.puIpAddr == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
*(pFilterData->DestnAddr.puIpAddr)=ADDR_ME;
pFilterData->DestMask = MASK_ME;
}
else
{
if(pFilterData->bDstAnySpecified)
{
pFilterData->DestnAddr.dwNumIpAddresses = 1;
pFilterData->DestnAddr.puIpAddr= new ULONG[pFilterData->DestnAddr.dwNumIpAddresses];
if(pFilterData->DestnAddr.puIpAddr == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
*(pFilterData->DestnAddr.puIpAddr)=ADDR_ME;
pFilterData->DestMask = ADDR_ME;
}
}
//if DNS specified mask is to be made to 255.255.255.255
if (pFilterData->DestnAddr.pszDomainName)
{
pFilterData->DestMask = MASK_ME;
}
if (pFilterData->SourceAddr.pszDomainName)
{
pFilterData->SourMask = MASK_ME;
}
//if server type specified, ingore other irrelevent inputs
if(pFilterData->bSrcServerSpecified || pFilterData->bDstServerSpecified)
{
if(!(pFilterData->bSrcServerSpecified && pFilterData->bDstServerSpecified))
{
if(pFilterData->bSrcServerSpecified)
{
if(
!(pFilterData->bDstMeSpecified)
&& ((pFilterData->DestnAddr.puIpAddr && pFilterData->DestnAddr.puIpAddr !=0 )
||(pFilterData->DestMask != MASK_ME))
)
{
PrintMessageFromModule(g_hModule,ADD_STATIC_FILTER_SRCSERVER_WARNING);
}
}
else
{
if(
!(pFilterData->bSrcMeSpecified)
&& ( (pFilterData->SourceAddr.puIpAddr && pFilterData->SourceAddr.puIpAddr !=0 )
||(pFilterData->SourMask != MASK_ME))
)
{
PrintMessageFromModule(g_hModule,ADD_STATIC_FILTER_DSTSERVER_WARNING);
}
}
}
if(pFilterData->SourceAddr.pszDomainName)
{
delete [] pFilterData->SourceAddr.pszDomainName;
pFilterData->SourceAddr.pszDomainName=NULL;
}
if(pFilterData->DestnAddr.pszDomainName)
{
delete [] pFilterData->DestnAddr.pszDomainName;
pFilterData->DestnAddr.pszDomainName=NULL;
}
if(pFilterData->SourceAddr.puIpAddr)
{
delete [] pFilterData->SourceAddr.puIpAddr;
}
if(pFilterData->DestnAddr.puIpAddr)
{
delete [] pFilterData->DestnAddr.puIpAddr;
}
pFilterData->bSrcAddrSpecified=FALSE;
pFilterData->bSrcMaskSpecified=FALSE;
pFilterData->bDstAddrSpecified=FALSE;
pFilterData->bDstMaskSpecified=FALSE;
pFilterData->SourceAddr.dwNumIpAddresses = DEF_NUMBER_OF_ADDR;
pFilterData->SourceAddr.puIpAddr= new ULONG[DEF_NUMBER_OF_ADDR];
if(pFilterData->SourceAddr.puIpAddr == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memcpy( &(pFilterData->SourceAddr.puIpAddr[0]),&ADDR_ME ,sizeof(ULONG));
pFilterData->DestnAddr.dwNumIpAddresses = DEF_NUMBER_OF_ADDR;
pFilterData->DestnAddr.puIpAddr= new ULONG[DEF_NUMBER_OF_ADDR];
if(pFilterData->DestnAddr.puIpAddr == NULL)
{
dwReturn=ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memcpy( &(pFilterData->DestnAddr.puIpAddr[0]),&ADDR_ME ,sizeof(ULONG));
pFilterData->SourMask = MASK_ME;
pFilterData->DestMask = MASK_ME;
}
error:
*ppFilterData=pFilterData;
CleanUp();
return dwReturn;
}
////////////////////////////////////////////////////////////
//
//Function: HandleStaticAddFilterActions()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN LPCWSTR pwszMachine,
// IN OUT LPWSTR *ppwcArguments,
// IN DWORD dwCurrentIndex,
// IN DWORD dwArgCount,
// IN DWORD dwFlags,
// IN LPCVOID pvData,
// OUT BOOL *pbDone
//
//Return: DWORD
//
//Description:
// Implementation for the command "Add FilterActions"
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD WINAPI
HandleStaticAddFilterActions(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
HANDLE hPolicyStorage = NULL;
BOOL bNegPolExists=FALSE;
PFILTERACTION pFilterAction= NULL;
DWORD dwReturnCode = ERROR_SUCCESS;
PARSER_PKT parser;
ZeroMemory(&parser, sizeof(parser));
const TAG_TYPE vcmdStaticAddFilterAction[] =
{
{ CMD_TOKEN_STR_NAME, NS_REQ_PRESENT, FALSE },
{ CMD_TOKEN_STR_DESCR, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_QMPFS, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_INPASS, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_SOFT, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_ACTION, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_QMSECMETHODS, NS_REQ_ZERO, FALSE }
};
const TOKEN_VALUE vtokStaticAddFilterAction[] =
{
{ CMD_TOKEN_STR_NAME, CMD_TOKEN_NAME },
{ CMD_TOKEN_STR_DESCR, CMD_TOKEN_DESCR },
{ CMD_TOKEN_STR_QMPFS, CMD_TOKEN_QMPFS },
{ CMD_TOKEN_STR_INPASS, CMD_TOKEN_INPASS },
{ CMD_TOKEN_STR_SOFT, CMD_TOKEN_SOFT },
{ CMD_TOKEN_STR_ACTION, CMD_TOKEN_ACTION },
{ CMD_TOKEN_STR_QMSECMETHODS, CMD_TOKEN_QMSECMETHODS }
};
//if the user asked for usage, delegate the responsibility to netsh
if(dwArgCount <=3)
{
dwReturnCode = ERROR_SHOW_USAGE;
BAIL_OUT;
}
parser.ValidTok = vtokStaticAddFilterAction;
parser.MaxTok = SIZEOF_TOKEN_VALUE(vtokStaticAddFilterAction);
parser.ValidCmd = vcmdStaticAddFilterAction;
parser.MaxCmd = SIZEOF_TAG_TYPE(vcmdStaticAddFilterAction);
//call parser
dwReturnCode = Parser(pwszMachine,ppwcArguments,dwCurrentIndex,dwArgCount,&parser);
if(dwReturnCode != ERROR_SUCCESS)
{
CleanUp();
if (dwReturnCode==RETURN_NO_ERROR)
{
dwReturnCode = ERROR_SUCCESS;
}
BAIL_OUT;
}
//get the parsed user input
dwReturnCode = FillAddFilterActionInfo(&pFilterAction,parser,vtokStaticAddFilterAction);
if(dwReturnCode==ERROR_OUTOFMEMORY)
{
PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
dwReturnCode = ERROR_SUCCESS;
BAIL_OUT;
}
// if no name, bail out
if(!pFilterAction->pszFAName)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_RULE_2);
BAIL_OUT;
}
if((pFilterAction->NegPolAction==GUID_NEGOTIATION_ACTION_BLOCK)||(pFilterAction->NegPolAction==GUID_NEGOTIATION_ACTION_NO_IPSEC))
{
pFilterAction->bQMPfs=0;
pFilterAction->bSoft=0;
}
dwReturnCode = OpenPolicyStore(&hPolicyStorage);
if (dwReturnCode != ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_FAILED_POLSTORE_OPEN);
dwReturnCode=ERROR_SUCCESS;
BAIL_OUT;
}
// check for multiple filteractions with same name
if(g_NshPolStoreHandle.GetBatchmodeStatus() && g_NshPolNegFilData.CheckNegPolInCacheByName(pFilterAction->pszFAName))
{
bNegPolExists=TRUE;
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTERACTION_1,pFilterAction->pszFAName);
BAIL_OUT;
}
else
{
bNegPolExists = CheckFilterActionExistance(hPolicyStorage,pFilterAction->pszFAName);
if(bNegPolExists)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTERACTION_1,pFilterAction->pszFAName);
BAIL_OUT;
}
}
PIPSEC_NEGPOL_DATA pNegPolData=NULL;
if(pFilterAction->dwNumSecMethodCount==0 && (!((pFilterAction->NegPolAction==GUID_NEGOTIATION_ACTION_BLOCK)|| (pFilterAction->NegPolAction==GUID_NEGOTIATION_ACTION_NO_IPSEC))))
{
dwReturnCode = LoadOfferDefaults(pFilterAction->pIpsecSecMethods,pFilterAction->dwNumSecMethodCount);
if(dwReturnCode == ERROR_OUTOFMEMORY)
{
PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
dwReturnCode=ERROR_SUCCESS;
BAIL_OUT;
}
}
// prepare the NEG_POL structure
dwReturnCode = MakeNegotiationPolicy(&pNegPolData,pFilterAction);
//call the API
if(dwReturnCode==ERROR_SUCCESS)
{
if (pNegPolData)
{
dwReturnCode = CreateNegPolData(hPolicyStorage, pNegPolData);
}
if (dwReturnCode != ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTERACTION_2,pFilterAction->pszFAName);
dwReturnCode = ERROR_SUCCESS;
}
if(pNegPolData)
{
FreeNegPolData(pNegPolData);
}
}
else if(dwReturnCode==ERROR_OUTOFMEMORY)
{
PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
dwReturnCode=ERROR_SUCCESS;
}
else if(dwReturnCode==ERROR_INVALID_PARAMETER)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_STATIC_INTERNAL_ERROR);
dwReturnCode=ERROR_SUCCESS;
}
ClosePolicyStore(hPolicyStorage);
error:
// clean up the used structures
CleanUpLocalFilterActionDataStructure(pFilterAction);
return dwReturnCode;
}
////////////////////////////////////////////////////////////
//
//Function: FillAddFilterActionInfo( )
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// OUT PFILTERACTION* ppFilterData,
// IN PARSER_PKT & parser,
// IN const TOKEN_VALUE *vtokStaticAddFilterAction
//
//Return: DWORD
//
//Description:
// This function fills the local structure with the information got from the parser.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
FillAddFilterActionInfo(
OUT PFILTERACTION* ppFilterData,
IN PARSER_PKT & parser,
IN const TOKEN_VALUE *vtokStaticAddFilterAction
)
{
DWORD dwCount=0,dwReturn =ERROR_SUCCESS,dwStrLength = 0;
PFILTERACTION pFilterAction=new FILTERACTION;
if(pFilterAction==NULL)
{
dwReturn =ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pFilterAction,0,sizeof(FILTERACTION));
pFilterAction->NegPolAction=GUID_NEGOTIATION_ACTION_NORMAL_IPSEC;
for(dwCount=0;dwCount<parser.MaxTok;dwCount++)
{
switch(vtokStaticAddFilterAction[parser.Cmd[dwCount].dwCmdToken].dwValue)
{
case CMD_TOKEN_DESCR :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pFilterAction->pszFADescription = new _TCHAR[dwStrLength+1];
if(pFilterAction->pszFADescription==NULL)
{
dwReturn =ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pFilterAction->pszFADescription, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_NAME :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pFilterAction->pszFAName = new _TCHAR[dwStrLength+1];
if(pFilterAction->pszFAName==NULL)
{
dwReturn =ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pFilterAction->pszFAName, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_INPASS :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
if ( *(BOOL *)parser.Cmd[dwCount].pArg == TRUE)
{
pFilterAction->NegPolAction=GUID_NEGOTIATION_ACTION_INBOUND_PASSTHRU;
}
}
break;
case CMD_TOKEN_SOFT :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pFilterAction->bSoft = *(BOOL *)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_QMPFS :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pFilterAction->bQMPfs = *(BOOL *)parser.Cmd[dwCount].pArg;
}
break;
default :
break;
}
}
for(dwCount=0;dwCount<parser.MaxTok;dwCount++)
{
switch(vtokStaticAddFilterAction[parser.Cmd[dwCount].dwCmdToken].dwValue)
{
case CMD_TOKEN_ACTION :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
if (*(DWORD *)parser.Cmd[dwCount].pArg == TOKEN_QMSEC_PERMIT )
{
pFilterAction->NegPolAction=GUID_NEGOTIATION_ACTION_NO_IPSEC;
}
else if (*(DWORD *)parser.Cmd[dwCount].pArg == TOKEN_QMSEC_BLOCK)
{
pFilterAction->NegPolAction=GUID_NEGOTIATION_ACTION_BLOCK;
}
}
break;
default :
break;
}
}
//if action is permit or block , sec methods not required
if (!(pFilterAction->NegPolAction==GUID_NEGOTIATION_ACTION_NO_IPSEC || pFilterAction->NegPolAction==GUID_NEGOTIATION_ACTION_BLOCK))
{
for(dwCount=0;dwCount<parser.MaxTok;dwCount++)
{
switch(vtokStaticAddFilterAction[parser.Cmd[dwCount].dwCmdToken].dwValue)
{
case CMD_TOKEN_QMSECMETHODS : //qmsec methods
if (parser.Cmd[dwCount].dwStatus > 0)
{
pFilterAction->dwNumSecMethodCount=parser.Cmd[dwCount].dwStatus;
pFilterAction->pIpsecSecMethods = new IPSEC_QM_OFFER[pFilterAction->dwNumSecMethodCount];
if(pFilterAction->pIpsecSecMethods==NULL)
{
dwReturn =ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pFilterAction->pIpsecSecMethods, 0, sizeof(IPSEC_QM_OFFER) * pFilterAction->dwNumSecMethodCount);
for(DWORD j=0;j<(parser.Cmd[dwCount].dwStatus);j++)
{
if ( ((IPSEC_QM_OFFER **)parser.Cmd[dwCount].pArg)[j] )
{
memcpy( &(pFilterAction->pIpsecSecMethods[j]),((IPSEC_QM_OFFER **)parser.Cmd[dwCount].pArg)[j],sizeof(IPSEC_QM_OFFER));
}
}
}
break;
default :
break;
}
}
}
error:
*ppFilterData=pFilterAction;
CleanUp();
return dwReturn;
}
////////////////////////////////////////////////////////////
//
//Function: HandleStaticAddRule()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN LPCWSTR pwszMachine,
// IN OUT LPWSTR *ppwcArguments,
// IN DWORD dwCurrentIndex,
// IN DWORD dwArgCount,
// IN DWORD dwFlags,
// IN LPCVOID pvData,
// OUT BOOL *pbDone
//
//Return: DWORD
//
//Description
// Implementation for the command "Add Rule"
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD WINAPI
HandleStaticAddRule(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
DWORD dwRet = ERROR_SHOW_USAGE;
PRULEDATA pRuleData=NULL;
PARSER_PKT parser;
ZeroMemory(&parser, sizeof(parser));
const TAG_TYPE vcmdStaticAddRule[] =
{
{ CMD_TOKEN_STR_NAME, NS_REQ_PRESENT, FALSE },
{ CMD_TOKEN_STR_POLICY, NS_REQ_PRESENT, FALSE },
{ CMD_TOKEN_STR_FILTERLIST, NS_REQ_PRESENT, FALSE },
{ CMD_TOKEN_STR_FILTERACTION, NS_REQ_PRESENT, FALSE },
{ CMD_TOKEN_STR_TUNNEL, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_CONNTYPE, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_ACTIVATE, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_DESCR, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_KERB, NS_REQ_ZERO, FALSE },
{ CMD_TOKEN_STR_PSK, NS_REQ_ZERO, FALSE }
};
const TOKEN_VALUE vtokStaticAddRule[] =
{
{ CMD_TOKEN_STR_NAME, CMD_TOKEN_NAME },
{ CMD_TOKEN_STR_POLICY, CMD_TOKEN_POLICY },
{ CMD_TOKEN_STR_FILTERLIST, CMD_TOKEN_FILTERLIST },
{ CMD_TOKEN_STR_FILTERACTION, CMD_TOKEN_FILTERACTION },
{ CMD_TOKEN_STR_TUNNEL, CMD_TOKEN_TUNNEL },
{ CMD_TOKEN_STR_CONNTYPE, CMD_TOKEN_CONNTYPE },
{ CMD_TOKEN_STR_ACTIVATE, CMD_TOKEN_ACTIVATE },
{ CMD_TOKEN_STR_DESCR, CMD_TOKEN_DESCR },
{ CMD_TOKEN_STR_KERB, CMD_TOKEN_KERB },
{ CMD_TOKEN_STR_PSK, CMD_TOKEN_PSK }
};
const TOKEN_VALUE vlistStaticAddRule[] =
{
{ CMD_TOKEN_STR_ROOTCA, CMD_TOKEN_ROOTCA },
};
//if the user asked for usage, delegate the responsibility to netsh
if(dwArgCount <=3)
{
dwRet = ERROR_SHOW_USAGE;
BAIL_OUT;
}
parser.ValidTok = vtokStaticAddRule;
parser.MaxTok = SIZEOF_TOKEN_VALUE(vtokStaticAddRule);
parser.ValidCmd = vcmdStaticAddRule;
parser.MaxCmd = SIZEOF_TAG_TYPE(vcmdStaticAddRule);
parser.ValidList = vlistStaticAddRule;
parser.MaxList = SIZEOF_TOKEN_VALUE(vlistStaticAddRule);
dwRet = Parser(pwszMachine,ppwcArguments,dwCurrentIndex,dwArgCount,&parser);
if(dwRet != ERROR_SUCCESS)
{
CleanUp();
if (dwRet == RETURN_NO_ERROR)
{
dwRet = ERROR_SUCCESS;
}
BAIL_OUT;
}
// get parsed user input
dwRet = FillAddRuleInfo(&pRuleData,parser,vtokStaticAddRule);
if(dwRet==ERROR_OUTOFMEMORY)
{
PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
dwRet=ERROR_SUCCESS;
BAIL_OUT;
}
if(pRuleData)
{
//if tunnel specified, validate it
if (pRuleData->bTunnel)
{
if(!bIsValidIPAddress(htonl(pRuleData->TunnelIPAddress),TRUE,TRUE))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_RULE_INVALID_TUNNEL);
dwRet=ERROR_SUCCESS;
BAIL_OUT;
}
}
//create new rule
CreateNewRule(pRuleData);
dwRet=ERROR_SUCCESS;
}
error:
CleanUpLocalRuleDataStructure(pRuleData);
return dwRet;
}
////////////////////////////////////////////////////////////
//
//Function: CreateNewRule()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN PRULEDATA pRuleData
//
//Return: DWORD
//
//Description:
// Creates a new rule based on the user input
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
CreateNewRule(
IN PRULEDATA pRuleData
)
{
PIPSEC_POLICY_DATA pPolicyData = NULL;
PIPSEC_NEGPOL_DATA pNegPolData = NULL;
PIPSEC_FILTER_DATA pFilterData = NULL;
HANDLE hPolicyStorage = NULL;
BOOL bPolicyExists=FALSE,bFAExists=FALSE,bFLExists=FALSE;
BOOL bFilterExists=FALSE,bRuleExists=FALSE;
DWORD dwReturnCode = ERROR_SUCCESS;
// check for all mandatory names
if (!pRuleData->pszRuleName || (pRuleData->pszRuleName[0] == _TEXT('\0')) )
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_RULE_1);
return ERROR_INVALID_DATA;
}
if (!pRuleData->pszPolicyName || (pRuleData->pszPolicyName[0] == _TEXT('\0')) )
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_POLICY_MISSING_POL_NAME);
return ERROR_INVALID_DATA;
}
if (!pRuleData->pszFLName || (pRuleData->pszFLName[0] == _TEXT('\0')) )
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTERLIST_1);
return ERROR_INVALID_DATA;
}
if (!pRuleData->pszFAName || (pRuleData->pszFAName[0] == _TEXT('\0')) )
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_RULE_2);
return ERROR_INVALID_DATA;
}
if(!pRuleData->bConnectionTypeSpecified)
{
pRuleData->ConnectionType= INTERFACE_TYPE_ALL;
}
dwReturnCode = OpenPolicyStore(&hPolicyStorage);
if (dwReturnCode != ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_FAILED_POLSTORE_OPEN);
dwReturnCode = ERROR_SUCCESS;
BAIL_OUT;
}
//check for duplicate names in polstore
if(g_NshPolStoreHandle.GetBatchmodeStatus())
{
bPolicyExists=g_NshPolNegFilData.GetPolicyFromCacheByName(pRuleData->pszPolicyName,&pPolicyData);
}
if(!bPolicyExists)
{
if(!(bPolicyExists=GetPolicyFromStore(&pPolicyData,pRuleData->pszPolicyName,hPolicyStorage)))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_RULE_3,pRuleData->pszPolicyName);
dwReturnCode=ERROR_INVALID_DATA;
BAIL_OUT;
}
}
//check for readonly flag
if(pPolicyData->dwFlags & POLSTORE_READONLY )
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_SET_POL_READ_ONLY_OBJECT,pPolicyData->pszIpsecName);
dwReturnCode=ERROR_SUCCESS;
BAIL_OUT;
}
if (bPolicyExists && (bRuleExists=CheckForRuleExistance(pPolicyData,pRuleData->pszRuleName)))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_RULE_4,pRuleData->pszRuleName,pRuleData->pszPolicyName);
dwReturnCode=ERROR_INVALID_DATA;
BAIL_OUT;
}
//check for filterlist & filteractions, if not available bail out
if(g_NshPolStoreHandle.GetBatchmodeStatus())
{
bFAExists=g_NshPolNegFilData.GetNegPolFromCacheByName(pRuleData->pszFAName,&pNegPolData);
}
if(!bFAExists)
{
if(!(bFAExists=GetNegPolFromStore(&pNegPolData,pRuleData->pszFAName,hPolicyStorage)))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_RULE_5,pRuleData->pszFAName);
dwReturnCode=ERROR_INVALID_DATA;
BAIL_OUT;
}
}
if(g_NshPolStoreHandle.GetBatchmodeStatus())
{
bFLExists=g_NshPolNegFilData.GetFilterListFromCacheByName(pRuleData->pszFLName,&pFilterData);
}
if(!bFLExists)
{
if(!(bFLExists=GetFilterListFromStore(&pFilterData,pRuleData->pszFLName,hPolicyStorage,bFilterExists)))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTER_1,pRuleData->pszFLName);
dwReturnCode=ERROR_INVALID_DATA;
BAIL_OUT;
}
}
else // if no filters bail out
{
if(pFilterData->dwNumFilterSpecs > 0)
{
bFilterExists=TRUE;
}
}
if( !bFilterExists && bFLExists)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_RULE_6,pRuleData->pszFLName);
dwReturnCode=ERROR_INVALID_DATA;
BAIL_OUT;
}
//if everything is in place , proceed
if(bPolicyExists && bFAExists && bFLExists && bFilterExists)
{
dwReturnCode=AddRule(pPolicyData, pRuleData, pNegPolData, pFilterData,hPolicyStorage ) ;
if(dwReturnCode!=ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_RULE_7,pRuleData->pszRuleName);
}
}
ClosePolicyStore(hPolicyStorage);
if(pPolicyData)
{
FreePolicyData(pPolicyData);
}
error:
return dwReturnCode;
}
////////////////////////////////////////////////////////////
//
//Function: CheckRuleExistance( )
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN PIPSEC_POLICY_DATA pPolicy,
// IN PRULEDATA pRuleData
//
//Return: BOOL
//
//Description:
// This function checks whether the user specified rule already exists.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
BOOL
CheckForRuleExistance(
IN PIPSEC_POLICY_DATA pPolicy,
IN LPTSTR pszRuleName
)
{
BOOL bRuleExists=FALSE;
//check whether the specified rule already exists
for (DWORD n = 0; n < pPolicy->dwNumNFACount ; n++)
{
if (pPolicy->ppIpsecNFAData[n]->pszIpsecName && pszRuleName &&(_tcscmp(pPolicy->ppIpsecNFAData[n]->pszIpsecName,pszRuleName)==0))
{
bRuleExists=TRUE;
break;
}
}
return bRuleExists;
}
////////////////////////////////////////////////////////////
//
//Function: FillAddRuleInfo( )
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// OUT PRULEDATA* ppFilterData,
// IN PARSER_PKT & parser,
// IN const TOKEN_VALUE *vtokStaticAddRule,
// IN const TOKEN_VALUE *vlistStaticAddRule
//
//Return: DWORD
//
//Description:
// This function fills the local structure with the information got from the parser.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
FillAddRuleInfo(
OUT PRULEDATA* ppRuleData,
IN PARSER_PKT & parser,
IN const TOKEN_VALUE *vtokStaticAddRule
)
{
DWORD dwCount=0, dwReturn=ERROR_SUCCESS , dwStrLength = 0;
PRULEDATA pRuleData=new RULEDATA;
PSTA_AUTH_METHODS pKerbAuth = NULL;
PSTA_AUTH_METHODS pPskAuth = NULL;
PSTA_MM_AUTH_METHODS *ppRootcaMMAuth = NULL;
if(pRuleData == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pRuleData,0,sizeof(RULEDATA));
// default is that new rule is active
pRuleData->bActivate = TRUE;
for(dwCount=0; dwCount<parser.MaxTok; dwCount++)
{
switch(vtokStaticAddRule[parser.Cmd[dwCount].dwCmdToken].dwValue)
{
case CMD_TOKEN_NAME :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pRuleData->pszRuleName = new _TCHAR[dwStrLength+1];
if(pRuleData->pszRuleName == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pRuleData->pszRuleName, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_POLICY :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pRuleData->pszPolicyName = new _TCHAR[dwStrLength+1];
if(pRuleData->pszPolicyName == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pRuleData->pszPolicyName, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_DESCR :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pRuleData->pszRuleDescription = new _TCHAR[dwStrLength+1];
if(pRuleData->pszRuleDescription == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pRuleData->pszRuleDescription, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_FILTERLIST :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pRuleData->pszFLName = new _TCHAR[dwStrLength+1];
if(pRuleData->pszFLName == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pRuleData->pszFLName, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_FILTERACTION :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
dwStrLength = _tcslen((LPTSTR )parser.Cmd[dwCount].pArg);
pRuleData->pszFAName = new _TCHAR[dwStrLength+1];
if(pRuleData->pszFAName == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
_tcsncpy(pRuleData->pszFAName, (LPTSTR )parser.Cmd[dwCount].pArg,dwStrLength+1);
}
break;
case CMD_TOKEN_TUNNEL :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pRuleData->TunnelIPAddress = *(IPADDR *)parser.Cmd[dwCount].pArg;
if(pRuleData->TunnelIPAddress)
{
pRuleData->bTunnel=TRUE;
}
else
{
pRuleData->bTunnel=FALSE;
}
ADDR addr;
addr.uIpAddr = ntohl(pRuleData->TunnelIPAddress);
addr.uSubNetMask = 0;
if (!IsValidTunnelEndpointAddress(&addr))
{
dwReturn = ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
}
else
{
// if special server specified, give a warning, and proceed with no tunnel
switch(parser.Cmd[dwCount].dwStatus)
{
case SERVER_DNS :
case SERVER_WINS :
case SERVER_DHCP :
case SERVER_GATEWAY :
default :PrintMessageFromModule(g_hModule,ADD_STATIC_RULE_INVALID_TUNNEL);
break;
}
}
break;
case CMD_TOKEN_CONNTYPE :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pRuleData->ConnectionType = *(IF_TYPE *)parser.Cmd[dwCount].pArg;
pRuleData->bConnectionTypeSpecified=TRUE;
}
break;
case CMD_TOKEN_ACTIVATE :
if ((parser.Cmd[dwCount].dwStatus == VALID_TOKEN)&&(parser.Cmd[dwCount].pArg))
{
pRuleData->bActivate = *(BOOL *)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_KERB :
if (parser.Cmd[dwCount].dwStatus == VALID_TOKEN)
{
pRuleData->bAuthMethodSpecified = TRUE;
++pRuleData->AuthInfos.dwNumAuthInfos;
pKerbAuth = (PSTA_AUTH_METHODS)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_PSK :
if (parser.Cmd[dwCount].dwStatus == VALID_TOKEN)
{
pRuleData->bAuthMethodSpecified = TRUE;
++pRuleData->AuthInfos.dwNumAuthInfos;
pPskAuth = (PSTA_AUTH_METHODS)parser.Cmd[dwCount].pArg;
}
break;
case CMD_TOKEN_ROOTCA :
// this case is special, handled below...
break;
default :
break;
}
}
size_t uiRootcaIndex = parser.MaxTok;
if (parser.Cmd[uiRootcaIndex].dwStatus > 0)
{
pRuleData->bAuthMethodSpecified = TRUE;
pRuleData->AuthInfos.dwNumAuthInfos += parser.Cmd[uiRootcaIndex].dwStatus;
ppRootcaMMAuth = (PSTA_MM_AUTH_METHODS *)(parser.Cmd[uiRootcaIndex].pArg);
}
dwReturn = AddAllAuthMethods(pRuleData, pKerbAuth, pPskAuth, ppRootcaMMAuth, TRUE);
if (dwReturn != ERROR_SUCCESS)
{
BAIL_OUT;
}
error: // if default auth loading failed, clean up everything and make 'pRuleData' as NULL
CleanupAuthData(&pKerbAuth, &pPskAuth, ppRootcaMMAuth);
if(dwReturn==ERROR_SUCCESS && pRuleData->dwAuthInfos > 0)
{
*ppRuleData=pRuleData;
}
else
{
if(dwReturn != ERROR_OUTOFMEMORY)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_RULE_7,pRuleData->pszRuleName);
}
else
{
PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
}
CleanUpLocalRuleDataStructure(pRuleData);
}
CleanUp();
return dwReturn;
}
////////////////////////////////////////////////////////////
//
//Function: AddDefaultResponseRule()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN OUT PIPSEC_POLICY_DATA pPolicy,
// IN HANDLE hPolicyStorage,
// IN BOOL bActivateDefaultRule
//Return: DWORD
//
//Description:
// This function adds the NFA structure to the policy for default response rule
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
AddDefaultResponseRule(
IN OUT PIPSEC_POLICY_DATA pPolicy,
IN HANDLE hPolicyStorage,
IN BOOL bActivateDefaultRule,
IN BOOL bActivateDefaultRuleSpecified
)
{
DWORD dwReturn = ERROR_SUCCESS;
BOOL bCertConversionSuceeded=TRUE;
PIPSEC_NFA_DATA pRule = MakeDefaultResponseRule(bActivateDefaultRule,bActivateDefaultRuleSpecified);
// form policy data structures
if(pRule ==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
// if cert specified, and decode/ancode failed, bail out
if(!bCertConversionSuceeded)
{
dwReturn=ERROR_INVALID_DATA;
BAIL_OUT;
}
pPolicy->dwNumNFACount=1;
pPolicy->ppIpsecNFAData = (PIPSEC_NFA_DATA *) IPSecAllocPolMem(sizeof(PIPSEC_NFA_DATA));
if(pPolicy->ppIpsecNFAData ==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
// call the APIs
pPolicy->ppIpsecNFAData[pPolicy->dwNumNFACount-1] = pRule;
pRule->pIpsecNegPolData->NegPolType = GUID_NEGOTIATION_TYPE_DEFAULT;
//create default negpol
dwReturn = IPSecCreateNegPolData(hPolicyStorage, pRule->pIpsecNegPolData);
if (dwReturn == ERROR_SUCCESS)
{
dwReturn=CreatePolicyData(hPolicyStorage, pPolicy);
if(dwReturn==ERROR_SUCCESS)
{
dwReturn =IPSecCreateNFAData(hPolicyStorage,pPolicy->PolicyIdentifier, pRule);
if(dwReturn!=ERROR_SUCCESS)
{
IPSecDeleteISAKMPData(hPolicyStorage, pPolicy->ISAKMPIdentifier);
IPSecDeleteNegPolData(hPolicyStorage, pRule->NegPolIdentifier);
DeletePolicyData(hPolicyStorage, pPolicy);
}
}
else
{
IPSecDeleteNegPolData(hPolicyStorage, pRule->NegPolIdentifier);
}
}
error:
if(dwReturn == ERROR_OUTOFMEMORY)
{
dwReturn = ERROR_SUCCESS;
PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
}
return dwReturn;
}
////////////////////////////////////////////////////////////
//
//Function: MakeDefaultResponseRule()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN BOOL bActivate,
// IN BOOL bActivateSpecified
//
//Return: PIPSEC_NFA_DATA
//
//Description:
// This function fills the NFA structure for default response rule
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
PIPSEC_NFA_DATA
MakeDefaultResponseRule (
IN BOOL bActivate,
IN BOOL bActivateSpecified
)
{
RPC_STATUS RpcStat =RPC_S_OK , dwReturn = ERROR_SUCCESS;
PIPSEC_NFA_DATA pRule = (PIPSEC_NFA_DATA) IPSecAllocPolMem(sizeof(IPSEC_NFA_DATA));
if(pRule == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pRule,0,sizeof(IPSEC_NFA_DATA));
//no name, desc, interface name or endpoint name dor default rule
pRule->pszIpsecName = pRule->pszDescription = pRule->pszInterfaceName = pRule->pszEndPointName = NULL;
RpcStat = UuidCreate(&(pRule->NFAIdentifier));
if (!(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY))
{
dwReturn=ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
pRule->dwWhenChanged = 0;
// filter list
pRule->pIpsecFilterData = NULL;
RpcStat = UuidCreateNil(&(pRule->FilterIdentifier));
if (!(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY))
{
dwReturn=ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
pRule->pIpsecNegPolData = MakeDefaultResponseNegotiationPolicy ();
if(pRule->pIpsecNegPolData == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
pRule->NegPolIdentifier = pRule->pIpsecNegPolData->NegPolIdentifier;
// tunnel address
pRule->dwTunnelFlags = 0;
// interface type
pRule->dwInterfaceType = (DWORD)PAS_INTERFACE_TYPE_ALL;
// active flag
if(bActivateSpecified)
{
pRule->dwActiveFlag = bActivate;
}
else
{
pRule->dwActiveFlag = TRUE;
}
// auth methods = Kerberos for the time being
pRule->dwAuthMethodCount = 1;
pRule->ppAuthMethods = (PIPSEC_AUTH_METHOD *) IPSecAllocPolMem(pRule->dwAuthMethodCount * sizeof(PIPSEC_AUTH_METHOD));
if(pRule->ppAuthMethods==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
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;
error:
if(dwReturn == ERROR_OUTOFMEMORY || dwReturn == ERROR_INVALID_PARAMETER)
{
if(pRule)
{
CleanUpAuthInfo(pRule); //this function frees only auth info.
IPSecFreePolMem(pRule); //since the above fn is used in other fns also, this free is required to cleanup other rule memory
pRule = NULL;
}
}
return pRule;
}
////////////////////////////////////////////////////////////
//
//Function: MakeDefaultResponseNegotiationPolicy()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// VOID
//
//Return: PIPSEC_NEGPOL_DATA
//
//Description:
// This function fills the NegPol structure for default response rule
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
PIPSEC_NEGPOL_DATA
MakeDefaultResponseNegotiationPolicy (
VOID
)
{
RPC_STATUS RpcStat=RPC_S_OK;
DWORD dwReturn = ERROR_SUCCESS;
_TCHAR pFAName[MAXSTRLEN]={0};
PIPSEC_NEGPOL_DATA pNegPol = (PIPSEC_NEGPOL_DATA) IPSecAllocPolMem(sizeof(IPSEC_NEGPOL_DATA));
if(pNegPol == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
RpcStat = UuidCreate(&(pNegPol->NegPolIdentifier));
if (!(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY))
{
dwReturn=ERROR_INVALID_PARAMETER;
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_STATIC_INTERNAL_ERROR);
BAIL_OUT;
}
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));
if(pNegPol->pIpsecSecurityMethods==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
// 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 = CONF_ALGO_3_DES;
pNegPol->pIpsecSecurityMethods[0].Algos[0].secondaryAlgoIdentifier = AUTH_ALGO_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 = CONF_ALGO_3_DES;
pNegPol->pIpsecSecurityMethods[1].Algos[0].secondaryAlgoIdentifier = AUTH_ALGO_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 = CONF_ALGO_DES;
pNegPol->pIpsecSecurityMethods[2].Algos[0].secondaryAlgoIdentifier = AUTH_ALGO_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 = CONF_ALGO_DES;
pNegPol->pIpsecSecurityMethods[3].Algos[0].secondaryAlgoIdentifier = AUTH_ALGO_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 = AUTH_ALGO_SHA1;
pNegPol->pIpsecSecurityMethods[4].Algos[0].secondaryAlgoIdentifier = AUTH_ALGO_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 = AUTH_ALGO_MD5;
pNegPol->pIpsecSecurityMethods[5].Algos[0].secondaryAlgoIdentifier = AUTH_ALGO_NONE;
pNegPol->pIpsecSecurityMethods[5].Algos[0].algoKeylen = 0;
pNegPol->pIpsecSecurityMethods[5].Algos[0].algoRounds = 0;
pNegPol->pIpsecSecurityMethods[5].Algos[0].operation = Auth;
// not necessary to change to bounded printf
_stprintf(pFAName, _TEXT(""));
pNegPol->pszIpsecName = IPSecAllocPolStr(pFAName);
if(pNegPol->pszIpsecName==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
pNegPol->pszDescription = NULL;
error:
if(dwReturn == ERROR_OUTOFMEMORY || dwReturn==ERROR_INVALID_PARAMETER)
{
if(pNegPol)
{
if(pNegPol->pIpsecSecurityMethods)
{
IPSecFreePolMem(pNegPol->pIpsecSecurityMethods);
}
IPSecFreePolMem(pNegPol);
pNegPol = NULL;
}
}
return pNegPol;
}
////////////////////////////////////////////////////////////
//
//Function: MakeNegotiationPolicy()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// OUT PIPSEC_NEGPOL_DATA *ppNegPol,
// IN PFILTERACTION pFilterAction
//
//Return: DWORD
//
//Description:
// This function fills the Negpol structure based of the user input
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
MakeNegotiationPolicy(
OUT PIPSEC_NEGPOL_DATA *ppNegPol,
IN PFILTERACTION pFilterAction
)
{
RPC_STATUS RpcStat=RPC_S_OK;
DWORD i=0,dwReturn = ERROR_SUCCESS;
PIPSEC_NEGPOL_DATA pNegPol = (PIPSEC_NEGPOL_DATA) IPSecAllocPolMem(sizeof(IPSEC_NEGPOL_DATA));
if(pNegPol == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pNegPol,0,sizeof(IPSEC_NEGPOL_DATA));
RpcStat = UuidCreate(&(pNegPol->NegPolIdentifier));
if (!(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY))
{
dwReturn=ERROR_INVALID_PARAMETER;
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_STATIC_INTERNAL_ERROR);
BAIL_OUT;
}
// start with action=negotiate
pNegPol->NegPolAction = GUID_NEGOTIATION_ACTION_NORMAL_IPSEC;
pNegPol->NegPolType = GUID_NEGOTIATION_TYPE_STANDARD;
pNegPol->dwSecurityMethodCount = pFilterAction->dwNumSecMethodCount;
//if soft , increment the count
if(pFilterAction->bSoft)
{
pNegPol->dwSecurityMethodCount++;
}
if(pNegPol->dwSecurityMethodCount)
{
pNegPol->pIpsecSecurityMethods = (IPSEC_SECURITY_METHOD *) IPSecAllocPolMem(pNegPol->dwSecurityMethodCount * sizeof(IPSEC_SECURITY_METHOD));
if(pNegPol->pIpsecSecurityMethods==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
}
// handle sec.methods
for (i = 0; i < pFilterAction->dwNumSecMethodCount; i++)
{
DWORD j;
pNegPol->pIpsecSecurityMethods[i].Lifetime.KeyExpirationBytes = pFilterAction->pIpsecSecMethods[i].Lifetime.uKeyExpirationKBytes;
pNegPol->pIpsecSecurityMethods[i].Lifetime.KeyExpirationTime = pFilterAction->pIpsecSecMethods[i].Lifetime.uKeyExpirationTime;
pNegPol->pIpsecSecurityMethods[i].Flags = 0;
pNegPol->pIpsecSecurityMethods[i].PfsQMRequired = pFilterAction->bQMPfs;
pNegPol->pIpsecSecurityMethods[i].Count = pFilterAction->pIpsecSecMethods[i].dwNumAlgos;
for (j = 0; j < pNegPol->pIpsecSecurityMethods[i].Count && j < QM_MAX_ALGOS; j++)
{
pNegPol->pIpsecSecurityMethods[i].Algos[j].algoIdentifier = pFilterAction->pIpsecSecMethods[i].Algos[j].uAlgoIdentifier;
pNegPol->pIpsecSecurityMethods[i].Algos[j].secondaryAlgoIdentifier = pFilterAction->pIpsecSecMethods[i].Algos[j].uSecAlgoIdentifier;
pNegPol->pIpsecSecurityMethods[i].Algos[j].algoKeylen = pFilterAction->pIpsecSecMethods[i].Algos[j].uAlgoKeyLen;
pNegPol->pIpsecSecurityMethods[i].Algos[j].algoRounds = pFilterAction->pIpsecSecMethods[i].Algos[j].uAlgoRounds;
switch (pFilterAction->pIpsecSecMethods[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 (pFilterAction->bSoft)
{
memset(&(pNegPol->pIpsecSecurityMethods[pNegPol->dwSecurityMethodCount - 1]), 0, sizeof(IPSEC_SECURITY_METHOD));
}
if(pFilterAction->pszFAName)
{
pNegPol->pszIpsecName = IPSecAllocPolStr(pFilterAction->pszFAName);
if(pNegPol->pszIpsecName==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
}
if(pFilterAction->pszFADescription)
{
pNegPol->pszDescription = IPSecAllocPolStr(pFilterAction->pszFADescription);
if(pNegPol->pszDescription==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
}
// fill the relevent guid for action, got from the user
pNegPol->NegPolAction=pFilterAction->NegPolAction;
error: //clean up
if(dwReturn == ERROR_OUTOFMEMORY)
{
if(pNegPol)
{
if(pNegPol->pIpsecSecurityMethods)
{
IPSecFreePolMem(pNegPol->pIpsecSecurityMethods);
}
IPSecFreePolMem(pNegPol);
pNegPol=NULL;
}
}
*ppNegPol= pNegPol;
return dwReturn;
}
////////////////////////////////////////////////////////////
//
//Function: GetNegPolFromStore()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// OUT PIPSEC_NEGPOL_DATA *ppNegPol,
// IN LPTSTR pszFAName,
// IN HANDLE hPolicyStorage
//
//Return: BOOL
//
//Description:
// This function retrives the user specified NegPol data from the policy store
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
BOOL
GetNegPolFromStore(
OUT PIPSEC_NEGPOL_DATA *ppNegPol,
IN LPTSTR pszFAName,
IN HANDLE hPolicyStorage
)
{
PIPSEC_NEGPOL_DATA *ppNegPolEnum = NULL,pNegPolData=NULL;
DWORD dwNumNegPol=0 ;
BOOL bNegPolExists=FALSE;
DWORD dwReturnCode=ERROR_SUCCESS, i=0;
//enum and get the filteraction from the store
dwReturnCode = IPSecEnumNegPolData(hPolicyStorage, &ppNegPolEnum, &dwNumNegPol);
if (dwReturnCode == ERROR_SUCCESS && dwNumNegPol> 0 && ppNegPolEnum != NULL)
{
for (i = 0; i < dwNumNegPol; i++)
{
if ((ppNegPolEnum[i]->pszIpsecName!=NULL)&&( _tcscmp(ppNegPolEnum[i]->pszIpsecName, pszFAName) == 0))
{
bNegPolExists=TRUE;
dwReturnCode = IPSecCopyNegPolData(ppNegPolEnum[i],&pNegPolData);
break;
}
}
if (dwNumNegPol > 0 && ppNegPolEnum != NULL)
{
IPSecFreeMulNegPolData(ppNegPolEnum, dwNumNegPol);
}
}
if(pNegPolData)
{
*ppNegPol=pNegPolData;
}
return bNegPolExists;
}
////////////////////////////////////////////////////////////
//
//Function: GetFilterListFromStore()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// OUT PIPSEC_FILTER_DATA *ppFilter,
// IN LPTSTR pszFLName,
// IN HANDLE hPolicyStorage,
// IN OUT BOOL &bFilterExists
//
//Return: BOOL
//
//Description:
// This function retrives the user specified Filter list data from the policy store
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
BOOL
GetFilterListFromStore(
OUT PIPSEC_FILTER_DATA *ppFilter,
IN LPTSTR pszFLName,
IN HANDLE hPolicyStorage,
IN OUT BOOL &bFilterExists
)
{
PIPSEC_FILTER_DATA *ppFilterEnum = NULL,pFilterData=NULL;
DWORD dwNumFilter=0 , i=0 ;
BOOL bFilterListExists=FALSE;
DWORD dwReturnCode=ERROR_SUCCESS;
//enum and get the filterlist from the store
dwReturnCode = IPSecEnumFilterData(hPolicyStorage, &ppFilterEnum, &dwNumFilter);
if (dwReturnCode == ERROR_SUCCESS && dwNumFilter> 0 && ppFilterEnum != NULL)
{
for (i = 0; i < dwNumFilter; i++)
{
if ((ppFilterEnum[i]->pszIpsecName!=NULL)&&( _tcscmp(ppFilterEnum[i]->pszIpsecName, pszFLName) == 0))
{
bFilterListExists=TRUE;
dwReturnCode = IPSecCopyFilterData(ppFilterEnum[i],&pFilterData);
if(ppFilterEnum[i]->dwNumFilterSpecs > 0)
{
bFilterExists=TRUE;
}
break;
}
}
if (dwNumFilter > 0 && ppFilterEnum != NULL)
{
IPSecFreeMulFilterData(ppFilterEnum, dwNumFilter);
}
}
if(pFilterData)
{
*ppFilter=pFilterData;
}
return bFilterListExists;
}
////////////////////////////////////////////////////////////
//
//Function: GetPolicyFromStore()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// OUT PIPSEC_POLICY_DATA *ppPolicy,
// IN LPTSTR szPolicyName,
// IN HANDLE hPolicyStorage
//
//Return: BOOL
//
//Description:
// This function retrives the user specified Policy data from the policy store
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
BOOL
GetPolicyFromStore(
OUT PIPSEC_POLICY_DATA *ppPolicy,
IN LPTSTR szPolicyName,
IN HANDLE hPolicyStorage
)
{
PIPSEC_POLICY_DATA *ppPolicyEnum = NULL,pPolicy=NULL;
BOOL bPolicyExists=FALSE;
DWORD dwNumPolicies = 0,i=0,j=0;
DWORD dwReturnCode=ERROR_SUCCESS;
RPC_STATUS RpcStat =RPC_S_OK;
//enum and get the policy from the store
dwReturnCode = IPSecEnumPolicyData(hPolicyStorage, &ppPolicyEnum, &dwNumPolicies);
if (!(dwReturnCode == ERROR_SUCCESS && dwNumPolicies > 0 && ppPolicyEnum != NULL))
{
BAIL_OUT;
}
for (i = 0; i < dwNumPolicies; i++)
{
if (szPolicyName && _tcscmp(ppPolicyEnum[i]->pszIpsecName, szPolicyName) == 0)
{
bPolicyExists=TRUE;
dwReturnCode = IPSecCopyPolicyData(ppPolicyEnum[i], &pPolicy);
if (dwReturnCode == ERROR_SUCCESS)
{
dwReturnCode = IPSecEnumNFAData(hPolicyStorage, pPolicy->PolicyIdentifier
, &(pPolicy->ppIpsecNFAData), &(pPolicy->dwNumNFACount));
}
if (dwReturnCode == ERROR_SUCCESS)
{
dwReturnCode = IPSecGetISAKMPData(hPolicyStorage, pPolicy->ISAKMPIdentifier, &(pPolicy->pIpsecISAKMPData));
if(dwReturnCode==ERROR_SUCCESS )
{
for (j = 0; j < pPolicy->dwNumNFACount; j++)
{
if (!UuidIsNil(&(pPolicy->ppIpsecNFAData[j]->NegPolIdentifier), &RpcStat))
{
IPSecGetNegPolData(hPolicyStorage,
pPolicy->ppIpsecNFAData[j]->NegPolIdentifier,
&(pPolicy->ppIpsecNFAData[j]->pIpsecNegPolData));
}
}
}
}
}
}
// clean it up
if (dwNumPolicies > 0 && ppPolicyEnum != NULL)
{
IPSecFreeMulPolicyData(ppPolicyEnum, dwNumPolicies);
}
if(pPolicy)
{
*ppPolicy=pPolicy;
}
error:
return bPolicyExists;
}
////////////////////////////////////////////////////////////
//
//Function: MakeRule()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN PRULEDATA pRuleData,
// IN PIPSEC_NEGPOL_DATA pNegPolData,
// IN PIPSEC_FILTER_DATA pFilterData,
// IN OUT BOOL &bCertConversionSuceeded
//
//Return: PIPSEC_NFA_DATA
//
//Description:
// This function forms the NFA data structure basedon the user input.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
PIPSEC_NFA_DATA
MakeRule(
IN PRULEDATA pRuleData,
IN PIPSEC_NEGPOL_DATA pNegPolData,
IN PIPSEC_FILTER_DATA pFilterData,
IN OUT BOOL &bCertConversionSuceeded
)
{
RPC_STATUS RpcStat =RPC_S_OK;
DWORD dwReturn = ERROR_SUCCESS;
PIPSEC_NFA_DATA pRule = (PIPSEC_NFA_DATA) IPSecAllocPolMem(sizeof(IPSEC_NFA_DATA));
if(pRule==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pRule,0,sizeof(IPSEC_NFA_DATA));
pRule->pszIpsecName = pRule->pszDescription = pRule->pszInterfaceName = pRule->pszEndPointName = NULL;
//rule name
if (pRuleData->pszRuleName)
{
pRule->pszIpsecName = IPSecAllocPolStr(pRuleData->pszRuleName);
if(pRule->pszIpsecName==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
}
//rule desc
if (pRuleData->pszRuleDescription)
{
pRule->pszDescription = IPSecAllocPolStr(pRuleData->pszRuleDescription);
if(pRule->pszDescription==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
}
RpcStat = UuidCreate(&(pRule->NFAIdentifier));
if (!(RpcStat == RPC_S_OK || RpcStat == RPC_S_UUID_LOCAL_ONLY))
{
dwReturn=ERROR_INVALID_PARAMETER;
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_STATIC_INTERNAL_ERROR);
BAIL_OUT;
}
pRule->dwWhenChanged = 0;
//filterlist
pRule->pIpsecFilterData = NULL;
pRule->FilterIdentifier = pFilterData->FilterIdentifier;
//filteraction
pRule->pIpsecNegPolData = NULL;
pRule->NegPolIdentifier = pNegPolData->NegPolIdentifier;
// tunnel address
pRule->dwTunnelFlags = 0;
pRule->dwTunnelIpAddr= 0;
if (pRuleData->bTunnel)
{
pRule->dwTunnelFlags = 1;
pRule->dwTunnelIpAddr = pRuleData->TunnelIPAddress;
}
// interface type
if (pRuleData->ConnectionType == INTERFACE_TYPE_ALL)
{
pRule->dwInterfaceType = (DWORD)PAS_INTERFACE_TYPE_ALL;
}
else if (pRuleData->ConnectionType == INTERFACE_TYPE_LAN)
{
pRule->dwInterfaceType = (DWORD)PAS_INTERFACE_TYPE_LAN;
}
else if (pRuleData->ConnectionType == INTERFACE_TYPE_DIALUP)
{
pRule->dwInterfaceType = (DWORD)PAS_INTERFACE_TYPE_DIALUP;
}
else
{
pRule->dwInterfaceType = (DWORD)PAS_INTERFACE_TYPE_NONE;
}
// active flag
pRule->dwActiveFlag = pRuleData->bActivate;
// auth methods
pRule->dwAuthMethodCount = pRuleData->AuthInfos.dwNumAuthInfos;
pRule->ppAuthMethods = (PIPSEC_AUTH_METHOD *) IPSecAllocPolMem(pRule->dwAuthMethodCount * sizeof(PIPSEC_AUTH_METHOD));
if(pRule->ppAuthMethods==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
dwReturn = LoadAuthenticationInfos(pRuleData->AuthInfos, pRule,bCertConversionSuceeded);
error:
if(dwReturn == ERROR_OUTOFMEMORY || dwReturn == ERROR_INVALID_PARAMETER)
{
if(pRule)
{
CleanUpAuthInfo(pRule); //this function frees only auth info.
IPSecFreePolMem(pRule); //since the above fn is used in other fns also, this free is required to cleanup other rule memory
pRule = NULL;
}
}
return pRule;
}
////////////////////////////////////////////////////////////
//
//Function: DecodeCertificateName()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN LPBYTE EncodedName,
// IN DWORD EncodedNameLength,
// IN OUT LPTSTR *ppszSubjectName
//
//Return: DWORD
//
//Description:
// This function decodes the certificate name based on the user input.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
DecodeCertificateName (
IN LPBYTE EncodedName,
IN DWORD EncodedNameLength,
IN OUT LPTSTR *ppszSubjectName
)
{
DWORD DecodedNameLength=0, dwReturn=ERROR_SUCCESS;
CERT_NAME_BLOB CertName;
CertName.cbData = EncodedNameLength;
CertName.pbData = EncodedName;
//this API call is to get the size
DecodedNameLength = CertNameToStr(
X509_ASN_ENCODING,
&CertName,
CERT_X500_NAME_STR,
NULL,
NULL);
if (!DecodedNameLength)
{
dwReturn = ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
(*ppszSubjectName)= new _TCHAR[DecodedNameLength];
if (*ppszSubjectName == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
//this API call is for conversion
DecodedNameLength = CertNameToStr(
X509_ASN_ENCODING,
&CertName,
CERT_X500_NAME_STR,
*ppszSubjectName,
DecodedNameLength);
if (!DecodedNameLength)
{
delete (*ppszSubjectName);
(*ppszSubjectName) = 0;
dwReturn = ERROR_INVALID_PARAMETER;
}
error:
return dwReturn;
}
////////////////////////////////////////////////////////////
//
//Function: AddRule()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN OUT PIPSEC_POLICY_DATA pPolicy,
// IN PRULEDATA pRuleData,
// IN PIPSEC_NEGPOL_DATA pNegPolData,
// IN PIPSEC_FILTER_DATA pFilterData ,
// IN HANDLE hPolicyStorage
//
//Return: DWORD
//
//Description:
// This function adds the already formed NFA structure to the policy specified.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
AddRule(
IN OUT PIPSEC_POLICY_DATA pPolicy,
IN PRULEDATA pRuleData,
IN PIPSEC_NEGPOL_DATA pNegPolData,
IN PIPSEC_FILTER_DATA pFilterData ,
IN HANDLE hPolicyStorage
)
{
DWORD dwReturnCode = ERROR_SUCCESS;
BOOL bCertConversionSuceeded=TRUE;
PIPSEC_NFA_DATA pRule = MakeRule(pRuleData, pNegPolData, pFilterData,bCertConversionSuceeded);
if(pRule ==NULL)
{
dwReturnCode = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
if(!bCertConversionSuceeded)
{
dwReturnCode = ERROR_INVALID_DATA;
BAIL_OUT;
}
// form rule data structures
pPolicy->dwNumNFACount++;
pPolicy->ppIpsecNFAData = (PIPSEC_NFA_DATA *) ReAllocRuleMem(pPolicy->ppIpsecNFAData
, (pPolicy->dwNumNFACount-1), pPolicy->dwNumNFACount);
if(pPolicy->ppIpsecNFAData ==NULL)
{
dwReturnCode = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
pPolicy->ppIpsecNFAData[pPolicy->dwNumNFACount-1] = pRule;
// Create Rule
dwReturnCode=IPSecCreateNFAData(hPolicyStorage, pPolicy->PolicyIdentifier, pRule);
if(dwReturnCode==ERROR_SUCCESS)
{
dwReturnCode=SetPolicyData(hPolicyStorage, pPolicy);
}
error:
if(dwReturnCode == ERROR_OUTOFMEMORY)
{
PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
dwReturnCode = ERROR_SUCCESS;
}
return dwReturnCode;
}
////////////////////////////////////////////////////////////
//
//Function: LoadIkeDefaults()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN PPOLICYDATA pPolicy,
// OUT IPSEC_MM_OFFER **ppIpSecMMOffer
//
//Return: DWORD
//
//Description:
// This function loads the IKE default values
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
LoadIkeDefaults(
IN PPOLICYDATA pPolicy,
OUT IPSEC_MM_OFFER **ppIpSecMMOffer
)
{
DWORD dwReturn = ERROR_SUCCESS;
pPolicy->dwOfferCount = 3;
IPSEC_MM_OFFER *pOffers = new IPSEC_MM_OFFER[pPolicy->dwOfferCount];
if(pOffers == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pOffers, 0, sizeof(IPSEC_MM_OFFER) * (pPolicy->dwOfferCount));
// init these
for (DWORD i = 0; i < pPolicy->dwOfferCount; ++i)
{
pOffers[i].dwQuickModeLimit = pPolicy->dwQMLimit;
pOffers[i].Lifetime.uKeyExpirationKBytes = 0;
pOffers[i].Lifetime.uKeyExpirationTime = pPolicy->LifeTimeInSeconds;
}
// 3DES-SHA1-2
pOffers[0].EncryptionAlgorithm.uAlgoIdentifier = CONF_ALGO_3_DES;
pOffers[0].EncryptionAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
pOffers[0].EncryptionAlgorithm.uAlgoRounds = POTF_OAKLEY_ALGOROUNDS;
pOffers[0].HashingAlgorithm.uAlgoIdentifier = AUTH_ALGO_SHA1;
pOffers[0].HashingAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
pOffers[0].dwDHGroup = POTF_OAKLEY_GROUP2;
// 3DES-MD5-2
pOffers[1].EncryptionAlgorithm.uAlgoIdentifier = CONF_ALGO_3_DES;
pOffers[1].EncryptionAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
pOffers[1].EncryptionAlgorithm.uAlgoRounds = POTF_OAKLEY_ALGOROUNDS;
pOffers[1].HashingAlgorithm.uAlgoIdentifier = AUTH_ALGO_MD5;
pOffers[1].HashingAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
pOffers[1].dwDHGroup = POTF_OAKLEY_GROUP2;
// 3DES-SHA1-3
pOffers[2].EncryptionAlgorithm.uAlgoIdentifier = CONF_ALGO_3_DES;
pOffers[2].EncryptionAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
pOffers[2].EncryptionAlgorithm.uAlgoRounds = POTF_OAKLEY_ALGOROUNDS;
pOffers[2].HashingAlgorithm.uAlgoIdentifier = AUTH_ALGO_SHA1;
pOffers[2].HashingAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
pOffers[2].dwDHGroup = POTF_OAKLEY_GROUP2048;
*ppIpSecMMOffer=pOffers;
error:
return dwReturn;
}
////////////////////////////////////////////////////////////
//
//Function: LoadOfferDefaults()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// OUT PIPSEC_QM_OFFER & pOffers,
// OUT DWORD & dwNumOffers
//
//Return: DWORD
//
//Description:
// This function fills the Offers structure with default values
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
LoadOfferDefaults(
OUT PIPSEC_QM_OFFER & pOffers,
OUT DWORD & dwNumOffers
)
{
DWORD dwReturn = ERROR_SUCCESS;
dwNumOffers = 2;
DWORD i=0;
pOffers = new IPSEC_QM_OFFER[dwNumOffers];
if(pOffers == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(pOffers, 0, sizeof(IPSEC_QM_OFFER) * dwNumOffers);
for (i = 0; i < dwNumOffers; ++i)
{
pOffers[i].Lifetime.uKeyExpirationKBytes = POTF_DEFAULT_P2REKEY_BYTES;
pOffers[i].Lifetime.uKeyExpirationTime = POTF_DEFAULT_P2REKEY_TIME;
pOffers[i].bPFSRequired = FALSE;
pOffers[i].dwPFSGroup = 0;
pOffers[i].dwFlags = 0;
pOffers[i].dwNumAlgos = 1;
pOffers[i].Algos[0].Operation = ENCRYPTION;
}
//esp[3des,sha1]
pOffers[0].Algos[0].uAlgoIdentifier = CONF_ALGO_3_DES;
pOffers[0].Algos[0].uSecAlgoIdentifier = HMAC_AUTH_ALGO_SHA1;
//esp[3des,md5]
pOffers[1].Algos[0].uAlgoIdentifier = CONF_ALGO_3_DES;
pOffers[1].Algos[0].uSecAlgoIdentifier = HMAC_AUTH_ALGO_MD5;
error:
return dwReturn;
}
////////////////////////////////////////////////////////////
//
//Function: CheckPolicyExistance()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN HANDLE hPolicyStorage,
// IN LPTSTR pszPolicyName
//
//Return: BOOL
//
//Description:
// This function checks whether the specified policy exists in Policy store.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
BOOL
CheckPolicyExistance(
IN HANDLE hPolicyStorage,
IN LPTSTR pszPolicyName
)
{
PIPSEC_POLICY_DATA *ppPolicyEnum = NULL;
BOOL bPolicyExists=FALSE;
DWORD dwNumPolicies=0;
DWORD dwReturnCode=ERROR_SUCCESS;
// check whether the policy already exists in store
dwReturnCode = IPSecEnumPolicyData(hPolicyStorage, &ppPolicyEnum, &dwNumPolicies);
if (dwReturnCode == ERROR_SUCCESS && dwNumPolicies > 0 && ppPolicyEnum != NULL)
{
for (DWORD i = 0; i < dwNumPolicies; i++)
if (_tcscmp(ppPolicyEnum[i]->pszIpsecName, pszPolicyName) == 0)
{
bPolicyExists=TRUE;
break;
}
if (dwNumPolicies > 0 && ppPolicyEnum != NULL)
{
IPSecFreeMulPolicyData(ppPolicyEnum, dwNumPolicies);
}
}
return bPolicyExists;
}
////////////////////////////////////////////////////////////
//
//Function: ReAllocRuleMem()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN PIPSEC_NFA_DATA *ppOldMem,
// IN DWORD cbOld,
// IN DWORD cbNew
//
//Return: PIPSEC_NFA_DATA*
//
//Description:
// This function reallocates the memory for the NFA structure.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
PIPSEC_NFA_DATA*
ReAllocRuleMem(
IN PIPSEC_NFA_DATA *ppOldMem,
IN DWORD cbOld,
IN DWORD cbNew
)
{
PIPSEC_NFA_DATA * ppNewMem=NULL;
DWORD j=0;
//reallocate the NFA mem
ppNewMem= (PIPSEC_NFA_DATA *) IPSecAllocPolMem(cbNew * sizeof(PIPSEC_NFA_DATA));
if (ppNewMem)
{
for(DWORD i=0;i<min(cbNew, cbOld);i++)
{
while(!ppOldMem[j])
j++;
ppNewMem[i]=ppOldMem[j];
j++;
}
IPSecFreePolMem(ppOldMem);
}
return ppNewMem;
}
////////////////////////////////////////////////////////////
//
//Function: ReAllocFilterSpecMem()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN PIPSEC_FILTER_SPEC * ppOldMem,
// IN DWORD cbOld,
// IN DWORD cbNew
//
//Return: PIPSEC_FILTER_SPEC *
//
//Description:
// This function reallocates the Filter Spec memory
//
//Revision History:
//
//<Version number, Change request number, Date of modification,
// Author, Nature of change>
////////////////////////////////////////////////////////////
PIPSEC_FILTER_SPEC *
ReAllocFilterSpecMem(
IN PIPSEC_FILTER_SPEC * ppOldMem,
IN DWORD cbOld,
IN DWORD cbNew
)
{
PIPSEC_FILTER_SPEC * ppNewMem=NULL;
DWORD j=0;
ppNewMem= (PIPSEC_FILTER_SPEC *) IPSecAllocPolMem(cbNew * sizeof(PIPSEC_FILTER_SPEC));
// reallocate the filterspec memory
if(ppNewMem)
{
for(DWORD i=0;i<min(cbNew, cbOld);i++)
{
while(!ppOldMem[j])
j++;
ppNewMem[i]=ppOldMem[j];
j++;
}
IPSecFreePolMem(ppOldMem);
}
return ppNewMem;
}
////////////////////////////////////////////////////////////
//
//Function: ValidateFilterSpec()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN PPOLICYDATA pPolicyData
//
//Return: DWORD
//
//Description:
// This function validates the Filter Spec details
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
ValidateFilterSpec(
IN PFILTERDATA pFilterData
)
{
DWORD dwReturn=ERROR_SUCCESS;
ADDR SrcAddr,DstAddr;
SrcAddr.uIpAddr=htonl(pFilterData->SourceAddr.puIpAddr[0]);
SrcAddr.uSubNetMask=htonl(pFilterData->SourMask);
DstAddr.uIpAddr=htonl(pFilterData->DestnAddr.puIpAddr[0]);
DstAddr.uSubNetMask=htonl(pFilterData->DestMask);
if(!pFilterData->SourceAddr.pszDomainName)
{
// if only IP addr specified
if(pFilterData->bSrcAddrSpecified && !pFilterData->bSrcMaskSpecified)
{
if(pFilterData->SourceAddr.puIpAddr[0]!=0)
{
if(!bIsValidIPAddress(htonl(pFilterData->SourceAddr.puIpAddr[0]),TRUE,TRUE))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTER_6);
dwReturn=ERROR_INVALID_DATA;
BAIL_OUT;
}
}
}
else if(pFilterData->bSrcAddrSpecified && pFilterData->bSrcMaskSpecified)
{
// if both IP and mask specified
if(!((pFilterData->SourceAddr.puIpAddr[0]==0) && ((pFilterData->SourMask==0)||(pFilterData->SourMask==MASK_ME))))
{
SrcAddr.AddrType= IP_ADDR_UNIQUE;
if (!IsValidSubnettedAddress(&SrcAddr) && !IsValidSubnet(&SrcAddr))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTER_7);
dwReturn=ERROR_INVALID_DATA;
BAIL_OUT;
}
}
}
}
if(!pFilterData->DestnAddr.pszDomainName)
{
// if only IP addr specified
if(pFilterData->bDstAddrSpecified && !pFilterData->bDstMaskSpecified)
{
if(pFilterData->DestnAddr.puIpAddr[0]!=0)
{
if(!bIsValidIPAddress(htonl(pFilterData->DestnAddr.puIpAddr[0]),TRUE,TRUE))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTER_11);
dwReturn=ERROR_INVALID_DATA;
BAIL_OUT;
}
}
}
else if(pFilterData->bDstAddrSpecified && pFilterData->bDstMaskSpecified)
{
// if both IP and mask specified
if(!((pFilterData->DestnAddr.puIpAddr[0]==0)&& ((pFilterData->DestMask==0)||(pFilterData->DestMask==MASK_ME))))
{
DstAddr.AddrType= IP_ADDR_UNIQUE;
if(!IsValidSubnettedAddress(&DstAddr) && !IsValidSubnet(&DstAddr))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTER_12);
dwReturn=ERROR_INVALID_DATA;
BAIL_OUT;
}
}
}
}
if(!pFilterData->DestnAddr.pszDomainName && !pFilterData->SourceAddr.pszDomainName)
{
// check for address conflict
if(!(pFilterData->bSrcServerSpecified || pFilterData->bDstServerSpecified))
{
SrcAddr.AddrType=IP_ADDR_SUBNET;
DstAddr.AddrType=IP_ADDR_SUBNET;
if(AddressesConflict(SrcAddr,DstAddr))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTER_8);
dwReturn=ERROR_INVALID_DATA;
BAIL_OUT;
}
}
}
if(pFilterData->DestnAddr.pszDomainName && pFilterData->SourceAddr.pszDomainName)
{
// check for same src and dst DNS names
if(_tcscmp(pFilterData->SourceAddr.pszDomainName,pFilterData->DestnAddr.pszDomainName)==0)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTER_8);
dwReturn=ERROR_INVALID_DATA;
BAIL_OUT;
}
}
if(pFilterData->bSrcServerSpecified || pFilterData->bDstServerSpecified)
{
//validate special server
if(!IsSpecialServ(ExTypeToAddrType(pFilterData->ExType)))
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTER_9);
dwReturn=ERROR_INVALID_DATA;
BAIL_OUT;
}
}
if(pFilterData->bSrcServerSpecified || pFilterData->bDstServerSpecified)
{
if(pFilterData->ExType==EXT_NORMAL)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTER_10);
dwReturn=ERROR_INVALID_DATA;
BAIL_OUT;
}
}
if(pFilterData->bSrcServerSpecified && pFilterData->bDstServerSpecified)
{
// check if both sides servers specified
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_FILTER_3);
dwReturn=ERROR_INVALID_DATA;
}
error:
return dwReturn;
}
////////////////////////////////////////////////////////////
//
//Function: CheckFilterListExistance()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN HANDLE hPolicyStorage,
// IN LPTSTR pszFLName
//
//Return: BOOL
//
//Description:
// This function checks whether the specified filterlist exists in Policy store.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
BOOL
CheckFilterListExistance(
IN HANDLE hPolicyStorage,
IN LPTSTR pszFLName
)
{
PIPSEC_FILTER_DATA *ppFilterEnum = NULL;
BOOL bFilterExists=FALSE;
DWORD dwNumFilters=0;
DWORD dwReturnCode=ERROR_SUCCESS;
// check for duplicate Filterlist on same name
dwReturnCode = IPSecEnumFilterData(hPolicyStorage, &ppFilterEnum, &dwNumFilters);
if (dwReturnCode == ERROR_SUCCESS && dwNumFilters > 0 && ppFilterEnum != NULL)
{
DWORD i;
for (i = 0; i < dwNumFilters; i++)
{
if ( pszFLName && ppFilterEnum[i]->pszIpsecName && ( _tcscmp(ppFilterEnum[i]->pszIpsecName, pszFLName) == 0))
{
bFilterExists=TRUE;
break;
}
}
if(ppFilterEnum && dwNumFilters>0)
{
IPSecFreeMulFilterData( ppFilterEnum,dwNumFilters);
}
}
return bFilterExists;
}
////////////////////////////////////////////////////////////
//
//Function: CheckFilterActionExistance()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN HANDLE hPolicyStorage,
// IN LPTSTR pszFAName
//
//Return: BOOL
//
//Description:
// This function checks whether the specified filteraction exists in Policy store.
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
BOOL
CheckFilterActionExistance(
IN HANDLE hPolicyStorage,
IN LPTSTR pszFAName
)
{
PIPSEC_NEGPOL_DATA *ppNegPolEnum = NULL;
BOOL bNegPolExists=FALSE;
DWORD dwNumNegPol=0;
DWORD dwReturnCode=ERROR_SUCCESS;
// check for duplicate Filteraction on same name
dwReturnCode = IPSecEnumNegPolData(hPolicyStorage, &ppNegPolEnum, &dwNumNegPol);
if (dwReturnCode == ERROR_SUCCESS && dwNumNegPol> 0 && ppNegPolEnum != NULL)
{
DWORD i;
for (i = 0; i < dwNumNegPol; i++)
{
if (ppNegPolEnum[i]->pszIpsecName && pszFAName && ( _tcscmp(ppNegPolEnum[i]->pszIpsecName, pszFAName) == 0))
{
bNegPolExists=TRUE;
break;
}
}
if (dwNumNegPol > 0 && ppNegPolEnum != NULL)
{
IPSecFreeMulNegPolData( ppNegPolEnum,dwNumNegPol);
}
}
return bNegPolExists;
}
////////////////////////////////////////////////////////////
//
//Function: LoadAuthenticationInfos()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN INT_MM_AUTH_METHODS AuthInfos,
// IN OUT PIPSEC_NFA_DATA &pRule
//
//Return: DWORD
//
//Description:
// This function loads the authentication details
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
LoadAuthenticationInfos(
IN STA_AUTH_METHODS AuthInfos,
IN OUT PIPSEC_NFA_DATA &pRule,
IN OUT BOOL &bCertConversionSuceeded
)
{
DWORD dwReturn = ERROR_SUCCESS;
BOOL bWarningPrinted = FALSE;
for (DWORD i = 0; i < pRule->dwAuthMethodCount; i++)
{
pRule->ppAuthMethods[i] = (PIPSEC_AUTH_METHOD) IPSecAllocPolMem(sizeof(IPSEC_AUTH_METHOD));
if(pRule->ppAuthMethods[i]== NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
ZeroMemory(pRule->ppAuthMethods[i], sizeof(IPSEC_AUTH_METHOD));
pRule->ppAuthMethods[i]->dwAuthType = AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo->AuthMethod;
if (pRule->ppAuthMethods[i]->dwAuthType == IKE_SSPI) //kerb
{
pRule->ppAuthMethods[i]->dwAuthLen = 0;
pRule->ppAuthMethods[i]->pszAuthMethod = NULL;
pRule->ppAuthMethods[i]->dwAltAuthLen = 0;
pRule->ppAuthMethods[i]->pAltAuthMethod = NULL;
pRule->ppAuthMethods[i]->dwAuthFlags = 0;
}
else if (pRule->ppAuthMethods[i]->dwAuthType == IKE_RSA_SIGNATURE) //cert
{
LPTSTR pTemp = NULL;
pRule->ppAuthMethods[i]->dwAuthFlags = AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo->dwAuthFlags;
pRule->ppAuthMethods[i]->dwAltAuthLen = AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo->dwAuthInfoSize;
pRule->ppAuthMethods[i]->pAltAuthMethod = (PBYTE) IPSecAllocPolMem(AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo->dwAuthInfoSize);
if(pRule->ppAuthMethods[i]->pAltAuthMethod==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memcpy(pRule->ppAuthMethods[i]->pAltAuthMethod, AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo->pAuthInfo, AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo->dwAuthInfoSize);
dwReturn = DecodeCertificateName(pRule->ppAuthMethods[i]->pAltAuthMethod, pRule->ppAuthMethods[i]->dwAltAuthLen, &pTemp);
if(dwReturn != ERROR_SUCCESS)
{
PrintErrorMessage(IPSEC_ERR,0,ERRCODE_ADD_STATIC_RULE_UPDATING_INFO);
bCertConversionSuceeded=FALSE;
}
pRule->ppAuthMethods[i]->pszAuthMethod = IPSecAllocPolStr(pTemp);
if(pRule->ppAuthMethods[i]->pszAuthMethod == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
pRule->ppAuthMethods[i]->dwAuthLen = wcslen(pRule->ppAuthMethods[i]->pszAuthMethod);
delete [] pTemp;
}
else if (pRule->ppAuthMethods[i]->dwAuthType == IKE_PRESHARED_KEY) //preshared key
{
pRule->ppAuthMethods[i]->dwAuthLen = AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo->dwAuthInfoSize / sizeof(WCHAR);
pRule->ppAuthMethods[i]->pszAuthMethod = (LPWSTR) IPSecAllocPolMem(AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo->dwAuthInfoSize + sizeof(WCHAR));
if(pRule->ppAuthMethods[i]->pszAuthMethod==NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memcpy(pRule->ppAuthMethods[i]->pszAuthMethod, AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo->pAuthInfo, AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo->dwAuthInfoSize);
pRule->ppAuthMethods[i]->pszAuthMethod[pRule->ppAuthMethods[i]->dwAuthLen] = 0;
pRule->ppAuthMethods[i]->dwAltAuthLen = 0;
pRule->ppAuthMethods[i]->pAltAuthMethod = NULL;
pRule->ppAuthMethods[i]->dwAuthFlags = 0;
}
}
error:
return dwReturn;
}
////////////////////////////////////////////////////////////
//
//Function: ConvertMMAuthToStaticLocal()
//
//Date of Creation: 21st Aug 2001
//
//Parameters:
// IN PINT_IPSEC_MM_AUTH_INFO pAuthenticationInfo,
// IN DWORD dwAuthInfos,
// IN OUT STA_AUTH_METHODS &AuthInfos
//
//Return: DWORD
//
//Description:
// This function converts the PINT_IPSEC_MM_AUTH_INFO structure to STA_AUTH_METHODS
//
//Revision History:
//
// Date Author Comments
//
////////////////////////////////////////////////////////////
DWORD
ConvertMMAuthToStaticLocal(
IN PINT_IPSEC_MM_AUTH_INFO pAuthenticationInfo,
IN DWORD dwAuthInfos,
IN OUT STA_AUTH_METHODS &AuthInfos
)
{
DWORD dwReturn = ERROR_SUCCESS;
DWORD i = 0 ;
if(pAuthenticationInfo == NULL || dwAuthInfos == 0 )
{
dwReturn = ERROR_INVALID_PARAMETER;
BAIL_OUT;
}
AuthInfos.dwNumAuthInfos = dwAuthInfos;
AuthInfos.pAuthMethodInfo = new STA_MM_AUTH_METHODS[AuthInfos.dwNumAuthInfos];
if(AuthInfos.pAuthMethodInfo == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
for(i=0;i<AuthInfos.dwNumAuthInfos;i++)
{
memset(&(AuthInfos.pAuthMethodInfo[i]),0,sizeof(STA_MM_AUTH_METHODS));
AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo = new INT_IPSEC_MM_AUTH_INFO;
if(AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo == NULL)
{
dwReturn = ERROR_OUTOFMEMORY;
BAIL_OUT;
}
memset(AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo ,0,sizeof(INT_IPSEC_MM_AUTH_INFO));
memcpy( AuthInfos.pAuthMethodInfo[i].pAuthenticationInfo , &(pAuthenticationInfo[i]),sizeof(INT_IPSEC_MM_AUTH_INFO));
}
error:
return dwReturn;
}
DWORD
ConnectStaticMachine(
IN LPCWSTR pwszMachine,
IN DWORD dwLocation
)
{
DWORD dwReturnCode;
HANDLE hPolicyStorage;
LPWSTR pszTarget = NULL;
// Connect to the appropriate store
//
dwReturnCode =
IPSecOpenPolicyStore(
(LPWSTR)pwszMachine,
dwLocation,
NULL,
&hPolicyStorage);
if (dwReturnCode == ERROR_SUCCESS)
{
if (dwLocation == IPSEC_DIRECTORY_PROVIDER)
{
pszTarget = g_StorageLocation.pszDomainName;
}
else
{
pszTarget = g_StorageLocation.pszMachineName;
}
if (pwszMachine)
{
_tcsncpy(pszTarget, pwszMachine,MAXCOMPUTERNAMELEN-1);
}
else
{
_tcsncpy(pszTarget, _TEXT(""), 2);
}
g_StorageLocation.dwLocation = dwLocation;
g_NshPolStoreHandle.SetStorageHandle(hPolicyStorage);
}
return dwReturnCode;
}