mirror of https://github.com/tongzx/nt5src
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.
1300 lines
42 KiB
1300 lines
42 KiB
/////////////////////////////////////////////////////////////
|
|
// 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;
|
|
|
|
}
|
|
|
|
|