windows-nt/Source/XPSP1/NT/net/ipsec/ipsecshr/utils.c
2020-09-26 16:20:57 +08:00

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);
}