1300 lines
42 KiB
C++
1300 lines
42 KiB
C++
/////////////////////////////////////////////////////////////
|
||
// Copyright(c) 1998-2000, Microsoft Corporation
|
||
//
|
||
// text2pol.cpp
|
||
//
|
||
// Created on 4/5/98 by Randyram
|
||
// Revisions:
|
||
// Moved the routines to this module 8/25/98
|
||
//
|
||
// Split into text2pol.cpp, text2spd.h and text2spd.cpp 2/15/00 DKalin
|
||
//
|
||
// Implementation for the text to policy conversion routines (generic ones)
|
||
// (See more in the text2spd.cpp)
|
||
//
|
||
/////////////////////////////////////////////////////////////
|
||
|
||
#include "ipseccmd.h"
|
||
|
||
|
||
|
||
// CFilter storage version
|
||
DWORD ConvertFilter(IN T2P_FILTER &Filter,
|
||
IN OUT IPSEC_FILTER_SPEC &PolstoreFilter)
|
||
{
|
||
DWORD dwReturn = T2P_OK; // return code of this function
|
||
|
||
PolstoreFilter.pszSrcDNSName = PolstoreFilter.pszDestDNSName = 0;
|
||
|
||
if (Filter.QMFilterType == QM_TRANSPORT_FILTER)
|
||
{
|
||
PolstoreFilter.FilterSpecGUID = Filter.TransportFilter.gFilterID;
|
||
PolstoreFilter.pszDescription = IPSecAllocPolStr(Filter.TransportFilter.pszFilterName);
|
||
PolstoreFilter.dwMirrorFlag = Filter.TransportFilter.bCreateMirror;
|
||
|
||
PolstoreFilter.Filter.SrcAddr = Filter.TransportFilter.SrcAddr.uIpAddr;
|
||
PolstoreFilter.Filter.SrcMask = Filter.TransportFilter.SrcAddr.uSubNetMask;
|
||
PolstoreFilter.Filter.DestAddr = Filter.TransportFilter.DesAddr.uIpAddr;
|
||
PolstoreFilter.Filter.DestMask = Filter.TransportFilter.DesAddr.uSubNetMask;
|
||
PolstoreFilter.Filter.TunnelAddr = 0;
|
||
PolstoreFilter.Filter.Protocol = Filter.TransportFilter.Protocol.dwProtocol;
|
||
PolstoreFilter.Filter.SrcPort = Filter.TransportFilter.SrcPort.wPort;
|
||
PolstoreFilter.Filter.DestPort = Filter.TransportFilter.DesPort.wPort;
|
||
PolstoreFilter.Filter.TunnelFilter = FALSE;
|
||
}
|
||
else
|
||
{
|
||
// tunnel filter
|
||
PolstoreFilter.FilterSpecGUID = Filter.TunnelFilter.gFilterID;
|
||
PolstoreFilter.pszDescription = IPSecAllocPolStr(Filter.TunnelFilter.pszFilterName);
|
||
PolstoreFilter.dwMirrorFlag = FALSE;
|
||
|
||
PolstoreFilter.Filter.SrcAddr = Filter.TunnelFilter.SrcAddr.uIpAddr;
|
||
PolstoreFilter.Filter.SrcMask = Filter.TunnelFilter.SrcAddr.uSubNetMask;
|
||
PolstoreFilter.Filter.DestAddr = Filter.TunnelFilter.DesAddr.uIpAddr;
|
||
PolstoreFilter.Filter.DestMask = Filter.TunnelFilter.DesAddr.uSubNetMask;
|
||
PolstoreFilter.Filter.TunnelAddr = Filter.TunnelFilter.DesTunnelAddr.uIpAddr;
|
||
PolstoreFilter.Filter.Protocol = Filter.TunnelFilter.Protocol.dwProtocol;
|
||
PolstoreFilter.Filter.SrcPort = Filter.TunnelFilter.SrcPort.wPort;
|
||
PolstoreFilter.Filter.DestPort = Filter.TunnelFilter.DesPort.wPort;
|
||
PolstoreFilter.Filter.TunnelFilter = TRUE;
|
||
}
|
||
|
||
return dwReturn;
|
||
}
|
||
|
||
|
||
DWORD TextToStorageLocation(IN char *szText, OUT STORAGE_INFO & StoreInfo)
|
||
{
|
||
DWORD dwReturn = T2P_OK;
|
||
WCHAR *pString = NULL,
|
||
*pTmp = NULL;
|
||
WCHAR szTmp[POTF_MAX_STRLEN];
|
||
WCHAR *Info = NULL;
|
||
|
||
if (szText != NULL)
|
||
{
|
||
// copy szText so we can muck with it
|
||
|
||
_stprintf(szTmp, TEXT("%S"), szText);
|
||
|
||
// parse string
|
||
if ( (pString = wcschr(szTmp, POTF_STORAGE_TOKEN)) != NULL )
|
||
*pString = L'\0';
|
||
|
||
if (towlower(szTmp[0]) == tolower(POTF_STORAGE_DS[0]))
|
||
{
|
||
StoreInfo.Type = STORAGE_TYPE_DS;
|
||
|
||
if ((pString != NULL) && (wcslen(pString + 1) > 0) )
|
||
{
|
||
++pString; // now pointing at string
|
||
|
||
wcscpy(StoreInfo.szLocationName, pString);
|
||
}
|
||
// else no domain provided
|
||
}
|
||
else if (towlower(szTmp[0]) == tolower(POTF_STORAGE_REG[0]))
|
||
{
|
||
StoreInfo.Type = STORAGE_TYPE_REGISTRY;
|
||
}
|
||
else if (towlower(szTmp[0]) == tolower(POTF_STORAGE_CACHE[0]))
|
||
{
|
||
StoreInfo.Type = STORAGE_TYPE_CACHE;
|
||
}
|
||
else // invalid option
|
||
{
|
||
dwReturn = T2P_INVALID_STORAGE_INFO;
|
||
}
|
||
|
||
}
|
||
else
|
||
dwReturn = T2P_NULL_STRING;
|
||
|
||
return dwReturn;
|
||
}
|
||
|
||
// the whole reason to have this is to extract the polling interval
|
||
// if specified
|
||
DWORD TextToPolicyName(IN char *szText, OUT STORAGE_INFO & StoreInfo)
|
||
{
|
||
DWORD dwReturn = T2P_OK;
|
||
WCHAR *pString = NULL,
|
||
*pTmp = NULL;
|
||
WCHAR szTmp[POTF_MAX_STRLEN];
|
||
WCHAR *Info = NULL;
|
||
|
||
if (szText != NULL)
|
||
{
|
||
// copy szText so we can muck with it
|
||
|
||
_stprintf(szTmp, TEXT("%S"), szText);
|
||
|
||
// parse string
|
||
if ( (pString = wcschr(szTmp, POTF_STORAGE_TOKEN)) != NULL )
|
||
*pString = '\0';
|
||
|
||
wcscpy(StoreInfo.szPolicyName, szTmp);
|
||
|
||
if ((pString != NULL) && (wcslen(pString + 1) > 0) )
|
||
{
|
||
++pString; // now pointing at polling interval
|
||
|
||
// XX could be checked more stringently
|
||
// do the converstion to minutes here
|
||
StoreInfo.tPollingInterval = 60 * (wcstol(pString, NULL, 10));
|
||
}
|
||
|
||
}
|
||
else
|
||
dwReturn = T2P_NULL_STRING;
|
||
|
||
return dwReturn;
|
||
}
|
||
|
||
bool InStorageMode(IN UINT uArgCount, IN char *strArgs[])
|
||
{
|
||
for (UINT i = 0; i < uArgCount; ++i)
|
||
if ( strArgs[i][1] == POTF_STORAGE_FLAG )
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
// CmdLineToPolicy
|
||
|
||
// pStorageInfo has NULL as default
|
||
// Returns False if there is any kind of failure
|
||
|
||
DWORD CmdLineToPolicy(IN UINT uArgCount, IN char *strArgs[],
|
||
OUT IPSEC_IKE_POLICY & IpsecIkePol,
|
||
OUT bool & bConfirm
|
||
,OUT PSTORAGE_INFO pStorageInfo)
|
||
{
|
||
|
||
DWORD dwReturn = T2P_OK;
|
||
|
||
IPSEC_QM_POLICY IpsPol;
|
||
IPSEC_MM_POLICY IkePol;
|
||
MM_AUTH_METHODS AuthInfos;
|
||
MM_FILTER* pMMFilters;
|
||
DWORD dwNumMMFilters;
|
||
QM_FILTER_TYPE QMFilterType;
|
||
DWORD dwNumFilters;
|
||
TRANSPORT_FILTER* pTransportFilters;
|
||
TUNNEL_FILTER* pTunnelFilters;
|
||
|
||
memcpy(&IpsPol, &IpsecIkePol.IpsPol, sizeof(IpsPol));
|
||
memcpy(&IkePol, &IpsecIkePol.IkePol, sizeof(IkePol));
|
||
memcpy(&AuthInfos, &IpsecIkePol.AuthInfos, sizeof(AuthInfos));
|
||
|
||
pMMFilters = IpsecIkePol.pMMFilters;
|
||
dwNumMMFilters = IpsecIkePol.dwNumMMFilters;
|
||
QMFilterType = IpsecIkePol.QMFilterType;
|
||
dwNumFilters = IpsecIkePol.dwNumFilters;
|
||
pTransportFilters = IpsecIkePol.pTransportFilters;
|
||
pTunnelFilters = IpsecIkePol.pTunnelFilters;
|
||
|
||
// used when finding out how much mem to alloc
|
||
UINT uFiltAlloc = 0,
|
||
uMMFiltAlloc = 0,
|
||
uSecMetAlloc = 0,
|
||
uOfferAlloc = 0,
|
||
uAuthAlloc = 0;
|
||
|
||
UINT i = 0; // loop cntr
|
||
bool bIsMirrorFilt = false,
|
||
bMirrorFiltRC = true; // since MirrorFilt is not a T2P mod
|
||
|
||
T2P_FILTER Filter; // for TextToFilter calls
|
||
memset(&Filter, 0, sizeof(Filter));
|
||
Filter.QMFilterType = QM_TRANSPORT_FILTER; // by default it's transport
|
||
|
||
bConfirm = false;
|
||
|
||
// for post-processing Ike policy
|
||
bool bP1RekeyUsed = false;
|
||
KEY_LIFETIME OakLife;
|
||
DWORD QMLimit = POTF_DEFAULT_P1REKEY_QMS;
|
||
OakLife.uKeyExpirationTime = POTF_DEFAULT_P1REKEY_TIME;
|
||
OakLife.uKeyExpirationKBytes = 0; // not used
|
||
|
||
IF_TYPE Interface = INTERFACE_TYPE_ALL;
|
||
|
||
IPAddr DesTunnelAddr = 0;
|
||
IPAddr SrcTunnelAddr = 0;
|
||
|
||
// We do some things differently in storage mode:
|
||
// * process negotiation policy actions
|
||
// * use a different filter list
|
||
//
|
||
// This could all be much cleaner, but until the cmd line
|
||
// parsing is actually separated from the policy processing
|
||
// we're pretty much stuck with this unless we want to duplicated
|
||
// alot of code. eg. 2 cmdlinetopolicy, one dynamic, one storage
|
||
//
|
||
|
||
bool bStorageMode = InStorageMode(uArgCount, strArgs);
|
||
|
||
if ( bStorageMode && !pStorageInfo )
|
||
return T2P_NO_STORAGE_INFO;
|
||
|
||
//
|
||
// we'll allow the cmd line to specify
|
||
// storage options. Use a temp structure to hold those
|
||
// options-- then we'll copy it at the end if pStorageInfo != NULL
|
||
//
|
||
|
||
STORAGE_INFO tmpStorageInfo;
|
||
memset(&tmpStorageInfo, 0, sizeof(tmpStorageInfo));
|
||
tmpStorageInfo.guidNegPolAction = GUID_NEGOTIATION_ACTION_NORMAL_IPSEC;
|
||
|
||
// init OUT params (free them if necessary)
|
||
|
||
if (IkePol.pOffers != NULL)
|
||
{
|
||
free(IkePol.pOffers);
|
||
}
|
||
IkePol.pOffers = NULL;
|
||
IkePol.dwOfferCount = 0;
|
||
|
||
if (IpsPol.pOffers != NULL)
|
||
{
|
||
free(IpsPol.pOffers);
|
||
}
|
||
IpsPol.pOffers = NULL;
|
||
IpsPol.dwOfferCount = 0;
|
||
|
||
if (AuthInfos.pAuthenticationInfo != NULL)
|
||
{
|
||
for (i = 0; i < (UINT) AuthInfos.dwNumAuthInfos; i++)
|
||
{
|
||
if (AuthInfos.pAuthenticationInfo[i].pAuthInfo != NULL)
|
||
free(AuthInfos.pAuthenticationInfo[i].pAuthInfo);
|
||
}
|
||
free(AuthInfos.pAuthenticationInfo);
|
||
}
|
||
AuthInfos.pAuthenticationInfo = NULL;
|
||
AuthInfos.dwNumAuthInfos = NULL;
|
||
|
||
// cleanup filters
|
||
if (pTransportFilters != NULL)
|
||
{
|
||
for (i = 0; i < (UINT) dwNumFilters; i++)
|
||
{
|
||
if (pTransportFilters[i].pszFilterName != NULL)
|
||
free(pTransportFilters[i].pszFilterName);
|
||
}
|
||
free(pTransportFilters);
|
||
}
|
||
pTransportFilters = NULL;
|
||
|
||
if (pTunnelFilters != NULL)
|
||
{
|
||
for (i = 0; i < (UINT) dwNumFilters; i++)
|
||
{
|
||
if (pTunnelFilters[i].pszFilterName != NULL)
|
||
free(pTunnelFilters[i].pszFilterName);
|
||
}
|
||
free(pTunnelFilters);
|
||
}
|
||
pTunnelFilters = NULL;
|
||
|
||
QMFilterType = Filter.QMFilterType;
|
||
dwNumFilters = 0;
|
||
|
||
// mm filters
|
||
if (pMMFilters != NULL)
|
||
{
|
||
for (i = 0; i < (UINT) dwNumMMFilters; i++)
|
||
{
|
||
if (pMMFilters[i].pszFilterName != NULL)
|
||
free(pMMFilters[i].pszFilterName);
|
||
}
|
||
free(pMMFilters);
|
||
}
|
||
pMMFilters = NULL;
|
||
|
||
dwNumMMFilters = 0;
|
||
|
||
// we assume uArgCount and strArgs are OK
|
||
// but defend against ######### here
|
||
if (uArgCount > 0 && strArgs != NULL)
|
||
{
|
||
// find out how much memory we're going to need
|
||
// we do this here because I allow multiple flags of same type
|
||
for (i = 1; i < uArgCount; )
|
||
{
|
||
if ( strchr(POTF_FLAG_TOKENS, strArgs[i][0]) != NULL )
|
||
{
|
||
if (strArgs[i][1] == POTF_FILTER_FLAG)
|
||
{
|
||
if (strArgs[i][2] != '\0') // user omitted space
|
||
{
|
||
++uFiltAlloc;
|
||
}
|
||
|
||
++i;
|
||
|
||
while ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
++uFiltAlloc;
|
||
++i;
|
||
}
|
||
}
|
||
else if (strArgs[i][1] == POTF_NEGPOL_FLAG)
|
||
{
|
||
if (strArgs[i][2] != '\0') // user omitted space
|
||
++uOfferAlloc;
|
||
|
||
++i;
|
||
|
||
while ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
++uOfferAlloc;
|
||
++i;
|
||
}
|
||
}
|
||
else if (strArgs[i][1] == POTF_AUTH_FLAG)
|
||
{
|
||
if (strArgs[i][2] != '\0') // user omitted space
|
||
++uAuthAlloc;
|
||
|
||
++i;
|
||
|
||
while ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
++uAuthAlloc;
|
||
++i;
|
||
}
|
||
}
|
||
else if ( strncmp(&strArgs[i][1], POTF_SECMETHOD_FLAG,
|
||
strlen(POTF_SECMETHOD_FLAG)) == 0 )
|
||
{
|
||
if (strArgs[i][3] != '\0') // user omitted space
|
||
++uSecMetAlloc;
|
||
|
||
++i;
|
||
|
||
while ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
++uSecMetAlloc;
|
||
++i;
|
||
}
|
||
}
|
||
else if ( strncmp(&strArgs[i][1], POTF_MMFILTER_FLAG,
|
||
strlen(POTF_MMFILTER_FLAG)) == 0 )
|
||
{
|
||
if (strArgs[i][3] != '\0') // user omitted space
|
||
++uMMFiltAlloc;
|
||
|
||
++i;
|
||
|
||
while ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
++uMMFiltAlloc;
|
||
++i;
|
||
}
|
||
}
|
||
else if (strArgs[i][1] == POTF_TUNNEL_FLAG)
|
||
{
|
||
// switch to tunnel mode
|
||
QMFilterType = Filter.QMFilterType = QM_TUNNEL_FILTER;
|
||
i++;
|
||
}
|
||
else
|
||
++i;
|
||
}
|
||
else
|
||
++i;
|
||
}
|
||
|
||
// now allocate the memory
|
||
if (uFiltAlloc)
|
||
{
|
||
// we allocate both transport and tunnel filter storage because of RPC reasons
|
||
|
||
pTransportFilters = new TRANSPORT_FILTER[uFiltAlloc + 1];
|
||
assert(pTransportFilters != NULL);
|
||
|
||
// init these
|
||
for (i = 0; i <= uFiltAlloc; ++i)
|
||
memset(&pTransportFilters[i], 0, sizeof(TRANSPORT_FILTER));
|
||
memset(&Filter.TransportFilter, 0, sizeof(TRANSPORT_FILTER));
|
||
|
||
// tunnel mode
|
||
pTunnelFilters = new TUNNEL_FILTER[uFiltAlloc + 1];
|
||
assert(pTunnelFilters != NULL);
|
||
|
||
// init these
|
||
for (i = 0; i <= uFiltAlloc; ++i)
|
||
memset(&pTunnelFilters[i], 0, sizeof(TUNNEL_FILTER));
|
||
memset(&Filter.TunnelFilter, 0, sizeof(TUNNEL_FILTER));
|
||
|
||
if (!uMMFiltAlloc)
|
||
{
|
||
// allocate main mode filters for auto-generation
|
||
pMMFilters = new MM_FILTER[uFiltAlloc + 1];
|
||
assert(pMMFilters != NULL);
|
||
|
||
// init these
|
||
for (i = 0; i <= uFiltAlloc; ++i)
|
||
memset(&pMMFilters[i], 0, sizeof(MM_FILTER));
|
||
}
|
||
}
|
||
if (uMMFiltAlloc)
|
||
{
|
||
// allocate main mode filters
|
||
pMMFilters = new MM_FILTER[uMMFiltAlloc + 1];
|
||
assert(pMMFilters != NULL);
|
||
|
||
// init these
|
||
for (i = 0; i <= uMMFiltAlloc; ++i)
|
||
memset(&pMMFilters[i], 0, sizeof(MM_FILTER));
|
||
}
|
||
if (uAuthAlloc)
|
||
{
|
||
AuthInfos.pAuthenticationInfo = new IPSEC_MM_AUTH_INFO[uAuthAlloc + 1];
|
||
assert(AuthInfos.pAuthenticationInfo != NULL);
|
||
|
||
// init these
|
||
for (i = 0; i <= uAuthAlloc; ++i)
|
||
memset(&AuthInfos.pAuthenticationInfo[i], 0, sizeof(IPSEC_MM_AUTH_INFO));
|
||
}
|
||
if (uOfferAlloc)
|
||
{
|
||
IpsPol.pOffers = new IPSEC_QM_OFFER[uOfferAlloc + 1];
|
||
assert(IpsPol.pOffers != NULL);
|
||
|
||
// init these
|
||
for (i = 0; i <= uOfferAlloc; ++i)
|
||
{
|
||
memset(&IpsPol.pOffers[i], 0, sizeof(IPSEC_QM_OFFER));
|
||
}
|
||
}
|
||
if (uSecMetAlloc)
|
||
{
|
||
IkePol.pOffers = new IPSEC_MM_OFFER[uSecMetAlloc + 1];
|
||
assert(IkePol.pOffers != NULL);
|
||
|
||
// init these
|
||
for (i = 0; i <= uSecMetAlloc; ++i)
|
||
{
|
||
memset(&IkePol.pOffers[i], 0, sizeof(IPSEC_MM_OFFER));
|
||
}
|
||
}
|
||
|
||
// Main processing loop ////////////////////////////////////////////////////////
|
||
// invariants;
|
||
// 1. use dwReturn when calling util functions, if returns false
|
||
// break out of for loop and let cleanup code take over
|
||
// 2. advance i each time you process a param
|
||
for (i = 1; i < uArgCount && T2P_SUCCESS(dwReturn); ) // we'll advance i below
|
||
{
|
||
// make sure there is actually a flag, else we have parse error
|
||
if ( strchr(POTF_FLAG_TOKENS, strArgs[i][0]) != NULL )
|
||
{
|
||
if (strArgs[i][1] == POTF_FILTER_FLAG) // filter list
|
||
{
|
||
// first filter is special case because user may
|
||
// omit space after flag
|
||
if ((strArgs[i][2] != '\0')
|
||
&& (strchr(POTF_FLAG_TOKENS, strArgs[i][2]) == NULL))
|
||
{
|
||
//
|
||
// Even if we're in storage mode, we use these
|
||
// filters.
|
||
//
|
||
|
||
dwReturn = TextToFilter(&strArgs[i][2], Filter);
|
||
if (QMFilterType == QM_TRANSPORT_FILTER)
|
||
{
|
||
memcpy(&pTransportFilters[dwNumFilters], &Filter.TransportFilter, sizeof(TRANSPORT_FILTER));
|
||
}
|
||
else
|
||
{
|
||
// tunnel
|
||
memcpy(&pTunnelFilters[dwNumFilters], &Filter.TunnelFilter, sizeof(TUNNEL_FILTER));
|
||
}
|
||
|
||
if (!T2P_SUCCESS(dwReturn))
|
||
break;
|
||
else
|
||
{
|
||
++dwNumFilters;
|
||
}
|
||
}
|
||
else if (strArgs[i][2] != '\0')
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"Unexpected flag: %s. Check usage.\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
break;
|
||
}
|
||
|
||
++i; // advance to next arg
|
||
|
||
while ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
//
|
||
// Even if we're in storage mode, we fill these in
|
||
//
|
||
|
||
dwReturn = TextToFilter(&strArgs[i][0], Filter);
|
||
if (QMFilterType == QM_TRANSPORT_FILTER)
|
||
{
|
||
memcpy(&pTransportFilters[dwNumFilters], &Filter.TransportFilter, sizeof(TRANSPORT_FILTER));
|
||
}
|
||
else
|
||
{
|
||
// tunnel
|
||
memcpy(&pTunnelFilters[dwNumFilters], &Filter.TunnelFilter, sizeof(TUNNEL_FILTER));
|
||
}
|
||
|
||
if (!T2P_SUCCESS(dwReturn))
|
||
break;
|
||
else
|
||
{
|
||
++dwNumFilters;
|
||
}
|
||
|
||
++i; // advance to next arg
|
||
}
|
||
}
|
||
else if (strArgs[i][1] == POTF_NEGPOL_FLAG)
|
||
{
|
||
|
||
// first offer is special case because user may
|
||
// omit space after flag
|
||
if ((strArgs[i][2] != '\0')
|
||
&& (strchr(POTF_FLAG_TOKENS, strArgs[i][2]) == NULL))
|
||
{
|
||
if ( !strcmp(&strArgs[i][2], POTF_PASSTHRU) )
|
||
{
|
||
tmpStorageInfo.guidNegPolAction
|
||
= GUID_NEGOTIATION_ACTION_NO_IPSEC;
|
||
}
|
||
else if ( !strcmp(&strArgs[i][2], POTF_INBOUND_PASSTHRU) )
|
||
{
|
||
tmpStorageInfo.guidNegPolAction =
|
||
GUID_NEGOTIATION_ACTION_INBOUND_PASSTHRU;
|
||
}
|
||
else if ( !strcmp(&strArgs[i][2], POTF_BLOCK) )
|
||
{
|
||
tmpStorageInfo.guidNegPolAction =
|
||
GUID_NEGOTIATION_ACTION_BLOCK;
|
||
}
|
||
else
|
||
{
|
||
|
||
dwReturn = TextToOffer(&strArgs[i][2], IpsPol.pOffers[IpsPol.dwOfferCount]);
|
||
|
||
if (!T2P_SUCCESS(dwReturn)) break;
|
||
else ++IpsPol.dwOfferCount;
|
||
}
|
||
}
|
||
else if (strArgs[i][2] != '\0')
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"Unexpected flag: %s. Check usage.\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
break;
|
||
}
|
||
|
||
++i; // advance to next arg
|
||
|
||
while ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
if ( !strcmp(&strArgs[i][0], POTF_PASSTHRU) )
|
||
{
|
||
tmpStorageInfo.guidNegPolAction
|
||
= GUID_NEGOTIATION_ACTION_NO_IPSEC;
|
||
}
|
||
else if ( !strcmp(&strArgs[i][0], POTF_INBOUND_PASSTHRU) )
|
||
{
|
||
tmpStorageInfo.guidNegPolAction =
|
||
GUID_NEGOTIATION_ACTION_INBOUND_PASSTHRU;
|
||
}
|
||
else if ( !strcmp(&strArgs[i][0], POTF_BLOCK) )
|
||
{
|
||
tmpStorageInfo.guidNegPolAction =
|
||
GUID_NEGOTIATION_ACTION_BLOCK;
|
||
}
|
||
else
|
||
{
|
||
dwReturn = TextToOffer(&strArgs[i][0], IpsPol.pOffers[IpsPol.dwOfferCount]);
|
||
|
||
if (!T2P_SUCCESS(dwReturn)) goto error_occured;
|
||
else ++IpsPol.dwOfferCount;
|
||
}
|
||
|
||
++i; // advance to next arg
|
||
}
|
||
}
|
||
else if (strArgs[i][1] == POTF_TUNNEL_FLAG)
|
||
{
|
||
if (strArgs[i][2] != '\0') // no space after flag
|
||
{
|
||
TextToIPAddr(&strArgs[i][2], DesTunnelAddr);
|
||
}
|
||
else
|
||
{
|
||
++i;
|
||
TextToIPAddr(&strArgs[i][0], DesTunnelAddr);
|
||
}
|
||
|
||
++i;
|
||
// now check for second tunnel address
|
||
if (i < uArgCount && strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL)
|
||
{
|
||
// not an option, tunnel address
|
||
SrcTunnelAddr = DesTunnelAddr;
|
||
TextToIPAddr(&strArgs[i][0], DesTunnelAddr);
|
||
++i;
|
||
}
|
||
|
||
}
|
||
else if (strArgs[i][1] == POTF_AUTH_FLAG)
|
||
{
|
||
// first offer is special case because user may
|
||
// omit space after flag
|
||
if ((strArgs[i][2] != '\0')
|
||
&& (strchr(POTF_FLAG_TOKENS, strArgs[i][2]) == NULL))
|
||
{
|
||
dwReturn = TextToOakleyAuth(&strArgs[i][2], AuthInfos.pAuthenticationInfo[AuthInfos.dwNumAuthInfos]);
|
||
if (!T2P_SUCCESS(dwReturn)) break;
|
||
else ++AuthInfos.dwNumAuthInfos;
|
||
}
|
||
else if (strArgs[i][2] != '\0')
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"Unexpected flag: %s. Check usage.\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
break;
|
||
}
|
||
|
||
++i; // advance to next arg
|
||
|
||
while ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
dwReturn = TextToOakleyAuth(&strArgs[i][0], AuthInfos.pAuthenticationInfo[AuthInfos.dwNumAuthInfos]);
|
||
if (!T2P_SUCCESS(dwReturn)) goto error_occured;
|
||
else ++AuthInfos.dwNumAuthInfos;
|
||
|
||
++i; // advance to next arg
|
||
}
|
||
}
|
||
else if (strArgs[i][1] == POTF_STORAGE_FLAG)
|
||
{
|
||
if ((strArgs[i][2] != '\0')
|
||
&& (strchr(POTF_FLAG_TOKENS, strArgs[i][2]) == NULL))
|
||
{
|
||
dwReturn = TextToStorageLocation(&strArgs[i][2], tmpStorageInfo);
|
||
if (!T2P_SUCCESS(dwReturn)) break;
|
||
}
|
||
else if (strArgs[i][2] != '\0')
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"Unexpected flag: %s. Check usage.\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
break;
|
||
}
|
||
else // storage info must be in next param
|
||
{
|
||
++i; // advance to next arg
|
||
if ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
dwReturn = TextToStorageLocation(&strArgs[i][0], tmpStorageInfo);
|
||
if (!T2P_SUCCESS(dwReturn)) goto error_occured;
|
||
|
||
++i; // advance to next arg
|
||
}
|
||
else
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"You must specify storage info: %s. Check usage.\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else if (strArgs[i][1] == POTF_POLNAME_FLAG)
|
||
{
|
||
if ((strArgs[i][2] != '\0')
|
||
&& (strchr(POTF_FLAG_TOKENS, strArgs[i][2]) == NULL))
|
||
{
|
||
dwReturn = TextToPolicyName(&strArgs[i][2], tmpStorageInfo);
|
||
if (!T2P_SUCCESS(dwReturn)) break;
|
||
}
|
||
else if (strArgs[i][2] != '\0')
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"Unexpected flag: %s. Check usage.\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
break;
|
||
}
|
||
else // policy name must be in next param
|
||
{
|
||
++i; // advance to next arg
|
||
if ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
dwReturn = TextToPolicyName(&strArgs[i][0], tmpStorageInfo);
|
||
if (!T2P_SUCCESS(dwReturn)) goto error_occured;
|
||
|
||
++i; // advance to next arg
|
||
}
|
||
else
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"You must specify policy name: %s. Check usage.\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else if (strArgs[i][1] == POTF_RULENAME_FLAG)
|
||
{
|
||
// first offer is special case because user may
|
||
// omit space after flag
|
||
if ((strArgs[i][2] != '\0')
|
||
&& (strchr(POTF_FLAG_TOKENS, strArgs[i][2]) == NULL))
|
||
{
|
||
_stprintf(tmpStorageInfo.szRuleName, TEXT("%S"), &strArgs[i][2]);
|
||
}
|
||
else if (strArgs[i][2] != '\0')
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"Unexpected flag: %s. Check usage.\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
break;
|
||
}
|
||
else // policy name must be in next param
|
||
{
|
||
++i; // advance to next arg
|
||
if ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
_stprintf(tmpStorageInfo.szRuleName, TEXT("%S"), &strArgs[i][0]);
|
||
|
||
++i; // advance to next arg
|
||
}
|
||
else
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"You must specify rule name: %s. Check usage.\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else if (strArgs[i][1] == POTF_SETACTIVE_FLAG)
|
||
{
|
||
tmpStorageInfo.bSetActive = TRUE;
|
||
++i;
|
||
}
|
||
else if (strArgs[i][1] == POTF_SETINACTIVE_FLAG)
|
||
{
|
||
tmpStorageInfo.bSetInActive = TRUE;
|
||
++i;
|
||
}
|
||
else if (strArgs[i][1] == POTF_CONFIRM_FLAG)
|
||
{
|
||
bConfirm = true;
|
||
++i;
|
||
}
|
||
else if (strArgs[i][1] == POTF_DELETEPOLICY_FLAG)
|
||
{
|
||
tmpStorageInfo.bDeletePolicy = true;
|
||
++i;
|
||
}
|
||
else if ( strncmp(&strArgs[i][1], POTF_DIALUP_FLAG,
|
||
strlen(POTF_DIALUP_FLAG)) == 0 )
|
||
{
|
||
Interface = INTERFACE_TYPE_DIALUP;
|
||
++i;
|
||
}
|
||
else if (strArgs[i][1] == POTF_DEACTIVATE_FLAG)
|
||
{
|
||
// deactivate local registry policy right here
|
||
// this is left for backward compatibility with old text2pol
|
||
// directory policy assignment left intact
|
||
|
||
HANDLE hRegPolicyStore = NULL;
|
||
PIPSEC_POLICY_DATA pipspd = NULL;
|
||
DWORD dwRes = ERROR_SUCCESS;
|
||
|
||
dwRes = IPSecOpenPolicyStore(NULL, IPSEC_REGISTRY_PROVIDER, NULL, &hRegPolicyStore);
|
||
if (dwRes == ERROR_SUCCESS && hRegPolicyStore != NULL)
|
||
{
|
||
dwRes = IPSecGetAssignedPolicyData(hRegPolicyStore, &pipspd);
|
||
if (dwRes == ERROR_SUCCESS && pipspd != NULL)
|
||
{
|
||
dwRes = IPSecUnassignPolicy(hRegPolicyStore, pipspd[0].PolicyIdentifier);
|
||
IPSecFreePolicyData(pipspd);
|
||
}
|
||
|
||
IPSecClosePolicyStore(hRegPolicyStore);
|
||
}
|
||
|
||
if (dwRes != ERROR_SUCCESS)
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"Polstore operation returned 0x%x!\n", dwRes);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
break;
|
||
}
|
||
|
||
++i;
|
||
}
|
||
else if ( strncmp(&strArgs[i][1], POTF_MMFILTER_FLAG,
|
||
strlen(POTF_MMFILTER_FLAG)) == 0 )
|
||
{
|
||
// first filter is special case because user may
|
||
// omit space after flag
|
||
if ((strArgs[i][3] != '\0')
|
||
&& (strchr(POTF_FLAG_TOKENS, strArgs[i][3]) == NULL))
|
||
{
|
||
dwReturn = TextToMMFilter(&strArgs[i][3], pMMFilters[dwNumMMFilters]);
|
||
|
||
if (!T2P_SUCCESS(dwReturn))
|
||
break;
|
||
else
|
||
{
|
||
++dwNumMMFilters;
|
||
}
|
||
}
|
||
else if (strArgs[i][3] != '\0')
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"Unexpected flag: %s. Check usage.\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
break;
|
||
}
|
||
|
||
++i; // advance to next arg
|
||
|
||
while ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
dwReturn = TextToMMFilter(&strArgs[i][0], pMMFilters[dwNumMMFilters]);
|
||
|
||
if (!T2P_SUCCESS(dwReturn))
|
||
break;
|
||
else
|
||
{
|
||
++dwNumMMFilters;
|
||
}
|
||
|
||
++i; // advance to next arg
|
||
}
|
||
}
|
||
else if ( strncmp(&strArgs[i][1], POTF_SECMETHOD_FLAG,
|
||
strlen(POTF_SECMETHOD_FLAG)) == 0 )
|
||
{
|
||
// first method is special case because user may
|
||
// omit space after flag
|
||
if ((strArgs[i][3] != '\0')
|
||
&& (strchr(POTF_FLAG_TOKENS, strArgs[i][3]) == NULL))
|
||
{
|
||
dwReturn = TextToSecMethod(&strArgs[i][3], IkePol.pOffers[IkePol.dwOfferCount]);
|
||
if (!T2P_SUCCESS(dwReturn)) break;
|
||
else ++IkePol.dwOfferCount;
|
||
}
|
||
else if (strArgs[i][3] != '\0')
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"Unexpected flag: %s. Check usage.\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = false;
|
||
break;
|
||
}
|
||
|
||
++i; // advance to next arg
|
||
|
||
while ( (i < uArgCount) && (strchr(POTF_FLAG_TOKENS, strArgs[i][0]) == NULL) )
|
||
{
|
||
dwReturn = TextToSecMethod(&strArgs[i][0], IkePol.pOffers[IkePol.dwOfferCount]);
|
||
if (!T2P_SUCCESS(dwReturn)) goto error_occured;
|
||
else ++IkePol.dwOfferCount;
|
||
|
||
++i; // advance to next arg
|
||
}
|
||
}
|
||
else if ( strncmp(&strArgs[i][1], POTF_P1PFS_FLAG,
|
||
strlen(POTF_P1PFS_FLAG)) == 0 )
|
||
{
|
||
QMLimit = 1;
|
||
bP1RekeyUsed = true; // will fixup all the P1 offers later
|
||
++i;
|
||
}
|
||
else if ( strncmp(&strArgs[i][1], POTF_SOFTSA_FLAG,
|
||
strlen(POTF_SOFTSA_FLAG)) == 0 )
|
||
{
|
||
IpsPol.dwFlags |= IPSEC_QM_POLICY_ALLOW_SOFT;
|
||
if (!IkePol.uSoftSAExpirationTime)
|
||
{
|
||
// set this time to default
|
||
IkePol.uSoftSAExpirationTime = POTF_DEF_P1SOFT_TIME;
|
||
}
|
||
++i;
|
||
}
|
||
else if ( strncmp(&strArgs[i][1], POTF_LAN_FLAG,
|
||
strlen(POTF_LAN_FLAG)) == 0 )
|
||
{
|
||
Interface = INTERFACE_TYPE_LAN;
|
||
++i;
|
||
}
|
||
else if ( strncmp(&strArgs[i][1], POTF_SOFTSAEXP_FLAG,
|
||
strlen(POTF_SOFTSAEXP_FLAG)) == 0 )
|
||
{
|
||
if (strArgs[i][3] != '\0')
|
||
{
|
||
// they may have omitted a space
|
||
IkePol.uSoftSAExpirationTime = atol(&strArgs[i][3]);
|
||
++i;
|
||
}
|
||
else
|
||
{
|
||
++i;
|
||
// process next arg
|
||
IkePol.uSoftSAExpirationTime = atol(&strArgs[i][0]);
|
||
++i;
|
||
}
|
||
}
|
||
else if ( strncmp(&strArgs[i][1], POTF_P1REKEY_FLAG,
|
||
strlen(POTF_P1REKEY_FLAG)) == 0 )
|
||
{
|
||
// special case because user may
|
||
// omit space after flag
|
||
if (strArgs[i][3] != '\0')
|
||
{
|
||
dwReturn = TextToP1Rekey(&strArgs[i][3], OakLife, QMLimit);
|
||
if (!T2P_SUCCESS(dwReturn)) break;
|
||
|
||
++i; // advance to next arg
|
||
}
|
||
else
|
||
{
|
||
++i; // advance to next arg
|
||
dwReturn = TextToP1Rekey(&strArgs[i][0], OakLife, QMLimit);
|
||
if (!T2P_SUCCESS(dwReturn)) break;
|
||
|
||
++i; // advance to next arg
|
||
}
|
||
|
||
bP1RekeyUsed = true;
|
||
}
|
||
else
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"Unknown flag: %s\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
}
|
||
} // end if flag
|
||
else
|
||
{
|
||
sprintf(STRLASTERR,
|
||
"I don't understand:\n%s\n", strArgs[i]);
|
||
PARSE_ERROR;
|
||
dwReturn = POTF_FAILED;
|
||
}
|
||
} // end main processing loop
|
||
|
||
// now do some post-processing
|
||
// either cleanup for errors or fix up policy
|
||
|
||
if ( bP1RekeyUsed && T2P_SUCCESS(dwReturn) && (IkePol.pOffers == NULL))
|
||
{
|
||
LoadIkeDefaults(IkePol);
|
||
}
|
||
|
||
// filter post-processing
|
||
// apply interface type to transports and interface type + tunnel address to tunnels
|
||
if (QMFilterType == QM_TRANSPORT_FILTER)
|
||
{
|
||
for (i = 0; i < dwNumFilters; i++)
|
||
{
|
||
RPC_STATUS RpcStat = RPC_S_OK;
|
||
pTransportFilters[i].InterfaceType = Interface;
|
||
// apply guidNegPolAction so that PASS INPASS and BLOCK take effect here
|
||
if (UuidCompare(&(tmpStorageInfo.guidNegPolAction), (UUID *) &GUID_NEGOTIATION_ACTION_INBOUND_PASSTHRU, &RpcStat) == 0 && RpcStat == RPC_S_OK)
|
||
{
|
||
pTransportFilters[i].InboundFilterFlag = PASS_THRU;
|
||
pTransportFilters[i].OutboundFilterFlag = NEGOTIATE_SECURITY;
|
||
}
|
||
else if (UuidCompare(&(tmpStorageInfo.guidNegPolAction), (UUID *) &GUID_NEGOTIATION_ACTION_BLOCK, &RpcStat) == 0 && RpcStat == RPC_S_OK)
|
||
{
|
||
pTransportFilters[i].InboundFilterFlag = BLOCKING;
|
||
pTransportFilters[i].OutboundFilterFlag = BLOCKING;
|
||
}
|
||
else if (UuidCompare(&(tmpStorageInfo.guidNegPolAction), (UUID *) &GUID_NEGOTIATION_ACTION_NO_IPSEC, &RpcStat) == 0 && RpcStat == RPC_S_OK)
|
||
{
|
||
pTransportFilters[i].InboundFilterFlag = PASS_THRU;
|
||
pTransportFilters[i].OutboundFilterFlag = PASS_THRU;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// tunnel filter
|
||
for (i = 0; i < dwNumFilters; i++)
|
||
{
|
||
pTunnelFilters[i].InterfaceType = Interface;
|
||
|
||
if (SrcTunnelAddr == 0)
|
||
{
|
||
// SrcTunnelAddr is set to any
|
||
pTunnelFilters[i].SrcTunnelAddr.AddrType = IP_ADDR_SUBNET;
|
||
pTunnelFilters[i].SrcTunnelAddr.uIpAddr = SUBNET_ADDRESS_ANY;
|
||
pTunnelFilters[i].SrcTunnelAddr.uSubNetMask = SUBNET_MASK_ANY;
|
||
}
|
||
else
|
||
{
|
||
pTunnelFilters[i].SrcTunnelAddr.AddrType = IP_ADDR_UNIQUE;
|
||
pTunnelFilters[i].SrcTunnelAddr.uIpAddr = SrcTunnelAddr;
|
||
pTunnelFilters[i].SrcTunnelAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
|
||
}
|
||
|
||
// DesTunnelAddr is our tunnel address
|
||
pTunnelFilters[i].DesTunnelAddr.AddrType = IP_ADDR_UNIQUE;
|
||
pTunnelFilters[i].DesTunnelAddr.uIpAddr = DesTunnelAddr;
|
||
pTunnelFilters[i].DesTunnelAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
|
||
}
|
||
}
|
||
|
||
// if mainmode filters specified, apply interface type
|
||
if (uMMFiltAlloc)
|
||
{
|
||
for (i = 0; i < dwNumMMFilters; i++)
|
||
{
|
||
pMMFilters[i].InterfaceType = Interface;
|
||
}
|
||
}
|
||
|
||
if (!uMMFiltAlloc)
|
||
{
|
||
// generate mainmode filters - filter generation also depends on QMFilterType
|
||
if (QMFilterType == QM_TRANSPORT_FILTER)
|
||
{
|
||
// transport
|
||
Filter.QMFilterType = QM_TRANSPORT_FILTER;
|
||
for (i = 0; i < dwNumFilters; i++)
|
||
{
|
||
bool bSuccess;
|
||
bool bFound;
|
||
int j;
|
||
memcpy(&Filter.TransportFilter, &pTransportFilters[i], sizeof(TRANSPORT_FILTER));
|
||
if (Filter.TransportFilter.OutboundFilterFlag == NEGOTIATE_SECURITY
|
||
|| Filter.TransportFilter.InboundFilterFlag == NEGOTIATE_SECURITY)
|
||
{
|
||
bSuccess = GenerateMMFilter(Filter, pMMFilters[dwNumMMFilters]);
|
||
assert(bSuccess);
|
||
dwNumMMFilters++;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// tunnel - generate just one filter
|
||
bool bSuccess;
|
||
Filter.QMFilterType = QM_TUNNEL_FILTER;
|
||
memcpy(&Filter.TunnelFilter, &pTunnelFilters[0], sizeof(TUNNEL_FILTER));
|
||
bSuccess = GenerateMMFilter(Filter, pMMFilters[0]);
|
||
assert(bSuccess);
|
||
dwNumMMFilters++;
|
||
}
|
||
}
|
||
|
||
error_occured:
|
||
if (!T2P_SUCCESS(dwReturn))
|
||
{
|
||
// error occured, clean up
|
||
if (uFiltAlloc)
|
||
{
|
||
// clean up both transports and tunnels since we allocated both
|
||
|
||
for (i = 0; i <= uFiltAlloc; i++)
|
||
{
|
||
if (pTransportFilters[i].pszFilterName != NULL)
|
||
free(pTransportFilters[i].pszFilterName);
|
||
}
|
||
delete [] pTransportFilters;
|
||
pTransportFilters = NULL;
|
||
|
||
// tunnel filter
|
||
for (i = 0; i <= uFiltAlloc; i++)
|
||
{
|
||
if (pTunnelFilters[i].pszFilterName != NULL)
|
||
free(pTunnelFilters[i].pszFilterName);
|
||
}
|
||
delete [] pTunnelFilters;
|
||
pTunnelFilters = NULL;
|
||
dwNumFilters = 0;
|
||
|
||
if (!uMMFiltAlloc)
|
||
{
|
||
for (i = 0; i <= uMMFiltAlloc; i++)
|
||
{
|
||
if (pMMFilters[i].pszFilterName != NULL)
|
||
free(pMMFilters[i].pszFilterName);
|
||
}
|
||
delete [] pMMFilters;
|
||
pMMFilters = NULL;
|
||
dwNumMMFilters = 0;
|
||
}
|
||
}
|
||
if (uMMFiltAlloc)
|
||
{
|
||
for (i = 0; i <= uMMFiltAlloc; i++)
|
||
{
|
||
if (pMMFilters[i].pszFilterName != NULL)
|
||
free(pMMFilters[i].pszFilterName);
|
||
}
|
||
delete [] pMMFilters;
|
||
pMMFilters = NULL;
|
||
dwNumMMFilters = 0;
|
||
}
|
||
if (uOfferAlloc)
|
||
{
|
||
delete [] IpsPol.pOffers;
|
||
IpsPol.pOffers = NULL;
|
||
IpsPol.dwOfferCount = 0;
|
||
}
|
||
if (uSecMetAlloc)
|
||
{
|
||
delete [] IkePol.pOffers;
|
||
IkePol.pOffers = NULL;
|
||
IkePol.dwOfferCount = 0;
|
||
}
|
||
}
|
||
else // fix up policy as necessary
|
||
{
|
||
//
|
||
// if storage info requested, copy to caller
|
||
// only copy fields that were indicated, this gets
|
||
// passed in with caller specified items
|
||
//
|
||
|
||
if (bStorageMode)
|
||
{
|
||
T2P_FILTER tmpf;
|
||
tmpf.QMFilterType = QMFilterType;
|
||
|
||
tmpStorageInfo.FilterList = new IPSEC_FILTER_SPEC[dwNumFilters];
|
||
assert(tmpStorageInfo.FilterList != NULL);
|
||
|
||
// convert filters
|
||
for (i = 0; i < dwNumFilters; i++)
|
||
{
|
||
if (tmpf.QMFilterType == QM_TRANSPORT_FILTER)
|
||
{
|
||
memcpy(&(tmpf.TransportFilter), &(pTransportFilters[i]), sizeof(TRANSPORT_FILTER));
|
||
}
|
||
else
|
||
{
|
||
// tunnel
|
||
memcpy(&(tmpf.TunnelFilter), &(pTunnelFilters[i]), sizeof(TUNNEL_FILTER));
|
||
}
|
||
ConvertFilter(tmpf, tmpStorageInfo.FilterList[i]);
|
||
}
|
||
|
||
pStorageInfo->Type = tmpStorageInfo.Type;
|
||
|
||
if (tmpStorageInfo.szLocationName[0] != '\0')
|
||
wcscpy(pStorageInfo->szLocationName, tmpStorageInfo.szLocationName);
|
||
if (tmpStorageInfo.szPolicyName[0] != '\0')
|
||
wcscpy(pStorageInfo->szPolicyName, tmpStorageInfo.szPolicyName);
|
||
if (tmpStorageInfo.szRuleName[0] != '\0')
|
||
wcscpy(pStorageInfo->szRuleName, tmpStorageInfo.szRuleName);
|
||
if (tmpStorageInfo.tPollingInterval)
|
||
pStorageInfo->tPollingInterval = tmpStorageInfo.tPollingInterval;
|
||
|
||
pStorageInfo->guidNegPolAction = tmpStorageInfo.guidNegPolAction;
|
||
pStorageInfo->bSetActive = tmpStorageInfo.bSetActive;
|
||
pStorageInfo->bSetInActive = tmpStorageInfo.bSetInActive;
|
||
pStorageInfo->bDeleteRule = tmpStorageInfo.bDeleteRule;
|
||
pStorageInfo->bDeletePolicy = tmpStorageInfo.bDeletePolicy;
|
||
pStorageInfo->FilterList = tmpStorageInfo.FilterList;
|
||
pStorageInfo->uNumFilters = tmpStorageInfo.uNumFilters;
|
||
|
||
}
|
||
|
||
// fix up MM policy
|
||
if (bP1RekeyUsed)
|
||
{
|
||
// fix up Ike policy by filling each ike offer
|
||
// with the phase1 rekey
|
||
for (i = 0; i < IkePol.dwOfferCount; ++i)
|
||
{
|
||
IkePol.pOffers[i].Lifetime.uKeyExpirationKBytes = OakLife.uKeyExpirationKBytes;
|
||
IkePol.pOffers[i].Lifetime.uKeyExpirationTime = OakLife.uKeyExpirationTime;
|
||
IkePol.pOffers[i].dwQuickModeLimit = QMLimit;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
// load defaults
|
||
for (i = 0; i < IkePol.dwOfferCount; ++i)
|
||
{
|
||
IkePol.pOffers[i].Lifetime.uKeyExpirationKBytes = 0; // not used
|
||
IkePol.pOffers[i].Lifetime.uKeyExpirationTime = POTF_DEFAULT_P1REKEY_TIME;
|
||
IkePol.pOffers[i].dwQuickModeLimit = POTF_DEFAULT_P1REKEY_QMS;
|
||
}
|
||
}
|
||
|
||
// if Kerberos is used, need to set AuthInfo string
|
||
// to dummy since RPC will choke otherwise
|
||
for (i = 0; i < AuthInfos.dwNumAuthInfos; ++i)
|
||
{
|
||
if (AuthInfos.pAuthenticationInfo[i].AuthMethod == IKE_SSPI ||
|
||
(AuthInfos.pAuthenticationInfo[i].AuthMethod == IKE_RSA_SIGNATURE &&
|
||
AuthInfos.pAuthenticationInfo[i].pAuthInfo == NULL)
|
||
)
|
||
{
|
||
AuthInfos.pAuthenticationInfo[i].dwAuthInfoSize = 0;
|
||
AuthInfos.pAuthenticationInfo[i].pAuthInfo = (LPBYTE) new wchar_t[1];
|
||
AuthInfos.pAuthenticationInfo[i].pAuthInfo[0] = UNICODE_NULL;
|
||
}
|
||
}
|
||
}
|
||
} // end if args valid
|
||
else
|
||
{
|
||
fprintf(stderr, "Fatal error occured processing cmd line at line %d\n",
|
||
__LINE__ );
|
||
dwReturn = POTF_FAILED;
|
||
}
|
||
|
||
//
|
||
// OK, copy the info to the caller
|
||
//
|
||
|
||
memcpy(&IpsecIkePol.IpsPol, &IpsPol, sizeof(IpsPol));
|
||
memcpy(&IpsecIkePol.IkePol, &IkePol, sizeof(IkePol));
|
||
memcpy(&IpsecIkePol.AuthInfos, &AuthInfos, sizeof(AuthInfos));
|
||
|
||
IpsecIkePol.pMMFilters = pMMFilters;
|
||
IpsecIkePol.dwNumMMFilters = dwNumMMFilters;
|
||
IpsecIkePol.QMFilterType = QMFilterType;
|
||
IpsecIkePol.dwNumFilters = dwNumFilters;
|
||
IpsecIkePol.pTransportFilters = pTransportFilters;
|
||
IpsecIkePol.pTunnelFilters = pTunnelFilters;
|
||
|
||
// done
|
||
|
||
return dwReturn;
|
||
|
||
}
|
||
|
||
|