Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

3189 lines
81 KiB

/*++
Copyright (C) 1992-98 Microsft Corporation. All rights reserved.
Module Name:
rasipsec.c
Abstract:
All code corresponding to the interface between ras and the
IPSEC Policy Agent lives here
Author:
Rao Salapaka (raos) 03-Mar-1998
Revision History:
Abhishek (abhishev) 17-Feb-2000
--*/
#ifndef UNICODE
#define UNICODE
#endif
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <rasman.h>
#include <wanpub.h>
#include <ntlsa.h>
#include <ntmsv1_0.h>
#include <raserror.h>
#include <media.h>
#include <devioctl.h>
#include <windows.h>
#include <wincrypt.h>
#include <tchar.h>
#include <stdlib.h>
#include <string.h>
#include <mprlog.h>
#include <rtutils.h>
#include <rpc.h>
#include "logtrdef.h"
#include "defs.h"
#include "structs.h"
#include "protos.h"
#include "globals.h"
#include "nouiutil.h"
#include "loaddlls.h"
#include "winsock2.h"
#include "winipsec.h"
#include "memory.h"
#include "certmgmt.h"
#include "offers.h"
#include "iphlpapi.h"
#include "iprtrmib.h"
#include "rasipsec.h"
GUID gServerQMPolicyID;
GUID gServerMMPolicyID;
GUID gServerMMAuthID;
GUID gServerTxFilterID;
GUID gServerOutTxFilterID;
GUID gServerInTxFilterID;
GUID gServerMMFilterID;
GUID gServerOutMMFilterID;
GUID gServerInMMFilterID;
DWORD g_dwProhibitIpsec = 0;
RAS_L2TP_ENCRYPTION eServerEncryption = 0;
PIPSEC_SRV_NODE gpIpSecSrvList = NULL;
#define L2TP_DEST_PORT 1701
#define IPSEC_PA_RETRY_ATTEMPTS 3
#define IPSEC_PA_RETRY_WAIT_TIME 5000
DWORD g_dwIpSecRetryAttempts;
LPWSTR gpszServFilterName = L"L2TP Server Inbound and Outbound Filter";
LPWSTR gpszServOutFilterName = L"L2TP Server Outbound Filter";
LPWSTR gpszServInFilterName = L"L2TP Server Inbound Filter";
LPWSTR gpszClntFilterName = L"L2TP Client Inbound and Outbound Filter";
LPWSTR gpszQMPolicyNameNo = L"L2TP No Encryption Quick Mode Policy";
LPWSTR gpszQMPolicyNameOpt = L"L2TP Optional Encryption Quick Mode Policy";
LPWSTR gpszQMPolicyNameReq = L"L2TP Require Encryption Quick Mode Policy";
LPWSTR gpszQMPolicyNameMax = L"L2TP Require Max Encryption Quick Mode Policy";
LPWSTR gpszServerQMPolicyName = NULL;
LPWSTR gpszMMPolicyName = L"L2TP Main Mode Policy";
LPWSTR gpszServerMMPolicyName = NULL;
BOOL gbSQMPolicyAdded = FALSE;
BOOL gbSMMPolicyAdded = FALSE;
BOOL gbSMMAuthAdded = FALSE;
HANDLE ghSTxFilter = NULL;
HANDLE ghSTxOutFilter = NULL;
HANDLE ghSTxInFilter = NULL;
HANDLE ghSMMFilter = NULL;
HANDLE ghSMMOutFilter = NULL;
HANDLE ghSMMInFilter = NULL;
/*++
Routine Description:
Bind to the ipsec rpc server. This is temporary
and will be removed when the ipsec people prov
ide use with a library to initialize this stuff.
Arguments:
Return Value:
Nothing.
--*/
DWORD APIENTRY
DwInitializeIpSec(void)
{
DWORD dwErr = ERROR_SUCCESS;
{
HKEY hkey = NULL;
LONG lr = 0;
DWORD dwType = 0;
DWORD dwSize = sizeof(DWORD);
g_dwIpSecRetryAttempts = IPSEC_PA_RETRY_ATTEMPTS;
//
// Read the registry to see if number of ipsec
// retry attempts is specified.
//
if(NO_ERROR == (lr = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Services\\Rasman\\Parameters",
0,
KEY_ALL_ACCESS,
&hkey)))
{
//
// Query the value
//
lr = RegQueryValueEx(
hkey,
L"IpsecPARetryAttempts",
NULL,
&dwType,
(PBYTE) &g_dwIpSecRetryAttempts,
&dwSize);
if(NO_ERROR != lr)
{
g_dwIpSecRetryAttempts = IPSEC_PA_RETRY_ATTEMPTS;
}
RegCloseKey(hkey);
}
}
return dwErr;
}
/*++
Routine Description:
Free the binding to the rpc server
Arguments:
Return Value:
Nothing.
--*/
DWORD APIENTRY
DwUnInitializeIpSec(void)
{
return NO_ERROR;
}
/*++
Routine Description:
Query existing associations
Arguments:
ppIpSecSAList - address of pointer to a SAList
to contain the existing SA's
Return Value:
return values from the PA apis
--*/
DWORD
DwQueryAssociations(PIPSEC_QM_SA * ppIpSecSAList,
PDWORD pdwNumQMSAs, PDWORD pdwResumeHandle)
{
DWORD dwStatus = NO_ERROR;
DWORD dwNumTotalQMSAs = 0;
*ppIpSecSAList = NULL;
TracePrintfExA(TraceHandle,
RASMAN_TRACE_CONNECTION,
"DwQueryAssociations");
dwStatus = EnumQMSAs(
NULL,
NULL,
ppIpSecSAList,
0,
pdwNumQMSAs,
&dwNumTotalQMSAs,
pdwResumeHandle,
0
);
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"DwQueryAssociation, rc=0x%x",
dwStatus);
return dwStatus;
}
/*++
Routine Description:
Free the SA list obtained from the
DwQueryAssociations api
Arguments:
SA List to free
Return Value:
Nothing.
--*/
VOID
FreeSAList(IPSEC_QM_SA * pSAList)
{
if (pSAList) {
SPDApiBufferFree(pSAList);
}
return;
}
/*++
Routine Description:
Adds IpSec Filter
Arguments:
ppcb - pcb of the port for which to add the
filter
Return Value:
ERROR_SUCCESS if successful.
return values from PA apis
--*/
DWORD
DwAddIpSecFilter(
pPCB ppcb,
BOOL fServer,
RAS_L2TP_ENCRYPTION eEncryption
)
{
DWORD dwStatus = ERROR_INVALID_PARAMETER;
DWORD dwFilterCount = 0;
DWORD dwInfoCount = 0;
HRESULT hr = S_OK;
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"AddIpSecFilter, port=%d, fServer=%d, encryption=%d",
ppcb->PCB_PortHandle,
fServer,
eEncryption);
dwStatus = DwInitializeIpSec();
if (fServer) {
//
// TODO: figure out a better way of doing this
//
if(eServerEncryption != eEncryption)
{
DWORD dwNumServerFilters = dwServerConnectionCount;
DWORD i = 0;
TracePrintfExA( TraceHandle, RASMAN_TRACE_CONNECTION,
"Deleting previous filters since "
"ePrev != eCur (%d != %d)",
eServerEncryption,
eEncryption);
//
// Delte any existing filters since server
// is plumbing a new encryption filter.
//
for(i = 0; i < dwNumServerFilters; i++)
{
dwStatus = DwDeleteServerIpSecFilter(ppcb);
}
//
// Run through all the filters and reset the
// filter present flag
//
for (i = 0; i < MaxPorts; i++)
{
if(Pcb[i] != NULL)
{
Pcb[i]->PCB_fFilterPresent = FALSE;
}
}
}
else if(ppcb->PCB_fFilterPresent)
{
//
// Filter is already present
//
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"Port %d already has a plumbed filter",
ppcb->PCB_PortHandle);
dwStatus = ERROR_SUCCESS;
goto error;
}
dwStatus = DwAddServerIpSecFilter(
ppcb,
eEncryption
);
if(ERROR_SUCCESS == dwStatus)
{
ppcb->PCB_fFilterPresent = TRUE;
}
}else {
dwStatus = DwAddClientIpSecFilter(
ppcb,
eEncryption
);
}
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"AddIpSecFilter: rc=0x%x",
dwStatus);
return(dwStatus);
error:
return(dwStatus);
}
DWORD
DwGetPresharedKey(
pPCB ppcb,
DWORD dwMask,
DWORD *pcbkey,
PBYTE *ppbkey)
{
DWORD dwErr = NO_ERROR;
DWORD dwID;
GUID *pGuid = NULL;
if(NULL == pcbkey)
{
dwErr = E_INVALIDARG;
goto done;
}
if( (NULL != ppcb)
&& (NULL != ppcb->PCB_Connection))
{
pGuid = &ppcb->PCB_Connection->CB_GuidEntry;
}
//
// Get the size of the key
//
dwErr = GetKey(
NULL,
pGuid,
dwMask,
pcbkey,
NULL,
FALSE);
if(ERROR_BUFFER_TOO_SMALL == dwErr)
{
*ppbkey = LocalAlloc(LPTR, *pcbkey);
if(NULL == *ppbkey)
{
dwErr = GetLastError();
goto done;
}
dwErr = GetKey(
NULL,
pGuid,
dwMask,
pcbkey,
*ppbkey,
FALSE);
//
// Since IKE doesn't expect a NULL
// at the end of the psk, we remove
// the null.
//
if( (*pcbkey > 2)
&& (UNICODE_NULL == *((WCHAR *) (*ppbkey + *pcbkey - sizeof(WCHAR)))))
{
*pcbkey -= sizeof(WCHAR);
}
}
done:
return dwErr;
}
DWORD
DwGetMMAuthMethodsForServer(
MM_AUTH_METHODS *pAuthMethods,
DWORD *pdwInfoCount,
DWORD *pcbkey,
PBYTE *ppbkey,
IPSEC_MM_AUTH_INFO ** ppAuthInfo)
{
DWORD dwStatus = ERROR_SUCCESS;
DWORD cbkey = 0;
BYTE *pbkey = NULL;
IPSEC_MM_AUTH_INFO *pAuthPSK = NULL;
BOOL fMyStoreEmpty = TRUE;
if( (NULL == pAuthMethods)
|| (NULL == pcbkey)
|| (NULL == ppbkey)
|| (NULL == ppAuthInfo))
{
dwStatus = E_INVALIDARG;
goto done;
}
*ppAuthInfo = NULL;
memset(pAuthMethods, 0, sizeof(MM_AUTH_METHODS));
if(UuidCreate(&pAuthMethods->gMMAuthID))
{
RasmanTrace("UuidCreate returned non-zero value");
}
if(NULL == *ppbkey)
{
//
// Get the preshared key if theres one available.
//
dwStatus = DwGetPresharedKey(
NULL,
DLPARAMS_MASK_SERVER_PRESHAREDKEY,
pcbkey,
ppbkey);
}
//
// We're using a certificate for authentication.
// By leaving the AuthInfo empty, we specify that we want to use
// the default machine cert.
//
dwStatus = GenerateCertificatesList(
ppAuthInfo,
pdwInfoCount,
&fMyStoreEmpty
);
if( (*pcbkey == 0)
&& ((ERROR_SUCCESS != dwStatus)
|| (0 == *pdwInfoCount)
|| fMyStoreEmpty))
{
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"Failed to generate certificate list. "
"rc=0x%x, Count=%d, MyStoreEmpty=%d",
dwStatus,
*pdwInfoCount,
fMyStoreEmpty);
if ( (0 == *pdwInfoCount)
|| (fMyStoreEmpty))
{
dwStatus = ERROR_NO_CERTIFICATE;
}
if (*ppAuthInfo) {
FreeCertificatesList(
*ppAuthInfo,
*pdwInfoCount
);
*ppAuthInfo = NULL;
}
goto done;
}
if(*pcbkey > 0)
{
dwStatus = ERROR_SUCCESS;
//
// Add preshared key to the auth info
//
if(NULL == *ppAuthInfo)
{
*ppAuthInfo = LocalAlloc(LPTR, sizeof(IPSEC_MM_AUTH_INFO));
if(NULL == *ppAuthInfo)
{
dwStatus = GetLastError();
goto done;
}
}
//
// Note that ListCertChainsInStore would allocate
// for authinfo if needed.
//
pAuthPSK = *ppAuthInfo + *pdwInfoCount;
pAuthPSK->AuthMethod = IKE_PRESHARED_KEY;
pAuthPSK->pAuthInfo = *ppbkey;
pAuthPSK->dwAuthInfoSize = *pcbkey;
*pdwInfoCount += 1;
}
BuildMMAuth(
pAuthMethods,
*ppAuthInfo,
*pdwInfoCount
);
done:
return dwStatus;
}
DWORD
DwUpdatePreSharedKey(
DWORD cbkey,
BYTE *pbkey)
{
DWORD retcode = ERROR_SUCCESS;
DWORD dwInfoCount = 0;
IPSEC_MM_AUTH_INFO *pAuthInfo = NULL;
DWORD cbkeyp = cbkey;
BYTE *pbkeyp = pbkey;
MM_AUTH_METHODS MMAuthMethods;
if( (cbkeyp >= 2)
&& (UNICODE_NULL == *((WCHAR *)
(pbkeyp + cbkeyp - sizeof(WCHAR)))))
{
cbkeyp -= sizeof(WCHAR);
}
retcode = DwGetMMAuthMethodsForServer(
&MMAuthMethods,
&dwInfoCount,
&cbkeyp,
&pbkeyp,
&pAuthInfo);
if(ERROR_SUCCESS != retcode)
{
if( ((0 == cbkeyp)
|| (NULL == pbkeyp)))
{
RasmanTrace("DwUpdatePreSharedKey:"
"Failed to fetch certs and"
" PSK=NULL - deleting auth methods");
retcode = DeleteMMAuthMethods(NULL, gServerMMAuthID);
if(retcode = ERROR_IPSEC_MM_AUTH_NOT_FOUND)
{
//
// The auth method is not present.
//
retcode = ERROR_SUCCESS;
}
}
goto done;
}
retcode = SetMMAuthMethods(
NULL,
gServerMMAuthID,
&MMAuthMethods);
//
// Decrement infocount to remove the authinfo
// corresponding to PreSharedKey
//
dwInfoCount -= 1;
if(0 != dwInfoCount)
{
FreeCertificatesList(pAuthInfo, dwInfoCount);
}
done:
return retcode;
}
DWORD
DwAddServerIpSecFilter(
pPCB ppcb,
RAS_L2TP_ENCRYPTION eEncryption
)
{
DWORD dwStatus = ERROR_INVALID_PARAMETER;
IPSEC_MM_POLICY MMPolicy;
MM_AUTH_METHODS MMAuthMethods;
IPSEC_QM_POLICY QMPolicy;
IPSEC_MM_AUTH_INFO * pAuthInfo = NULL;
// IPSEC_QM_OFFER Offers[20];
IPSEC_QM_OFFER *pOffers = NULL;
TRANSPORT_FILTER myOutFilter;
TRANSPORT_FILTER myInFilter;
TRANSPORT_FILTER myFilter;
DWORD dwInfoCount = 0;
DWORD dwOfferCount = 1;
DWORD dwFlags = 0;
DWORD dwCount = 3;
BOOL fMyStoreEmpty = FALSE;
// IPSEC_MM_OFFER MMOffers[10];
IPSEC_MM_OFFER *pMMOffers = NULL;
DWORD dwMMOfferCount = 0;
DWORD dwMMFlags = 0;
MM_FILTER myOutMMFilter;
MM_FILTER myInMMFilter;
MM_FILTER myMMFilter;
DWORD dwPersist = 0;
DWORD cbkey = 0;
PBYTE pbkey = NULL;
IPSEC_MM_AUTH_INFO *pAuthPSK = NULL;
pOffers = LocalAlloc(LPTR, 20 * sizeof(IPSEC_QM_OFFER));
if(NULL == pOffers)
{
return GetLastError();
}
pMMOffers = LocalAlloc(LPTR, 10 * sizeof(IPSEC_MM_OFFER));
if(NULL == pMMOffers)
{
LocalFree(pOffers);
return GetLastError();
}
//
// Make a global copy for the server
// We use this to delete two filters in
// the RAS_L2TP_OPTIONAL_ENCRYPTION case
//
eServerEncryption = eEncryption;
if (!dwServerConnectionCount) {
switch (eEncryption) {
case RAS_L2TP_NO_ENCRYPTION:
case RAS_L2TP_OPTIONAL_ENCRYPTION:
memset(&gServerQMPolicyID, 0, sizeof(GUID));
memset(&gServerMMPolicyID, 0, sizeof(GUID));
memset(&gServerMMAuthID, 0, sizeof(GUID));
memset(&gServerTxFilterID, 0, sizeof(GUID));
memset(&gServerOutTxFilterID, 0, sizeof(GUID));
memset(&gServerInTxFilterID, 0, sizeof(GUID));
memset(&gServerMMFilterID, 0, sizeof(GUID));
memset(&gServerOutMMFilterID, 0, sizeof(GUID));
memset(&gServerInMMFilterID, 0, sizeof(GUID));
memset(&MMPolicy, 0, sizeof(IPSEC_MM_POLICY));
if(UuidCreate(&MMPolicy.gPolicyID))
{
RasmanTrace("UuidCreate returned non-zero value");
}
memset(&QMPolicy, 0, sizeof(IPSEC_QM_POLICY));
if(UuidCreate(&QMPolicy.gPolicyID))
{
RasmanTrace("UuidCreate returned non-zero value");
}
memset(&MMAuthMethods, 0, sizeof(MM_AUTH_METHODS));
if(UuidCreate(&MMAuthMethods.gMMAuthID))
{
RasmanTrace("UuidCreate returned non-zero value");
}
#if 0
//
// Get the preshared key if theres one available.
//
dwStatus = DwGetPresharedKey(
ppcb,
DLPARAMS_MASK_SERVER_PRESHAREDKEY,
&cbkey,
&pbkey);
//
// We're using a certificate for authentication.
// By leaving the AuthInfo empty, we specify that we want to use
// the default machine cert.
//
dwStatus = GenerateCertificatesList(
&pAuthInfo,
&dwInfoCount,
&fMyStoreEmpty
);
if( (cbkey == 0)
&& ((ERROR_SUCCESS != dwStatus)
|| (0 == dwInfoCount)
|| fMyStoreEmpty))
{
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"Failed to generate certificate list. "
"rc=0x%x, Count=%d, MyStoreEmpty=%d",
dwStatus,
dwInfoCount,
fMyStoreEmpty);
if ( (0 == dwInfoCount)
|| (fMyStoreEmpty))
{
dwStatus = ERROR_NO_CERTIFICATE;
}
if (pAuthInfo) {
FreeCertificatesList(
pAuthInfo,
dwInfoCount
);
pAuthInfo = NULL;
}
goto error;
}
if(cbkey > 0)
{
//
// Add preshared key to the auth info
//
if(NULL == pAuthInfo)
{
pAuthInfo = LocalAlloc(LPTR, sizeof(IPSEC_MM_AUTH_INFO));
if(NULL == pAuthInfo)
{
dwStatus = GetLastError();
goto error;
}
}
//
// Note that ListCertChainsInStore would allocate
// for authinfo if needed.
//
pAuthPSK = pAuthInfo + dwInfoCount;
pAuthPSK->AuthMethod = IKE_PRESHARED_KEY;
pAuthPSK->pAuthInfo = pbkey;
pAuthPSK->dwAuthInfoSize = cbkey;
dwInfoCount += 1;
}
BuildMMAuth(
&MMAuthMethods,
pAuthInfo,
dwInfoCount
);
#endif
dwStatus = DwGetMMAuthMethodsForServer(
&MMAuthMethods,
&dwInfoCount,
&cbkey,
&pbkey,
&pAuthInfo);
if(ERROR_SUCCESS != dwStatus)
{
goto error;
}
//memset(Offers, 0, sizeof(IPSEC_QM_OFFER)*20);
dwStatus = BuildOffers(
eEncryption,
pOffers,
&dwOfferCount,
&dwFlags
);
BuildQMPolicy(
&QMPolicy,
eEncryption,
pOffers,
dwOfferCount,
dwFlags
);
//memset(MMOffers, 0, sizeof(IPSEC_MM_OFFER)*10);
BuildMMOffers(
pMMOffers,
&dwMMOfferCount,
&dwMMFlags
);
BuildMMPolicy(
&MMPolicy,
pMMOffers,
dwMMOfferCount,
dwMMFlags
);
//
// Now build the filter we are interested in
//
memset(&myOutFilter, 0, sizeof(TRANSPORT_FILTER));
memset(&myInFilter, 0, sizeof(TRANSPORT_FILTER));
memset(&myOutMMFilter, 0, sizeof(MM_FILTER));
memset(&myInMMFilter, 0, sizeof(MM_FILTER));
//
// This is the Outbound Filter
//
BuildOutTxFilter(
&myOutFilter,
QMPolicy.gPolicyID,
FALSE
);
//
// This is the Inbound Filter
//
BuildInTxFilter(
&myInFilter,
QMPolicy.gPolicyID,
FALSE
);
BuildOutMMFilter(
&myOutMMFilter,
MMPolicy.gPolicyID,
MMAuthMethods.gMMAuthID,
FALSE
);
BuildInMMFilter(
&myInMMFilter,
MMPolicy.gPolicyID,
MMAuthMethods.gMMAuthID,
FALSE
);
do
{
if (!gbSMMAuthAdded) {
dwStatus = AddMMAuthMethods(
NULL,
dwPersist,
&MMAuthMethods
);
if (!dwStatus) {
gbSMMAuthAdded = TRUE;
memcpy(&gServerMMAuthID,
&(MMAuthMethods.gMMAuthID), sizeof(GUID));
}
}
if (!gbSMMPolicyAdded) {
dwStatus = AddMMPolicy(
NULL,
dwPersist,
&MMPolicy
);
if (!dwStatus) {
gbSMMPolicyAdded = TRUE;
memcpy(&gServerMMPolicyID,
&(MMPolicy.gPolicyID), sizeof(GUID));
gpszServerMMPolicyName = MMPolicy.pszPolicyName;
}
}
if (!gbSQMPolicyAdded) {
dwStatus = AddQMPolicy(
NULL,
dwPersist,
&QMPolicy
);
if (!dwStatus) {
gbSQMPolicyAdded = TRUE;
memcpy(&gServerQMPolicyID,
&(QMPolicy.gPolicyID), sizeof(GUID));
gpszServerQMPolicyName = QMPolicy.pszPolicyName;
}
}
if (!ghSTxOutFilter) {
dwStatus = AddTransportFilter(
NULL,
dwPersist,
&myOutFilter,
&ghSTxOutFilter
);
if (!dwStatus) {
memcpy(&gServerOutTxFilterID,
&(myOutFilter.gFilterID), sizeof(GUID));
}
}
if (!ghSTxInFilter) {
dwStatus = AddTransportFilter(
NULL,
dwPersist,
&myInFilter,
&ghSTxInFilter
);
if (!dwStatus) {
memcpy(&gServerInTxFilterID,
&(myInFilter.gFilterID), sizeof(GUID));
}
}
if (!ghSMMOutFilter) {
dwStatus = AddMMFilter(
NULL,
dwPersist,
&myOutMMFilter,
&ghSMMOutFilter
);
if (!dwStatus) {
memcpy(&gServerOutMMFilterID,
&(myOutMMFilter.gFilterID), sizeof(GUID));
}
}
if (!ghSMMInFilter) {
dwStatus = AddMMFilter(
NULL,
dwPersist,
&myInMMFilter,
&ghSMMInFilter
);
if (!dwStatus) {
memcpy(&gServerInMMFilterID,
&(myInMMFilter.gFilterID), sizeof(GUID));
}
}
dwCount += 1;
if(ERROR_NOT_READY == dwStatus)
{
Sleep(IPSEC_PA_RETRY_WAIT_TIME);
}
}
while( (ERROR_NOT_READY == dwStatus)
&& (dwCount < g_dwIpSecRetryAttempts));
//
// Now free the certificates list.
// we don't want to keep this around
// we will reevaluate again
//
if (pAuthInfo) {
dwInfoCount -= 1;
if(cbkey > 0)
{
LocalFree(pbkey);
}
FreeCertificatesList(
pAuthInfo,
dwInfoCount
);
}
break;
case RAS_L2TP_REQUIRE_ENCRYPTION:
case RAS_L2TP_REQUIRE_MAX_ENCRYPTION:
memset(&gServerQMPolicyID, 0, sizeof(GUID));
memset(&gServerMMPolicyID, 0, sizeof(GUID));
memset(&gServerMMAuthID, 0, sizeof(GUID));
memset(&gServerTxFilterID, 0, sizeof(GUID));
memset(&gServerOutTxFilterID, 0, sizeof(GUID));
memset(&gServerInTxFilterID, 0, sizeof(GUID));
memset(&gServerMMFilterID, 0, sizeof(GUID));
memset(&gServerOutMMFilterID, 0, sizeof(GUID));
memset(&gServerInMMFilterID, 0, sizeof(GUID));
memset(&MMPolicy, 0, sizeof(IPSEC_MM_POLICY));
if(UuidCreate(&MMPolicy.gPolicyID))
{
RasmanTrace("UuidCreate returned non-zero value");
}
memset(&QMPolicy, 0, sizeof(IPSEC_QM_POLICY));
if(UuidCreate(&QMPolicy.gPolicyID))
{
RasmanTrace("UuidCreate returned non-zero value");
}
memset(&MMAuthMethods, 0, sizeof(MM_AUTH_METHODS));
if(UuidCreate(&MMAuthMethods.gMMAuthID))
{
RasmanTrace("UuidCreate returned non-zero value");
}
//
// We're using a certificate for authentication.
// By leaving the AuthInfo empty, we specify that we want to use
// the default machine cert.
//
dwStatus = GenerateCertificatesList(
&pAuthInfo,
&dwInfoCount,
&fMyStoreEmpty
);
if( (ERROR_SUCCESS != dwStatus)
|| (0 == dwInfoCount)
|| fMyStoreEmpty)
{
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"Failed to generate certificate list. "
"rc=0x%x, Count=%d, MyStoreEmpty=%d",
dwStatus,
dwInfoCount,
fMyStoreEmpty);
if ( (0 == dwInfoCount)
|| (fMyStoreEmpty))
{
dwStatus = ERROR_NO_CERTIFICATE;
}
if (pAuthInfo) {
FreeCertificatesList(
pAuthInfo,
dwInfoCount
);
}
goto error;
}
BuildMMAuth(
&MMAuthMethods,
pAuthInfo,
dwInfoCount
);
//memset(Offers, 0, sizeof(IPSEC_QM_OFFER)*20);
dwStatus = BuildOffers(
eEncryption,
pOffers,
&dwOfferCount,
&dwFlags
);
BuildQMPolicy(
&QMPolicy,
eEncryption,
pOffers,
dwOfferCount,
dwFlags
);
//memset(MMOffers, 0, sizeof(IPSEC_MM_OFFER)*10);
BuildMMOffers(
pMMOffers,
&dwMMOfferCount,
&dwMMFlags
);
BuildMMPolicy(
&MMPolicy,
pMMOffers,
dwMMOfferCount,
dwMMFlags
);
//
// Now build the filter we are interested in
//
memset(&myFilter, 0, sizeof(TRANSPORT_FILTER));
memset(&myMMFilter, 0, sizeof(MM_FILTER));
BuildOutTxFilter(
&myFilter,
QMPolicy.gPolicyID,
TRUE
);
BuildOutMMFilter(
&myMMFilter,
MMPolicy.gPolicyID,
MMAuthMethods.gMMAuthID,
TRUE
);
do
{
if (!gbSMMAuthAdded) {
dwStatus = AddMMAuthMethods(
NULL,
dwPersist,
&MMAuthMethods
);
if (!dwStatus) {
gbSMMAuthAdded = TRUE;
memcpy(&gServerMMAuthID,
&(MMAuthMethods.gMMAuthID), sizeof(GUID));
}
}
if (!gbSMMPolicyAdded) {
dwStatus = AddMMPolicy(
NULL,
dwPersist,
&MMPolicy
);
if (!dwStatus) {
gbSMMPolicyAdded = TRUE;
memcpy(&gServerMMPolicyID,
&(MMPolicy.gPolicyID), sizeof(GUID));
gpszServerMMPolicyName = MMPolicy.pszPolicyName;
}
}
if (!gbSQMPolicyAdded) {
dwStatus = AddQMPolicy(
NULL,
dwPersist,
&QMPolicy
);
if (!dwStatus) {
gbSQMPolicyAdded = TRUE;
memcpy(&gServerQMPolicyID,
&(QMPolicy.gPolicyID), sizeof(GUID));
gpszServerQMPolicyName = QMPolicy.pszPolicyName;
}
}
if (!ghSTxFilter) {
dwStatus = AddTransportFilter(
NULL,
dwPersist,
&myFilter,
&ghSTxFilter
);
if (!dwStatus) {
memcpy(&gServerTxFilterID,
&(myFilter.gFilterID), sizeof(GUID));
}
}
if (!ghSMMFilter) {
dwStatus = AddMMFilter(
NULL,
dwPersist,
&myMMFilter,
&ghSMMFilter
);
if (!dwStatus) {
memcpy(&gServerMMFilterID,
&(myMMFilter.gFilterID), sizeof(GUID));
}
}
if(ERROR_NOT_READY == dwStatus)
{
Sleep(IPSEC_PA_RETRY_WAIT_TIME);
}
dwCount += 1;
}
while( (ERROR_NOT_READY == dwStatus)
&& (dwCount < g_dwIpSecRetryAttempts));
//
// Now free the certificates list.
// we don't want to keep this around
// we will reevaluate again
//
if (pAuthInfo) {
FreeCertificatesList(
pAuthInfo,
dwInfoCount
);
}
break;
}
if(ERROR_SUCCESS == dwStatus)
{
dwServerConnectionCount++;
}
} else {
dwServerConnectionCount++;
dwStatus = ERROR_SUCCESS;
}
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"DwAddServerIpSecFilter: rc=0x%x",
dwStatus);
if(NULL != pOffers)
{
LocalFree(pOffers);
}
if(NULL != pMMOffers)
{
LocalFree(pMMOffers);
}
return(dwStatus);
error:
if(NULL != pOffers)
{
LocalFree(pOffers);
}
if(NULL != pMMOffers)
{
LocalFree(pMMOffers);
}
return(dwStatus);
}
DWORD
DwAddClientIpSecFilter(
pPCB ppcb,
RAS_L2TP_ENCRYPTION eEncryption
)
{
DWORD dwStatus = ERROR_INVALID_PARAMETER;
IPSEC_QM_POLICY QMPolicy;
IPSEC_MM_POLICY MMPolicy;
IPSEC_MM_AUTH_INFO * pAuthInfo = NULL;
MM_AUTH_METHODS MMAuthMethods;
// IPSEC_QM_OFFER Offers[20];
IPSEC_QM_OFFER *pOffers = NULL;
TRANSPORT_FILTER myFilter;
DWORD dwInfoCount = 0;
DWORD dwOfferCount = 1;
PIPSEC_SRV_NODE pClientNode = NULL;
GUID gQMPolicyID;
GUID gMMPolicyID;
GUID gMMAuthID;
GUID gTxFilterID;
GUID gMMFilterID;
DWORD dwFlags = 0;
HANDLE hTxFilter = NULL;
HANDLE hMMFilter = NULL;
// IPSEC_MM_OFFER MMOffers[10];
IPSEC_MM_OFFER *pMMOffers = NULL;
DWORD dwMMOfferCount = 0;
DWORD dwMMFlags = 0;
MM_FILTER myMMFilter;
PIPSEC_MM_POLICY pSPDMMPolicy = NULL;
PIPSEC_QM_POLICY pSPDQMPolicy = NULL;
DWORD dwPersist = 0;
DWORD cbkey = 0;
PBYTE pbkey = NULL;
IPSEC_MM_AUTH_INFO *pAuthPSK = NULL;
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"DwAddClientIpSecFilter, port=%d",
ppcb->PCB_PortHandle);
pOffers = LocalAlloc(LPTR, 20 * sizeof(IPSEC_QM_OFFER));
if(NULL == pOffers)
{
RasmanTrace("DwAddclientipsecfilter: failed to alloc");
return GetLastError();
}
pMMOffers = LocalAlloc(LPTR, 10 * sizeof(IPSEC_MM_OFFER));
if(NULL == pMMOffers)
{
RasmanTrace("DwAddclientipsecfilter: failed to alloc");
LocalFree(pOffers);
return GetLastError();
goto error;
}
memset(&gQMPolicyID, 0, sizeof(GUID));
memset(&gMMPolicyID, 0, sizeof(GUID));
memset(&gMMAuthID, 0, sizeof(GUID));
memset(&gTxFilterID, 0, sizeof(GUID));
memset(&gMMFilterID, 0, sizeof(GUID));
pClientNode = FindServerNode(
gpIpSecSrvList,
ppcb->PCB_ulDestAddr
);
if (pClientNode) {
if (eEncryption != pClientNode->eEncryption)
{
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"DwAddClientIpSecFilter: Already a filter"
" with a different encryption(%d) type exists"
" for ths dest address. port=%d",
pClientNode->eEncryption,
ppcb->PCB_PortHandle);
LocalFree(pOffers);
return (ERROR_INVALID_PARAMETER);
}
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"DwAddClientIpSecFilter: Filter already exists"
" port=%d",
ppcb->PCB_PortHandle);
pClientNode->dwRefCount++;
LocalFree(pOffers);
LocalFree(pMMOffers);
return (ERROR_SUCCESS);
} else {
BOOL fMyStoreEmpty;
//
// There was no filter plumbed, so plumb a filter
//
switch (eEncryption) {
case RAS_L2TP_NO_ENCRYPTION:
case RAS_L2TP_REQUIRE_ENCRYPTION:
case RAS_L2TP_OPTIONAL_ENCRYPTION:
case RAS_L2TP_REQUIRE_MAX_ENCRYPTION:
memset(&MMPolicy, 0, sizeof(IPSEC_MM_POLICY));
if(UuidCreate(&MMPolicy.gPolicyID))
{
RasmanTrace("UuidCreate returned non-zero value");
}
memset(&QMPolicy, 0, sizeof(IPSEC_QM_POLICY));
if(UuidCreate(&QMPolicy.gPolicyID))
{
RasmanTrace("UuidCreate returned non-zero value");
}
memset(&MMAuthMethods, 0, sizeof(MM_AUTH_METHODS));
if(UuidCreate(&MMAuthMethods.gMMAuthID))
{
RasmanTrace("UuidCreate returned non-zero value");
}
//
// Get presharedkey
//
if( (NULL != ppcb->PCB_Connection)
&& (CONNECTION_USEPRESHAREDKEY &
ppcb->PCB_Connection->
CB_ConnectionParams.CP_ConnectionFlags))
{
DWORD dwMask = DLPARAMS_MASK_PRESHAREDKEY;
if(GetCurrentProcessId() ==
ppcb->PCB_Connection->CB_dwPid)
{
dwMask = DLPARAMS_MASK_DDM_PRESHAREDKEY;
}
dwStatus = DwGetPresharedKey(
ppcb,
dwMask,
&cbkey,
&pbkey);
}
//
// Generate certificate list only if there is no
// pre-sharedkey for this connectoid.
//
if(cbkey == 0)
{
HCONN hConn = ppcb->PCB_Connection->CB_Handle;
//
// Leave submitcriticalsection before calling
// to generate certificate list.
//
LeaveCriticalSection(&g_csSubmitRequest);
//
// We're using a certificate for authentication.
// By leaving the AuthInfo empty, we specify that
// we want to use the default machine cert.
//
dwStatus = GenerateCertificatesList(
&pAuthInfo,
&dwInfoCount,
&fMyStoreEmpty
);
//
// Reacquire the critical section and make sure
// the connection is still valid.
//
EnterCriticalSection(&g_csSubmitRequest);
if(NULL == FindConnection(hConn))
{
RasmanTrace("DwAddClientIpSecFilter: connection 0x%x"
"not found", hConn);
FreeCertificatesList(pAuthInfo, dwInfoCount);
dwStatus = ERROR_NO_CONNECTION;
goto error;
}
if( (0 == cbkey)
&& ((ERROR_SUCCESS != dwStatus)
|| (0 == dwInfoCount)
|| fMyStoreEmpty))
{
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"Failed to generate certificate list. "
"rc=0x%x, Count=%d, MyStoreEmpty=%d",
dwStatus,
dwInfoCount,
fMyStoreEmpty);
if ( (0 == dwInfoCount)
|| (fMyStoreEmpty))
{
dwStatus = ERROR_CERT_FOR_ENCRYPTION_NOT_FOUND;
}
if (pAuthInfo) {
FreeCertificatesList(
pAuthInfo,
dwInfoCount
);
}
goto error;
}
}
if(cbkey > 0)
{
//
// Add preshared key to the auth info
//
if(NULL == pAuthInfo)
{
pAuthInfo = LocalAlloc(LPTR, sizeof(IPSEC_MM_AUTH_INFO));
if(NULL == pAuthInfo)
{
dwStatus = GetLastError();
goto error;
}
}
//
// Note that ListCertChainsInStore would allocate
// for authinfo if needed.
//
pAuthPSK = pAuthInfo + dwInfoCount;
pAuthPSK->AuthMethod = IKE_PRESHARED_KEY;
pAuthPSK->pAuthInfo = pbkey;
pAuthPSK->dwAuthInfoSize = cbkey;
dwInfoCount += 1;
}
BuildMMAuth(
&MMAuthMethods,
pAuthInfo,
dwInfoCount
);
//memset(Offers, 0, sizeof(IPSEC_QM_OFFER)*20);
dwStatus = BuildOffers(
eEncryption,
pOffers,
&dwOfferCount,
&dwFlags
);
BuildQMPolicy(
&QMPolicy,
eEncryption,
pOffers,
dwOfferCount,
dwFlags
);
//memset(MMOffers, 0, sizeof(IPSEC_MM_OFFER)*10);
BuildMMOffers(
pMMOffers,
&dwMMOfferCount,
&dwMMFlags
);
BuildMMPolicy(
&MMPolicy,
pMMOffers,
dwMMOfferCount,
dwMMFlags
);
//
// Now build the filter we are interested in
//
memset(&myFilter, 0, sizeof(TRANSPORT_FILTER));
memset(&myMMFilter, 0, sizeof(MM_FILTER));
dwStatus = AddMMAuthMethods(
NULL,
dwPersist,
&MMAuthMethods
);
if (!dwStatus) {
memcpy(&gMMAuthID, &MMAuthMethods.gMMAuthID, sizeof(GUID));
}
dwStatus = AddMMPolicy(
NULL,
dwPersist,
&MMPolicy
);
if (!dwStatus) {
memcpy(&gMMPolicyID, &(MMPolicy.gPolicyID), sizeof(GUID));
}
else {
if (dwStatus == ERROR_IPSEC_MM_POLICY_EXISTS) {
dwStatus = GetMMPolicy(
NULL,
MMPolicy.pszPolicyName,
&pSPDMMPolicy
);
if (!dwStatus) {
memcpy(&gMMPolicyID, &(pSPDMMPolicy->gPolicyID), sizeof(GUID));
SPDApiBufferFree(pSPDMMPolicy);
}
else {
dwStatus = AddMMPolicy(
NULL,
dwPersist,
&MMPolicy
);
memcpy(&gMMPolicyID, &(MMPolicy.gPolicyID), sizeof(GUID));
}
}
}
BuildCMMFilter(
&myMMFilter,
gMMPolicyID,
MMAuthMethods.gMMAuthID,
ppcb->PCB_ulDestAddr,
TRUE
);
dwStatus = AddQMPolicy(
NULL,
dwPersist,
&QMPolicy
);
if (!dwStatus) {
memcpy(&gQMPolicyID, &QMPolicy.gPolicyID, sizeof(GUID));
}
else {
if (dwStatus == ERROR_IPSEC_QM_POLICY_EXISTS) {
dwStatus = GetQMPolicy(
NULL,
QMPolicy.pszPolicyName,
&pSPDQMPolicy
);
if (!dwStatus) {
memcpy(&gQMPolicyID, &(pSPDQMPolicy->gPolicyID), sizeof(GUID));
SPDApiBufferFree(pSPDQMPolicy);
}
else {
dwStatus = AddQMPolicy(
NULL,
dwPersist,
&QMPolicy
);
memcpy(&gQMPolicyID, &(QMPolicy.gPolicyID), sizeof(GUID));
}
}
}
BuildCTxFilter(
&myFilter,
gQMPolicyID,
ppcb->PCB_ulDestAddr,
TRUE
);
dwStatus = AddTransportFilter(
NULL,
dwPersist,
&myFilter,
&hTxFilter
);
if (!dwStatus) {
memcpy(&gTxFilterID, &(myFilter.gFilterID), sizeof(GUID));
}
dwStatus = AddMMFilter(
NULL,
dwPersist,
&myMMFilter,
&hMMFilter
);
if (!dwStatus) {
memcpy(&gMMFilterID, &(myMMFilter.gFilterID), sizeof(GUID));
}
//
// Now free the certificates list.
// we don't want to keep this around
// we will reevaluate again
//
if (pAuthInfo) {
FreeCertificatesList(
pAuthInfo,
dwInfoCount
);
}
break;
}
if(ERROR_SUCCESS != dwStatus)
{
goto error;
}
//
// Successfully plumbed the policy, add this to the
// server list
//
gpIpSecSrvList= AddNodeToServerList(
gpIpSecSrvList,
eEncryption,
ppcb->PCB_ulDestAddr,
MMPolicy.pszPolicyName,
gMMPolicyID,
QMPolicy.pszPolicyName,
gQMPolicyID,
gMMAuthID,
gTxFilterID,
hTxFilter,
gMMFilterID,
hMMFilter
);
}
error:
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"DwAddClientIpSecFilter: rc=0x%x",
dwStatus);
if(NULL != pOffers)
{
LocalFree(pOffers);
}
if(NULL != pMMOffers)
{
LocalFree(pMMOffers);
}
return(dwStatus);
}
/*++
Routine Description:
Deletes ipsec filter
Arguments:
ppcb - port for which to disable ipsec
fServer - TRUE if Server is making this call
Return Value:
NO_ERROR if successful
return values from PA apis otherwise
E_FAIL if ipsec is not initialized
--*/
DWORD
DwDeleteIpSecFilter(pPCB ppcb, BOOL fServer)
{
DWORD dwStatus = NO_ERROR;
dwStatus = DwInitializeIpSec();
if (fServer) {
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"Deleting server ipsec filter on %d",
ppcb->PCB_PortHandle);
dwStatus = DwDeleteServerIpSecFilter(
ppcb
);
}else {
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"Deleting client ipsec filter on %d",
ppcb->PCB_PortHandle);
dwStatus = DwDeleteClientIpSecFilter(
ppcb
);
}
return dwStatus;
}
DWORD
DwDeleteServerIpSecFilter(
pPCB ppcb
)
{
DWORD dwStatus = ERROR_SUCCESS;
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"DwDeleteServerIpSecFilter. port=%d,"
"ServerConnectionCount=%d",
ppcb->PCB_PortHandle,
dwServerConnectionCount);
if (dwServerConnectionCount > 1) {
dwServerConnectionCount--;
} else if (dwServerConnectionCount == 1) {
switch (eServerEncryption) {
case RAS_L2TP_NO_ENCRYPTION:
case RAS_L2TP_OPTIONAL_ENCRYPTION:
if (ghSTxInFilter) {
dwStatus = DeleteTransportFilter(
ghSTxInFilter
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
if (ghSTxOutFilter) {
dwStatus = DeleteTransportFilter(
ghSTxOutFilter
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
if (ghSMMInFilter) {
dwStatus = DeleteMMFilter(
ghSMMInFilter
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
if (ghSMMOutFilter) {
dwStatus = DeleteMMFilter(
ghSMMOutFilter
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
if (gbSQMPolicyAdded) {
dwStatus = DeleteQMPolicy(
NULL,
gpszServerQMPolicyName
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
if (gbSMMPolicyAdded) {
dwStatus = DeleteMMPolicy(
NULL,
gpszServerMMPolicyName
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
if (gbSMMAuthAdded) {
dwStatus = DeleteMMAuthMethods(
NULL,
gServerMMAuthID
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
memset(&gServerQMPolicyID, 0, sizeof(GUID));
memset(&gServerMMPolicyID, 0, sizeof(GUID));
memset(&gServerMMAuthID, 0, sizeof(GUID));
memset(&gServerTxFilterID, 0, sizeof(GUID));
memset(&gServerOutTxFilterID, 0, sizeof(GUID));
memset(&gServerInTxFilterID, 0, sizeof(GUID));
memset(&gServerMMFilterID, 0, sizeof(GUID));
memset(&gServerOutMMFilterID, 0, sizeof(GUID));
memset(&gServerInMMFilterID, 0, sizeof(GUID));
gpszServerQMPolicyName = NULL;
gpszServerMMPolicyName = NULL;
ghSTxFilter = NULL;
ghSTxOutFilter = NULL;
ghSTxInFilter = NULL;
ghSMMFilter = NULL;
ghSMMOutFilter = NULL;
ghSMMInFilter = NULL;
gbSQMPolicyAdded = FALSE;
gbSMMAuthAdded = FALSE;
gbSMMPolicyAdded = FALSE;
dwServerConnectionCount--;
//
// Server Count is now 0
//
break;
case RAS_L2TP_REQUIRE_ENCRYPTION:
case RAS_L2TP_REQUIRE_MAX_ENCRYPTION:
if (ghSTxFilter) {
dwStatus = DeleteTransportFilter(
ghSTxFilter
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
if (ghSMMFilter) {
dwStatus = DeleteMMFilter(
ghSMMFilter
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
if (gbSQMPolicyAdded) {
dwStatus = DeleteQMPolicy(
NULL,
gpszServerQMPolicyName
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
if (gbSMMPolicyAdded) {
dwStatus = DeleteMMPolicy(
NULL,
gpszServerMMPolicyName
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
if (gbSMMAuthAdded) {
dwStatus = DeleteMMAuthMethods(
NULL,
gServerMMAuthID
);
}
if (dwStatus) {
dwServerConnectionCount = 0;
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
memset(&gServerQMPolicyID, 0, sizeof(GUID));
memset(&gServerMMPolicyID, 0, sizeof(GUID));
memset(&gServerMMAuthID, 0, sizeof(GUID));
memset(&gServerTxFilterID, 0, sizeof(GUID));
memset(&gServerOutTxFilterID, 0, sizeof(GUID));
memset(&gServerInTxFilterID, 0, sizeof(GUID));
memset(&gServerMMFilterID, 0, sizeof(GUID));
memset(&gServerOutMMFilterID, 0, sizeof(GUID));
memset(&gServerInMMFilterID, 0, sizeof(GUID));
gpszServerQMPolicyName = NULL;
gpszServerMMPolicyName = NULL;
ghSTxFilter = NULL;
ghSTxOutFilter = NULL;
ghSTxInFilter = NULL;
ghSMMFilter = NULL;
ghSMMOutFilter = NULL;
ghSMMInFilter = NULL;
gbSQMPolicyAdded = FALSE;
gbSMMAuthAdded = FALSE;
gbSMMPolicyAdded = FALSE;
dwServerConnectionCount--;
//
// Server Count is now 0
//
break;
}
}
else {
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"DwDeleteServerIpSecFilter: ref count = 0, rc=0x%x",
dwStatus);
}
ppcb->PCB_fFilterPresent = FALSE;
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"DwDeleteClientIpSecFilter: rc=0x%x",
dwStatus);
return dwStatus;
}
DWORD
DwDeleteClientIpSecFilter(
pPCB ppcb
)
{
PIPSEC_SRV_NODE pServerNode = NULL;
DWORD dwStatus = ERROR_SUCCESS;
RAS_L2TP_ENCRYPTION eEncryption = 0;
pServerNode = FindServerNode(
gpIpSecSrvList,
ppcb->PCB_ulDestAddr
);
if (!pServerNode) {
dwStatus = ERROR_INVALID_PARAMETER;
goto error;
}
if (pServerNode->dwRefCount > 1) {
pServerNode->dwRefCount--;
} else {
eEncryption = pServerNode->eEncryption;
switch (eEncryption) {
case RAS_L2TP_NO_ENCRYPTION:
case RAS_L2TP_REQUIRE_ENCRYPTION:
case RAS_L2TP_OPTIONAL_ENCRYPTION:
case RAS_L2TP_REQUIRE_MAX_ENCRYPTION:
if (pServerNode->hTxFilter) {
dwStatus = DeleteTransportFilter(
pServerNode->hTxFilter
);
if (dwStatus) {
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
}
if (pServerNode->hMMFilter) {
dwStatus = DeleteMMFilter(
pServerNode->hMMFilter
);
if (dwStatus) {
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
}
dwStatus = DeleteMMAuthMethods(
NULL,
pServerNode->gMMAuthID
);
if (dwStatus) {
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
if (pServerNode->pszQMPolicyName) {
dwStatus = DeleteQMPolicy(
NULL,
pServerNode->pszQMPolicyName
);
if (dwStatus) {
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
}
if (pServerNode->pszMMPolicyName) {
dwStatus = DeleteMMPolicy(
NULL,
pServerNode->pszMMPolicyName
);
if (dwStatus) {
dwStatus = ERROR_INVALID_PARAMETER;
break;
}
}
break;
}
pServerNode->dwRefCount--;
//
// Client Count is now 0
//
gpIpSecSrvList = RemoveNode(
gpIpSecSrvList,
pServerNode
);
}
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"DwDeleteClientIpSecFilter: dwStatus=0x%x, port=%d",
dwStatus,
ppcb->PCB_PortHandle);
error:
return dwStatus;
}
/*++
Routine Description:
Determines if ipsec is enabled on the port. Currently
all this does is enumerates all the SA in the system
and checks to see if l2tp port is specified as dest.
for any of the SAs. This will change once l2tp can
pass up the tuple corresponding to the src/dest through
tapi.
Arguments:
ppcb - port control block for the port
pfEnabled - pointer to a BOOL value to return the
status of ipsec of the port in.
Return Value:
Nothing.
--*/
DWORD
DwIsIpSecEnabled(pPCB ppcb,
BOOL *pfEnabled)
{
DWORD dwStatus = NO_ERROR;
DWORD i = 0;
DWORD SACount = 0;
DWORD ResumeHandle = 0;
PIPSEC_QM_SA pSAList = NULL;
*pfEnabled = FALSE;
dwStatus = DwInitializeIpSec();
do {
dwStatus = DwQueryAssociations(&pSAList, &SACount, &ResumeHandle);
if( (NO_ERROR != dwStatus)
|| (NULL == pSAList))
{
goto done;
}
//
// Run through the list and see if there
// is any filter associted with port 1701
//
for (i = 0; i < SACount; i++)
{
if(L2TP_DEST_PORT ==
pSAList[i].IpsecQMFilter.DesPort.wPort)
{
*pfEnabled = TRUE;
break;
}
}
SPDApiBufferFree(pSAList);
pSAList = NULL;
SACount = 0;
if (*pfEnabled == TRUE) {
break;
}
} while (dwStatus != ERROR_NO_DATA);
done:
return dwStatus;
}
DWORD
DwGetIpSecInformation(pPCB ppcb,
DWORD * pdwIpsecInfo)
{
DWORD dwErr = ERROR_SUCCESS;
PIPSEC_QM_SA pSAList = NULL;
DWORD i = 0, j = 0;
ULONG ulEncryptionAlgo = 0;
DWORD SACount = 0;
DWORD ResumeHandle = 0;
if(NULL == pdwIpsecInfo)
{
dwErr = E_INVALIDARG;
goto done;
}
*pdwIpsecInfo = 0;
do {
if(NULL != pSAList)
{
FreeSAList(pSAList);
pSAList = NULL;
SACount = 0;
}
//
// Query the SA's in the system
//
dwErr = DwQueryAssociations(&pSAList, &SACount, &ResumeHandle);
if( (ERROR_SUCCESS != dwErr)
|| (NULL == pSAList))
{
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"QuerySA returned dwErr=0x%x, pSAList=0x%x",
dwErr,
pSAList);
dwErr = E_FAIL;
goto done;
}
//
// Run through the SAList and find the SA
// corresponding to our policy.
//
for (i = 0; i < SACount; i++)
{
if( ((L2TP_DEST_PORT ==
pSAList[i].IpsecQMFilter.SrcPort.wPort)
|| ( (NULL == ppcb->PCB_Connection)
&& (L2TP_DEST_PORT ==
pSAList[i].IpsecQMFilter.DesPort.wPort)))
&& (ppcb->PCB_ulDestAddr ==
pSAList[i].IpsecQMFilter.DesAddr.uIpAddr))
{
break;
}
}
if (i == SACount)
{
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"No match found for the SA");
dwErr = E_FAIL;
continue;
}
for(j = 0; j < pSAList[i].SelectedQMOffer.dwNumAlgos; j++)
{
if(pSAList[i].SelectedQMOffer.Algos[j].Operation == ENCRYPTION)
{
break;
}
}
if(j == pSAList[i].SelectedQMOffer.dwNumAlgos)
{
//
// Means no encryption algorithms were
// negotiated.
//
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"No Encryption algorithm was returned");
dwErr = E_FAIL;
continue;
}
ulEncryptionAlgo =
(ULONG) pSAList[i].SelectedQMOffer.Algos[j].uAlgoIdentifier;
TracePrintfExA(TraceHandle, RASMAN_TRACE_CONNECTION,
"ulEncryptionAlgo = %d",
ulEncryptionAlgo);
if(ulEncryptionAlgo == (ULONG) IPSEC_DOI_ESP_DES)
{
*pdwIpsecInfo |= RASMAN_IPSEC_ESP_DES;
}
else if(ulEncryptionAlgo == (ULONG) IPSEC_DOI_ESP_3_DES)
{
*pdwIpsecInfo |= RASMAN_IPSEC_ESP_3_DES;
}
break;
} while (dwErr != ERROR_NO_DATA);
done:
if(NULL != pSAList)
{
FreeSAList(pSAList);
}
return dwErr;
}
PIPSEC_SRV_NODE
AddNodeToServerList(
PIPSEC_SRV_NODE pServerList,
RAS_L2TP_ENCRYPTION eEncryption,
DWORD dwIpAddress,
LPWSTR pszMMPolicyName,
GUID gMMPolicyID,
LPWSTR pszQMPolicyName,
GUID gQMPolicyID,
GUID gMMAuthID,
GUID gTxFilterID,
HANDLE hTxFilter,
GUID gMMFilterID,
HANDLE hMMFilter
)
{
PIPSEC_SRV_NODE pNode = NULL;
pNode = (PIPSEC_SRV_NODE)AllocADsMem(
sizeof(IPSEC_SRV_NODE)
);
if (!pNode) {
return (pServerList);
}
memcpy(&(pNode->gMMPolicyID), &gMMPolicyID, sizeof(GUID));
memcpy(&(pNode->gQMPolicyID), &gQMPolicyID, sizeof(GUID));
memcpy(&(pNode->gMMAuthID), &gMMAuthID, sizeof(GUID));
memcpy(&(pNode->gTxFilterID), &gTxFilterID, sizeof(GUID));
memcpy(&(pNode->gMMFilterID), &gMMFilterID, sizeof(GUID));
pNode->dwRefCount = 1;
pNode->dwIpAddress = dwIpAddress;
pNode->eEncryption = eEncryption;
if (pszQMPolicyName && *pszQMPolicyName) {
pNode->pszQMPolicyName = AllocADsStr(
pszQMPolicyName
);
if (!(pNode->pszQMPolicyName)) {
goto error;
}
}
if (pszMMPolicyName && *pszMMPolicyName) {
pNode->pszMMPolicyName = AllocADsStr(
pszMMPolicyName
);
if (!(pNode->pszMMPolicyName)) {
goto error;
}
}
pNode->hTxFilter = hTxFilter;
pNode->hMMFilter = hMMFilter;
pNode->pNext = pServerList;
return (pNode);
error:
if (pNode->pszQMPolicyName) {
FreeADsStr(pNode->pszQMPolicyName);
}
if (pNode->pszMMPolicyName) {
FreeADsStr(pNode->pszMMPolicyName);
}
if (pNode) {
FreeADsMem(pNode);
}
return (pServerList);
}
PIPSEC_SRV_NODE
FindServerNode(
PIPSEC_SRV_NODE pServerList,
DWORD dwIpAddress
)
{
if (pServerList == NULL) {
return (pServerList);
}
while (pServerList) {
if (pServerList->dwIpAddress == dwIpAddress) {
return (pServerList);
}
pServerList = pServerList->pNext;
}
return (pServerList);
}
PIPSEC_SRV_NODE
RemoveNode(
PIPSEC_SRV_NODE pServerList,
PIPSEC_SRV_NODE pNode
)
{
PIPSEC_SRV_NODE pTemp = NULL;
if (pServerList == NULL) {
return(NULL);
}
if (pNode == pServerList) {
pServerList = pServerList->pNext;
if (pNode->pszQMPolicyName) {
FreeADsStr(pNode->pszQMPolicyName);
}
if (pNode->pszMMPolicyName) {
FreeADsStr(pNode->pszMMPolicyName);
}
FreeADsMem(pNode);
return (pServerList);
}
pTemp = pServerList;
while (pTemp->pNext != NULL) {
if (pTemp->pNext == pNode) {
pTemp->pNext = (pTemp->pNext)->pNext;
if (pNode->pszQMPolicyName) {
FreeADsStr(pNode->pszQMPolicyName);
}
if (pNode->pszMMPolicyName) {
FreeADsStr(pNode->pszMMPolicyName);
}
FreeADsMem(pNode);
return(pServerList);
}
pTemp = pTemp->pNext;
}
return (pServerList);
}
DWORD
MapOakleyErrorToRasError(DWORD oakleyerror)
{
DWORD retcode;
switch (oakleyerror)
{
case ERROR_SUCCESS:
{
retcode = ERROR_SUCCESS;
break;
}
case ERROR_IPSEC_IKE_NO_CERT:
case ERROR_IPSEC_IKE_INVALID_CERT_TYPE:
case ERROR_IPSEC_IKE_NO_PRIVATE_KEY:
case ERROR_IPSEC_IKE_NO_PUBLIC_KEY:
{
retcode = ERROR_OAKLEY_NO_CERT;
break;
}
case ERROR_IPSEC_IKE_NO_PEER_CERT:
{
retcode = ERROR_OAKLEY_NO_PEER_CERT;
break;
}
case ERROR_IPSEC_IKE_AUTH_FAIL:
{
retcode = ERROR_OAKLEY_AUTH_FAIL;
break;
}
case ERROR_IPSEC_IKE_NO_POLICY:
{
retcode = ERROR_OAKLEY_NO_POLICY;
break;
}
case ERROR_IPSEC_IKE_ATTRIB_FAIL:
{
retcode = ERROR_OAKLEY_ATTRIB_FAIL;
break;
}
case ERROR_IPSEC_IKE_TIMED_OUT:
case ERROR_IPSEC_IKE_DROP_NO_RESPONSE:
{
retcode = ERROR_OAKLEY_TIMED_OUT;
break;
}
case ERROR_IPSEC_IKE_ERROR:
{
retcode = ERROR_OAKLEY_ERROR;
break;
}
case ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR:
case ERROR_IPSEC_IKE_NEGOTIATION_PENDING:
default:
{
retcode = ERROR_OAKLEY_GENERAL_PROCESSING;
break;
}
}
return retcode;
}
DWORD
DwDoIke(pPCB ppcb, HANDLE hEvent)
{
DWORD retcode = ERROR_SUCCESS;
IPSEC_QM_FILTER myFilter;
DWORD dwAddress;
DWORD dwMask;
RasmanTrace("DwDoIke: port=%s, hEvent=0x%x",
ppcb->PCB_Name,
hEvent);
//
// Get the address of the interface the
// traffic is most likely to go over.
//
retcode = DwGetBestInterface(ppcb->PCB_ulDestAddr,
&dwAddress,
&dwMask);
if(ERROR_SUCCESS != retcode)
{
RasmanTrace(
"DwDoIke: failed to get interface. 0x%x",
retcode);
//
// If we are unable to get a interface to tunnel
// over, return an error that will tell the user
// that the destination is not reachable.
//
retcode = ERROR_BAD_ADDRESS_SPECIFIED;
goto done;
}
memset(&myFilter, 0, sizeof(IPSEC_QM_FILTER));
myFilter.QMFilterType = QM_TRANSPORT_FILTER;
myFilter.SrcAddr.AddrType = IP_ADDR_UNIQUE;
myFilter.SrcAddr.uIpAddr = (ULONG) dwAddress;
myFilter.SrcAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
myFilter.DesAddr.AddrType = IP_ADDR_UNIQUE;
myFilter.DesAddr.uIpAddr = (ULONG) ppcb->PCB_ulDestAddr;
myFilter.DesAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
myFilter.Protocol.ProtocolType = PROTOCOL_UNIQUE;
myFilter.Protocol.dwProtocol = IPPROTO_UDP;
myFilter.SrcPort.PortType = PORT_UNIQUE;
myFilter.SrcPort.wPort = L2TP_DEST_PORT;
myFilter.DesPort.PortType = PORT_UNIQUE;
myFilter.DesPort.wPort = 0;
myFilter.MyTunnelEndpt.AddrType = IP_ADDR_UNIQUE;
myFilter.MyTunnelEndpt.uIpAddr = 0;
myFilter.MyTunnelEndpt.uSubNetMask = IP_ADDRESS_MASK_NONE;
myFilter.PeerTunnelEndpt.AddrType = IP_ADDR_UNIQUE;
myFilter.PeerTunnelEndpt.uIpAddr = 0;
myFilter.PeerTunnelEndpt.uSubNetMask = IP_ADDRESS_MASK_NONE;
myFilter.dwFlags = 0;
ppcb->PCB_hIkeNegotiation = NULL;
retcode = IPSecInitiateIKENegotiation(
NULL,
&myFilter,
GetCurrentProcessId(),
hEvent,
0,
&(ppcb->PCB_hIkeNegotiation)
);
if(ERROR_SUCCESS != retcode)
{
RasmanTrace(
"DwDoIke failed to init negotiation. 0x%x",
retcode);
retcode = MapOakleyErrorToRasError(retcode);
goto done;
}
done:
RasmanTrace("DwDoIke: done. 0x%x",
retcode);
return retcode;
}
DWORD
DwQueryIkeStatus(pPCB ppcb, DWORD * pdwStatus)
{
DWORD retcode = ERROR_SUCCESS;
SA_NEGOTIATION_STATUS_INFO NegotiationStatus;
memset(&NegotiationStatus, 0, sizeof(SA_NEGOTIATION_STATUS_INFO));
RasmanTrace("DwQueryIkeStatus: %s",
ppcb->PCB_Name);
retcode = IPSecQueryIKENegotiationStatus(
ppcb->PCB_hIkeNegotiation,
&NegotiationStatus
);
RasmanTrace(
"DwQueryIkeStatus: Closing Negotiation handle 0x%x",
ppcb->PCB_hIkeNegotiation);
(VOID) IPSecCloseIKENegotiationHandle(
ppcb->PCB_hIkeNegotiation);
ppcb->PCB_hIkeNegotiation = NULL;
*pdwStatus = MapOakleyErrorToRasError(NegotiationStatus.dwError);
RasmanTrace("DwQueryIkeStatus: retcode=0x%x, status=0x%x",
retcode,
NegotiationStatus.dwError);
if(ERROR_SUCCESS != retcode)
{
retcode = MapOakleyErrorToRasError(retcode);
}
return retcode;
}
VOID
BuildOutTxFilter(
PTRANSPORT_FILTER myOutFilter,
GUID gPolicyID,
BOOL bCreateMirror
)
{
if(UuidCreate(&(myOutFilter->gFilterID)))
{
RasmanTrace("UuidCreate returned non-zero value");
}
if (!bCreateMirror) {
myOutFilter->pszFilterName = gpszServOutFilterName;
}
else {
myOutFilter->pszFilterName = gpszServFilterName;
}
myOutFilter->InterfaceType = INTERFACE_TYPE_ALL;
myOutFilter->bCreateMirror = bCreateMirror;
myOutFilter->dwFlags = 0;
myOutFilter->SrcAddr.AddrType = IP_ADDR_UNIQUE;
myOutFilter->SrcAddr.uIpAddr = IP_ADDRESS_ME;
myOutFilter->SrcAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
myOutFilter->DesAddr.AddrType = IP_ADDR_SUBNET;
myOutFilter->DesAddr.uIpAddr = SUBNET_ADDRESS_ANY;
myOutFilter->DesAddr.uSubNetMask = SUBNET_MASK_ANY;
myOutFilter->Protocol.ProtocolType = PROTOCOL_UNIQUE;
myOutFilter->Protocol.dwProtocol = IPPROTO_UDP;
myOutFilter->SrcPort.PortType = PORT_UNIQUE;
myOutFilter->SrcPort.wPort = 0;
myOutFilter->DesPort.PortType = PORT_UNIQUE;
myOutFilter->DesPort.wPort = L2TP_DEST_PORT;
myOutFilter->InboundFilterFlag = NEGOTIATE_SECURITY;
myOutFilter->OutboundFilterFlag = NEGOTIATE_SECURITY;
memcpy(&(myOutFilter->gPolicyID), &(gPolicyID), sizeof(GUID));
}
VOID
BuildInTxFilter(
PTRANSPORT_FILTER myInFilter,
GUID gPolicyID,
BOOL bCreateMirror
)
{
if(UuidCreate(&(myInFilter->gFilterID)))
{
RasmanTrace("UuidCreate returned non-zero value");
}
myInFilter->pszFilterName = gpszServInFilterName;
myInFilter->InterfaceType = INTERFACE_TYPE_ALL;
myInFilter->bCreateMirror = bCreateMirror;
myInFilter->dwFlags = 0;
myInFilter->SrcAddr.AddrType = IP_ADDR_SUBNET;
myInFilter->SrcAddr.uIpAddr = SUBNET_ADDRESS_ANY;
myInFilter->SrcAddr.uSubNetMask = SUBNET_MASK_ANY;
myInFilter->DesAddr.AddrType = IP_ADDR_UNIQUE;
myInFilter->DesAddr.uIpAddr = IP_ADDRESS_ME;
myInFilter->DesAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
myInFilter->Protocol.ProtocolType = PROTOCOL_UNIQUE;
myInFilter->Protocol.dwProtocol = IPPROTO_UDP;
myInFilter->SrcPort.PortType = PORT_UNIQUE;
myInFilter->SrcPort.wPort = L2TP_DEST_PORT;
myInFilter->DesPort.PortType = PORT_UNIQUE;
myInFilter->DesPort.wPort = 0;
myInFilter->InboundFilterFlag = NEGOTIATE_SECURITY;
myInFilter->OutboundFilterFlag = NEGOTIATE_SECURITY;
memcpy(&(myInFilter->gPolicyID), &(gPolicyID), sizeof(GUID));
}
VOID
BuildMMAuth(
PMM_AUTH_METHODS pMMAuthMethods,
PIPSEC_MM_AUTH_INFO pAuthenticationInfo,
DWORD dwNumAuthInfos
)
{
pMMAuthMethods->dwFlags = 0;
pMMAuthMethods->pAuthenticationInfo = pAuthenticationInfo;
pMMAuthMethods->dwNumAuthInfos = dwNumAuthInfos;
}
VOID
BuildQMPolicy(
PIPSEC_QM_POLICY pQMPolicy,
RAS_L2TP_ENCRYPTION eEncryption,
PIPSEC_QM_OFFER pOffers,
DWORD dwNumOffers,
DWORD dwFlags
)
{
switch (eEncryption) {
case RAS_L2TP_NO_ENCRYPTION:
pQMPolicy->pszPolicyName = gpszQMPolicyNameNo;
break;
case RAS_L2TP_OPTIONAL_ENCRYPTION:
pQMPolicy->pszPolicyName = gpszQMPolicyNameOpt;
break;
case RAS_L2TP_REQUIRE_ENCRYPTION:
pQMPolicy->pszPolicyName = gpszQMPolicyNameReq;
break;
case RAS_L2TP_REQUIRE_MAX_ENCRYPTION:
pQMPolicy->pszPolicyName = gpszQMPolicyNameMax;
break;
}
pQMPolicy-> dwFlags = dwFlags;
pQMPolicy->pOffers = pOffers;
pQMPolicy->dwOfferCount = dwNumOffers;
}
VOID
BuildCTxFilter(
PTRANSPORT_FILTER myFilter,
GUID gPolicyID,
ULONG uDesIpAddr,
BOOL bCreateMirror
)
{
if(UuidCreate(&(myFilter->gFilterID)))
{
RasmanTrace("UuidCreate returned non-zero value");
}
myFilter->pszFilterName = gpszClntFilterName;
myFilter->InterfaceType = INTERFACE_TYPE_ALL;
myFilter->bCreateMirror = bCreateMirror;
myFilter->dwFlags = 0;
myFilter->SrcAddr.AddrType = IP_ADDR_UNIQUE;
myFilter->SrcAddr.uIpAddr = IP_ADDRESS_ME;
myFilter->SrcAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
myFilter->DesAddr.AddrType = IP_ADDR_UNIQUE;
myFilter->DesAddr.uIpAddr = uDesIpAddr;
myFilter->DesAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
myFilter->Protocol.ProtocolType = PROTOCOL_UNIQUE;
myFilter->Protocol.dwProtocol = IPPROTO_UDP;
myFilter->SrcPort.PortType = PORT_UNIQUE;
myFilter->SrcPort.wPort = L2TP_DEST_PORT;
myFilter->DesPort.PortType = PORT_UNIQUE;
myFilter->DesPort.wPort = 0;
myFilter->InboundFilterFlag = NEGOTIATE_SECURITY;
myFilter->OutboundFilterFlag = NEGOTIATE_SECURITY;
memcpy(&(myFilter->gPolicyID), &(gPolicyID), sizeof(GUID));
}
VOID
BuildOutMMFilter(
PMM_FILTER myOutFilter,
GUID gPolicyID,
GUID gMMAuthID,
BOOL bCreateMirror
)
{
if(UuidCreate(&(myOutFilter->gFilterID)))
{
RasmanTrace("UuidCreate returned non-zero value");
}
if (!bCreateMirror) {
myOutFilter->pszFilterName = gpszServOutFilterName;
}
else {
myOutFilter->pszFilterName = gpszServFilterName;
}
myOutFilter->InterfaceType = INTERFACE_TYPE_ALL;
myOutFilter->bCreateMirror = bCreateMirror;
myOutFilter->dwFlags = 0;
myOutFilter->SrcAddr.AddrType = IP_ADDR_UNIQUE;
myOutFilter->SrcAddr.uIpAddr = IP_ADDRESS_ME;
myOutFilter->SrcAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
myOutFilter->DesAddr.AddrType = IP_ADDR_SUBNET;
myOutFilter->DesAddr.uIpAddr = SUBNET_ADDRESS_ANY;
myOutFilter->DesAddr.uSubNetMask = SUBNET_MASK_ANY;
memcpy(&(myOutFilter->gPolicyID), &(gPolicyID), sizeof(GUID));
memcpy(&(myOutFilter->gMMAuthID), &(gMMAuthID), sizeof(GUID));
}
VOID
BuildInMMFilter(
PMM_FILTER myInFilter,
GUID gPolicyID,
GUID gMMAuthID,
BOOL bCreateMirror
)
{
if(UuidCreate(&(myInFilter->gFilterID)))
{
RasmanTrace("UuidCreate returned non-zero value");
}
myInFilter->pszFilterName = gpszServInFilterName;
myInFilter->InterfaceType = INTERFACE_TYPE_ALL;
myInFilter->bCreateMirror = bCreateMirror;
myInFilter->dwFlags = 0;
myInFilter->SrcAddr.AddrType = IP_ADDR_SUBNET;
myInFilter->SrcAddr.uIpAddr = SUBNET_ADDRESS_ANY;
myInFilter->SrcAddr.uSubNetMask = SUBNET_MASK_ANY;
myInFilter->DesAddr.AddrType = IP_ADDR_UNIQUE;
myInFilter->DesAddr.uIpAddr = IP_ADDRESS_ME;
myInFilter->DesAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
memcpy(&(myInFilter->gPolicyID), &(gPolicyID), sizeof(GUID));
memcpy(&(myInFilter->gMMAuthID), &(gMMAuthID), sizeof(GUID));
}
VOID
BuildCMMFilter(
PMM_FILTER myFilter,
GUID gPolicyID,
GUID gMMAuthID,
ULONG uDesIpAddr,
BOOL bCreateMirror
)
{
if(UuidCreate(&(myFilter->gFilterID)))
{
RasmanTrace("UuidCreate didn't return S_OK");
}
myFilter->pszFilterName = gpszClntFilterName;
myFilter->InterfaceType = INTERFACE_TYPE_ALL;
myFilter->bCreateMirror = bCreateMirror;
myFilter->dwFlags = 0;
myFilter->SrcAddr.AddrType = IP_ADDR_UNIQUE;
myFilter->SrcAddr.uIpAddr = IP_ADDRESS_ME;
myFilter->SrcAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
myFilter->DesAddr.AddrType = IP_ADDR_UNIQUE;
myFilter->DesAddr.uIpAddr = uDesIpAddr;
myFilter->DesAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
memcpy(&(myFilter->gPolicyID), &(gPolicyID), sizeof(GUID));
memcpy(&(myFilter->gMMAuthID), &(gMMAuthID), sizeof(GUID));
}
VOID
BuildMMOffers(
PIPSEC_MM_OFFER pMMOffers,
PDWORD pdwMMOfferCount,
PDWORD pdwMMFlags
)
{
PIPSEC_MM_OFFER pMMOffer = pMMOffers;
ConstructMMOffer(
pMMOffer,
DEFAULT_MM_KEY_EXPIRATION_TIME, 0,
0,
0,
DH_GROUP_2,
IPSEC_DOI_ESP_3_DES, 0, 0,
IPSEC_DOI_AH_SHA1, 0, 0
);
pMMOffer++;
ConstructMMOffer(
pMMOffer,
DEFAULT_MM_KEY_EXPIRATION_TIME, 0,
0,
0,
DH_GROUP_2,
IPSEC_DOI_ESP_3_DES, 0, 0,
IPSEC_DOI_AH_MD5, 0, 0
);
pMMOffer++;
ConstructMMOffer(
pMMOffer,
DEFAULT_MM_KEY_EXPIRATION_TIME, 0,
0,
0,
DH_GROUP_1,
IPSEC_DOI_ESP_DES, 0, 0,
IPSEC_DOI_AH_SHA1, 0, 0
);
pMMOffer++;
ConstructMMOffer(
pMMOffer,
DEFAULT_MM_KEY_EXPIRATION_TIME, 0,
0,
0,
DH_GROUP_1,
IPSEC_DOI_ESP_DES, 0, 0,
IPSEC_DOI_AH_MD5, 0, 0
);
pMMOffer++;
*pdwMMOfferCount = 4;
*pdwMMFlags = IPSEC_MM_POLICY_DISABLE_CRL;
}
VOID
ConstructMMOffer(
PIPSEC_MM_OFFER pMMOffer,
ULONG uTime,
ULONG uBytes,
DWORD dwFlags,
DWORD dwQuickModeLimit,
DWORD dwDHGroup,
ULONG uEspAlgo,
ULONG uEspLen,
ULONG uEspRounds,
ULONG uAHAlgo,
ULONG uAHLen,
ULONG uAHRounds
)
{
pMMOffer->Lifetime.uKeyExpirationTime = uTime,
pMMOffer->Lifetime.uKeyExpirationKBytes = uBytes;
pMMOffer->dwFlags = dwFlags;
pMMOffer->dwQuickModeLimit = dwQuickModeLimit;
pMMOffer->dwDHGroup = dwDHGroup;
pMMOffer->EncryptionAlgorithm.uAlgoIdentifier = uEspAlgo;
pMMOffer->EncryptionAlgorithm.uAlgoKeyLen = uEspLen;
pMMOffer->EncryptionAlgorithm.uAlgoRounds = uEspRounds;
pMMOffer->HashingAlgorithm.uAlgoIdentifier = uAHAlgo;
pMMOffer->HashingAlgorithm.uAlgoKeyLen = uAHLen;
pMMOffer->HashingAlgorithm.uAlgoRounds = uAHRounds;
}
VOID
BuildMMPolicy(
PIPSEC_MM_POLICY pMMPolicy,
PIPSEC_MM_OFFER pMMOffers,
DWORD dwMMOfferCount,
DWORD dwMMFlags
)
{
pMMPolicy->pszPolicyName = gpszMMPolicyName;
pMMPolicy->dwFlags = dwMMFlags;
pMMPolicy->uSoftSAExpirationTime = DEFAULT_MM_KEY_EXPIRATION_TIME;
pMMPolicy->pOffers = pMMOffers;
pMMPolicy->dwOfferCount = dwMMOfferCount;
}