//////////////////////////////////////////////////////////// // 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;idwOfferCount;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;dwCountpszPolicyName = 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;dwCountFilterIdentifier)); 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;dwCountpszFLName = 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 - 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;dwCountpszFADescription = 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;dwCountNegPolAction=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 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; dwCountpszRuleName = 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 //////////////////////////////////////////////////////////// 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;iSourceAddr.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