1208 lines
27 KiB
C
1208 lines
27 KiB
C
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
DWORD
|
|
ValidateMMPolicy(
|
|
PIPSEC_MM_POLICY pMMPolicy
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
|
|
|
|
if (!pMMPolicy) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (!(pMMPolicy->pszPolicyName) || !(*(pMMPolicy->pszPolicyName))) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = ValidateMMOffers(
|
|
pMMPolicy->dwOfferCount,
|
|
pMMPolicy->pOffers
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ValidateMMOffers(
|
|
DWORD dwOfferCount,
|
|
PIPSEC_MM_OFFER pOffers
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
DWORD i = 0;
|
|
PIPSEC_MM_OFFER pTemp = NULL;
|
|
|
|
|
|
if (!dwOfferCount || !pOffers || (dwOfferCount > IPSEC_MAX_MM_OFFERS)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
//
|
|
// Need to catch the exception when the number of offers
|
|
// specified is more than the actual number of offers.
|
|
//
|
|
|
|
|
|
pTemp = pOffers;
|
|
|
|
for (i = 0; i < dwOfferCount; i++) {
|
|
|
|
if ((pTemp->dwDHGroup != DH_GROUP_1) &&
|
|
(pTemp->dwDHGroup != DH_GROUP_2)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTemp->EncryptionAlgorithm.uAlgoIdentifier >= IPSEC_DOI_ESP_MAX) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTemp->HashingAlgorithm.uAlgoIdentifier >= IPSEC_DOI_AH_MAX) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
pTemp++;
|
|
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ValidateMMAuthMethods(
|
|
PMM_AUTH_METHODS pMMAuthMethods
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
DWORD i = 0;
|
|
PIPSEC_MM_AUTH_INFO pTemp = NULL;
|
|
DWORD dwNumAuthInfos = 0;
|
|
PIPSEC_MM_AUTH_INFO pAuthenticationInfo = NULL;
|
|
BOOL bSSPI = FALSE;
|
|
BOOL bPresharedKey = FALSE;
|
|
|
|
|
|
if (!pMMAuthMethods) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwNumAuthInfos = pMMAuthMethods->dwNumAuthInfos;
|
|
pAuthenticationInfo = pMMAuthMethods->pAuthenticationInfo;
|
|
|
|
if (!dwNumAuthInfos || !pAuthenticationInfo) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
//
|
|
// Need to catch the exception when the number of auth infos
|
|
// specified is more than the actual number of auth infos.
|
|
//
|
|
|
|
|
|
pTemp = pAuthenticationInfo;
|
|
|
|
for (i = 0; i < dwNumAuthInfos; i++) {
|
|
|
|
if ((pTemp->AuthMethod != IKE_PRESHARED_KEY) &&
|
|
(pTemp->AuthMethod != IKE_RSA_SIGNATURE) &&
|
|
(pTemp->AuthMethod != IKE_SSPI)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTemp->AuthMethod != IKE_SSPI) {
|
|
if (!(pTemp->dwAuthInfoSize) || !(pTemp->pAuthInfo)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
if (pTemp->AuthMethod == IKE_SSPI) {
|
|
if (bSSPI) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
bSSPI = TRUE;
|
|
}
|
|
|
|
if (pTemp->AuthMethod == IKE_PRESHARED_KEY) {
|
|
if (bPresharedKey) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
bPresharedKey = TRUE;
|
|
}
|
|
|
|
pTemp++;
|
|
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ValidateQMPolicy(
|
|
PIPSEC_QM_POLICY pQMPolicy
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
|
|
|
|
if (!pQMPolicy) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (!(pQMPolicy->pszPolicyName) || !(*(pQMPolicy->pszPolicyName))) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = ValidateQMOffers(
|
|
pQMPolicy->dwOfferCount,
|
|
pQMPolicy->pOffers
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ValidateQMOffers(
|
|
DWORD dwOfferCount,
|
|
PIPSEC_QM_OFFER pOffers
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
DWORD i = 0;
|
|
PIPSEC_QM_OFFER pTemp = NULL;
|
|
DWORD j = 0;
|
|
BOOL bAH = FALSE;
|
|
BOOL bESP = FALSE;
|
|
DWORD dwQMGroup = PFS_GROUP_NONE;
|
|
|
|
|
|
if (!dwOfferCount || !pOffers || (dwOfferCount > IPSEC_MAX_QM_OFFERS)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
//
|
|
// Need to catch the exception when the number of offers
|
|
// specified is more than the actual number of offers.
|
|
//
|
|
|
|
|
|
pTemp = pOffers;
|
|
|
|
if (pTemp->bPFSRequired) {
|
|
if ((pTemp->dwPFSGroup != PFS_GROUP_1) &&
|
|
(pTemp->dwPFSGroup != PFS_GROUP_2) &&
|
|
(pTemp->dwPFSGroup != PFS_GROUP_MM)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
dwQMGroup=pTemp->dwPFSGroup;
|
|
}
|
|
else {
|
|
if (pTemp->dwPFSGroup != PFS_GROUP_NONE) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < dwOfferCount; i++) {
|
|
|
|
if (dwQMGroup) {
|
|
if ((!pTemp->bPFSRequired) || (pTemp->dwPFSGroup != dwQMGroup)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
} else {
|
|
if ((pTemp->bPFSRequired) || (pTemp->dwPFSGroup != PFS_GROUP_NONE)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
if (!(pTemp->dwNumAlgos) || (pTemp->dwNumAlgos > QM_MAX_ALGOS)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
bAH = FALSE;
|
|
bESP = FALSE;
|
|
|
|
for (j = 0; j < (pTemp->dwNumAlgos); j++) {
|
|
|
|
switch (pTemp->Algos[j].Operation) {
|
|
|
|
case AUTHENTICATION:
|
|
if (bAH) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
if ((pTemp->Algos[j].uAlgoIdentifier == IPSEC_DOI_AH_NONE) ||
|
|
(pTemp->Algos[j].uAlgoIdentifier >= IPSEC_DOI_AH_MAX)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
if (pTemp->Algos[j].uSecAlgoIdentifier != HMAC_AH_NONE) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
bAH = TRUE;
|
|
break;
|
|
|
|
case ENCRYPTION:
|
|
if (bESP) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
if (pTemp->Algos[j].uAlgoIdentifier >= IPSEC_DOI_ESP_MAX) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
if (pTemp->Algos[j].uSecAlgoIdentifier >= HMAC_AH_MAX) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
if (pTemp->Algos[j].uAlgoIdentifier == IPSEC_DOI_ESP_NONE) {
|
|
if (pTemp->Algos[j].uSecAlgoIdentifier == HMAC_AH_NONE) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
}
|
|
bESP = TRUE;
|
|
break;
|
|
|
|
case NONE:
|
|
case COMPRESSION:
|
|
default:
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pTemp++;
|
|
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ValidateMMFilter(
|
|
PMM_FILTER pMMFilter
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function validates an external generic MM filter.
|
|
|
|
Arguments:
|
|
|
|
pMMFilter - Filter to validate.
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS - Success.
|
|
|
|
Win32 Error - Failure.
|
|
|
|
--*/
|
|
{
|
|
DWORD dwError = 0;
|
|
BOOL bConflicts = FALSE;
|
|
|
|
|
|
if (!pMMFilter) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyAddresses(pMMFilter->SrcAddr, TRUE , FALSE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyAddresses(pMMFilter->DesAddr, TRUE , TRUE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
bConflicts = AddressesConflict(
|
|
pMMFilter->SrcAddr,
|
|
pMMFilter->DesAddr
|
|
);
|
|
if (bConflicts) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (!(pMMFilter->pszFilterName) || !(*(pMMFilter->pszFilterName))) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pMMFilter->InterfaceType >= INTERFACE_TYPE_MAX) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pMMFilter->dwFlags &&
|
|
!(pMMFilter->dwFlags & IPSEC_MM_POLICY_DEFAULT_POLICY) &&
|
|
!(pMMFilter->dwFlags & IPSEC_MM_AUTH_DEFAULT_AUTH)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = ApplyMulticastFilterValidation(
|
|
pMMFilter->DesAddr,
|
|
pMMFilter->bCreateMirror
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
VerifyAddresses(
|
|
ADDR Addr,
|
|
BOOL bAcceptMe,
|
|
BOOL bIsDesAddr
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
BOOL bIsValid = FALSE;
|
|
|
|
switch (Addr.AddrType) {
|
|
|
|
case IP_ADDR_UNIQUE:
|
|
bIsValid = bIsValidIPAddress(
|
|
ntohl(Addr.uIpAddr),
|
|
bAcceptMe,
|
|
bIsDesAddr
|
|
);
|
|
if (!bIsValid) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
break;
|
|
|
|
case IP_ADDR_SUBNET:
|
|
dwError = VerifySubNetAddress(
|
|
ntohl(Addr.uIpAddr),
|
|
ntohl(Addr.uSubNetMask),
|
|
bIsDesAddr
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
break;
|
|
|
|
case IP_ADDR_INTERFACE:
|
|
if (Addr.uIpAddr) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
break;
|
|
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
VerifySubNetAddress(
|
|
ULONG uSubNetAddr,
|
|
ULONG uSubNetMask,
|
|
BOOL bIsDesAddr
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
BOOL bIsValid = FALSE;
|
|
|
|
if (uSubNetAddr == SUBNET_ADDRESS_ANY) {
|
|
if (uSubNetMask != SUBNET_MASK_ANY) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
}
|
|
else {
|
|
bIsValid = bIsValidSubnet(
|
|
uSubNetAddr,
|
|
uSubNetMask,
|
|
bIsDesAddr
|
|
);
|
|
if (!bIsValid) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
BOOL
|
|
bIsValidIPMask(
|
|
ULONG uMask
|
|
)
|
|
{
|
|
BOOL bValidMask = FALSE;
|
|
ULONG uTestMask = 0;
|
|
|
|
//
|
|
// Mask must be contiguous bits.
|
|
//
|
|
|
|
for (uTestMask = 0xFFFFFFFF; uTestMask; uTestMask <<= 1) {
|
|
|
|
if (uTestMask == uMask) {
|
|
bValidMask = TRUE;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return (bValidMask);
|
|
}
|
|
|
|
|
|
BOOL
|
|
bIsValidIPAddress(
|
|
ULONG uIpAddr,
|
|
BOOL bAcceptMe,
|
|
BOOL bIsDesAddr
|
|
)
|
|
{
|
|
ULONG uHostMask = IN_CLASSA_HOST; // Default host mask.
|
|
|
|
|
|
//
|
|
// Accept the address if its "me".
|
|
//
|
|
|
|
if (bAcceptMe) {
|
|
if (uIpAddr == IP_ADDRESS_ME) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Reject if its a multicast address and is not the
|
|
// destination address.
|
|
//
|
|
|
|
if (IN_CLASSD(uIpAddr)) {
|
|
if (bIsDesAddr) {
|
|
return TRUE;
|
|
}
|
|
else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Reject if its a Class E address.
|
|
//
|
|
|
|
if (IN_CLASSE(uIpAddr)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Reject if the first octet is zero.
|
|
//
|
|
|
|
if (!(IN_CLASSA_NET & uIpAddr)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Use default mask based on Class when none is provided.
|
|
//
|
|
|
|
if (IN_CLASSA(uIpAddr)) {
|
|
uHostMask = IN_CLASSA_HOST;
|
|
}
|
|
else if (IN_CLASSB(uIpAddr)) {
|
|
uHostMask = IN_CLASSB_HOST;
|
|
}
|
|
else if (IN_CLASSC(uIpAddr)) {
|
|
uHostMask = IN_CLASSC_HOST;
|
|
}
|
|
|
|
//
|
|
// Accept address when host portion is non-zero.
|
|
//
|
|
|
|
if (uHostMask & uIpAddr) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
bIsValidSubnet(
|
|
ULONG uIpAddr,
|
|
ULONG uMask,
|
|
BOOL bIsDesAddr
|
|
)
|
|
{
|
|
ULONG uHostMask = 0;
|
|
|
|
|
|
//
|
|
// Reject if its a multicast address and is not the
|
|
// destination address.
|
|
//
|
|
|
|
if (IN_CLASSD(uIpAddr)) {
|
|
if (!bIsDesAddr) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Reject if its a Class E address.
|
|
//
|
|
|
|
if (IN_CLASSE(uIpAddr)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Reject if the first octet is zero.
|
|
//
|
|
|
|
if (!(IN_CLASSA_NET & uIpAddr)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If the mask is invalid then return.
|
|
//
|
|
|
|
if (!bIsValidIPMask(uMask)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Use the provided subnet mask to generate the host mask.
|
|
//
|
|
|
|
uHostMask = 0xFFFFFFFF ^ uMask;
|
|
|
|
//
|
|
// Validate the address and the mask.
|
|
//
|
|
|
|
if (IN_CLASSA(uIpAddr)) {
|
|
if (IN_CLASSA_NET > uMask) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
else if (IN_CLASSB(uIpAddr)) {
|
|
if (IN_CLASSB_NET > uMask) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
else if (IN_CLASSC(uIpAddr)) {
|
|
if (IN_CLASSC_NET > uMask) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Accept address only when the host portion is zero, network
|
|
// portion is non-zero and first octet is non-zero.
|
|
//
|
|
|
|
if (!(uHostMask & uIpAddr) &&
|
|
(uMask & uIpAddr) &&
|
|
(IN_CLASSA_NET & uIpAddr)) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
AddressesConflict(
|
|
ADDR SrcAddr,
|
|
ADDR DesAddr
|
|
)
|
|
{
|
|
if ((SrcAddr.AddrType == IP_ADDR_UNIQUE) &&
|
|
(DesAddr.AddrType == IP_ADDR_UNIQUE)) {
|
|
|
|
if (SrcAddr.uIpAddr == DesAddr.uIpAddr) {
|
|
return (TRUE);
|
|
}
|
|
|
|
}
|
|
|
|
if ((SrcAddr.AddrType == IP_ADDR_INTERFACE) &&
|
|
(DesAddr.AddrType == IP_ADDR_INTERFACE)) {
|
|
return (TRUE);
|
|
}
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ValidateTransportFilter(
|
|
PTRANSPORT_FILTER pTransportFilter
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
BOOL bConflicts = FALSE;
|
|
|
|
|
|
if (!pTransportFilter) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyAddresses(pTransportFilter->SrcAddr, TRUE, FALSE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyAddresses(pTransportFilter->DesAddr, TRUE, TRUE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
bConflicts = AddressesConflict(
|
|
pTransportFilter->SrcAddr,
|
|
pTransportFilter->DesAddr
|
|
);
|
|
if (bConflicts) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyProtocols(pTransportFilter->Protocol);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyPortsForProtocol(
|
|
pTransportFilter->SrcPort,
|
|
pTransportFilter->Protocol
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyPortsForProtocol(
|
|
pTransportFilter->DesPort,
|
|
pTransportFilter->Protocol
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
if (!(pTransportFilter->pszFilterName) || !(*(pTransportFilter->pszFilterName))) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTransportFilter->InterfaceType >= INTERFACE_TYPE_MAX) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTransportFilter->InboundFilterFlag >= FILTER_FLAG_MAX) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTransportFilter->OutboundFilterFlag >= FILTER_FLAG_MAX) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTransportFilter->dwFlags &&
|
|
!(pTransportFilter->dwFlags & IPSEC_QM_POLICY_DEFAULT_POLICY)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = ApplyMulticastFilterValidation(
|
|
pTransportFilter->DesAddr,
|
|
pTransportFilter->bCreateMirror
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
DWORD
|
|
ValidateIPSecQMFilter(
|
|
PIPSEC_QM_FILTER pQMFilter
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
BOOL bConflicts = FALSE;
|
|
|
|
if (!pQMFilter) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyAddresses(pQMFilter->SrcAddr, FALSE, FALSE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyAddresses(pQMFilter->DesAddr, FALSE, TRUE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
bConflicts = AddressesConflict(
|
|
pQMFilter->SrcAddr,
|
|
pQMFilter->DesAddr
|
|
);
|
|
if (bConflicts) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyProtocols(pQMFilter->Protocol);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyPortsForProtocol(
|
|
pQMFilter->SrcPort,
|
|
pQMFilter->Protocol
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyPortsForProtocol(
|
|
pQMFilter->DesPort,
|
|
pQMFilter->Protocol
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
|
|
if (pQMFilter->QMFilterType == QM_TUNNEL_FILTER) {
|
|
|
|
if (pQMFilter->MyTunnelEndpt.AddrType != IP_ADDR_UNIQUE) {
|
|
dwError=ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pQMFilter->PeerTunnelEndpt.AddrType != IP_ADDR_UNIQUE) {
|
|
dwError=ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyAddresses(pQMFilter->MyTunnelEndpt, FALSE, FALSE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyAddresses(pQMFilter->PeerTunnelEndpt, FALSE, FALSE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
}
|
|
|
|
if (pQMFilter->QMFilterType != QM_TUNNEL_FILTER &&
|
|
pQMFilter->QMFilterType != QM_TRANSPORT_FILTER) {
|
|
dwError=ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
DWORD
|
|
VerifyProtocols(
|
|
PROTOCOL Protocol
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
|
|
switch (Protocol.ProtocolType) {
|
|
|
|
case PROTOCOL_UNIQUE:
|
|
if (Protocol.dwProtocol > 255) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
break;
|
|
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
VerifyPortsForProtocol(
|
|
PORT Port,
|
|
PROTOCOL Protocol
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
|
|
switch (Port.PortType) {
|
|
|
|
case PORT_UNIQUE:
|
|
|
|
if (Port.wPort < 0) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
switch (Protocol.ProtocolType) {
|
|
|
|
case PROTOCOL_UNIQUE:
|
|
if ((Protocol.dwProtocol != IPPROTO_TCP) &&
|
|
(Protocol.dwProtocol != IPPROTO_UDP)) {
|
|
if (Port.wPort != 0) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
break;
|
|
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ValidateMMFilterTemplate(
|
|
PMM_FILTER pMMFilter
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
BOOL bConflicts = FALSE;
|
|
|
|
|
|
if (!pMMFilter) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyAddresses(pMMFilter->SrcAddr, TRUE, FALSE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyAddresses(pMMFilter->DesAddr, TRUE, TRUE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
bConflicts = AddressesConflict(
|
|
pMMFilter->SrcAddr,
|
|
pMMFilter->DesAddr
|
|
);
|
|
if (bConflicts) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pMMFilter->dwDirection) {
|
|
if ((pMMFilter->dwDirection != FILTER_DIRECTION_INBOUND) &&
|
|
(pMMFilter->dwDirection != FILTER_DIRECTION_OUTBOUND)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ValidateTxFilterTemplate(
|
|
PTRANSPORT_FILTER pTxFilter
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
BOOL bConflicts = FALSE;
|
|
|
|
|
|
if (!pTxFilter) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyAddresses(pTxFilter->SrcAddr, TRUE, FALSE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyAddresses(pTxFilter->DesAddr, TRUE, TRUE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
bConflicts = AddressesConflict(
|
|
pTxFilter->SrcAddr,
|
|
pTxFilter->DesAddr
|
|
);
|
|
if (bConflicts) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyProtocols(pTxFilter->Protocol);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyPortsForProtocol(
|
|
pTxFilter->SrcPort,
|
|
pTxFilter->Protocol
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyPortsForProtocol(
|
|
pTxFilter->DesPort,
|
|
pTxFilter->Protocol
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
if (pTxFilter->dwDirection) {
|
|
if ((pTxFilter->dwDirection != FILTER_DIRECTION_INBOUND) &&
|
|
(pTxFilter->dwDirection != FILTER_DIRECTION_OUTBOUND)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ValidateTunnelFilter(
|
|
PTUNNEL_FILTER pTunnelFilter
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
BOOL bConflicts = FALSE;
|
|
|
|
|
|
if (!pTunnelFilter) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyAddresses(pTunnelFilter->SrcAddr, TRUE, FALSE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyAddresses(pTunnelFilter->DesAddr, TRUE, TRUE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
bConflicts = AddressesConflict(
|
|
pTunnelFilter->SrcAddr,
|
|
pTunnelFilter->DesAddr
|
|
);
|
|
if (bConflicts) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyAddresses(pTunnelFilter->DesTunnelAddr, TRUE, FALSE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyProtocols(pTunnelFilter->Protocol);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyPortsForProtocol(
|
|
pTunnelFilter->SrcPort,
|
|
pTunnelFilter->Protocol
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyPortsForProtocol(
|
|
pTunnelFilter->DesPort,
|
|
pTunnelFilter->Protocol
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
if (!(pTunnelFilter->pszFilterName) || !(*(pTunnelFilter->pszFilterName))) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTunnelFilter->InterfaceType >= INTERFACE_TYPE_MAX) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTunnelFilter->bCreateMirror) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTunnelFilter->InboundFilterFlag >= FILTER_FLAG_MAX) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTunnelFilter->OutboundFilterFlag >= FILTER_FLAG_MAX) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
if (pTunnelFilter->dwFlags &&
|
|
!(pTunnelFilter->dwFlags & IPSEC_QM_POLICY_DEFAULT_POLICY)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
//
|
|
// No need to call ApplyMulticastFilterValidation as bCreateMirror
|
|
// is always false for a tunnel filter.
|
|
//
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ValidateTnFilterTemplate(
|
|
PTUNNEL_FILTER pTnFilter
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
BOOL bConflicts = FALSE;
|
|
|
|
|
|
if (!pTnFilter) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyAddresses(pTnFilter->SrcAddr, TRUE, FALSE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyAddresses(pTnFilter->DesAddr, TRUE, TRUE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
bConflicts = AddressesConflict(
|
|
pTnFilter->SrcAddr,
|
|
pTnFilter->DesAddr
|
|
);
|
|
if (bConflicts) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
dwError = VerifyAddresses(pTnFilter->DesTunnelAddr, TRUE, FALSE);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyProtocols(pTnFilter->Protocol);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyPortsForProtocol(
|
|
pTnFilter->SrcPort,
|
|
pTnFilter->Protocol
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = VerifyPortsForProtocol(
|
|
pTnFilter->DesPort,
|
|
pTnFilter->Protocol
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
if (pTnFilter->dwDirection) {
|
|
if ((pTnFilter->dwDirection != FILTER_DIRECTION_INBOUND) &&
|
|
(pTnFilter->dwDirection != FILTER_DIRECTION_OUTBOUND)) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ApplyMulticastFilterValidation(
|
|
ADDR Addr,
|
|
BOOL bCreateMirror
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
|
|
|
|
if (((Addr.AddrType == IP_ADDR_UNIQUE) ||
|
|
(Addr.AddrType == IP_ADDR_SUBNET)) &&
|
|
(IN_CLASSD(ntohl(Addr.uIpAddr))) &&
|
|
bCreateMirror) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
error:
|
|
|
|
return (dwError);
|
|
}
|
|
|