405 lines
14 KiB
C++
405 lines
14 KiB
C++
/////////////////////////////////////////////////////////////
|
|
// Copyright(c) 2001, Microsoft Corporation
|
|
//
|
|
// spdutil.cpp
|
|
//
|
|
// Created on 3/27/01 by DKalin
|
|
// Revisions:
|
|
// File created 3/27/01 DKalin
|
|
//
|
|
// Implementation for the auxiliary functions for text to policy conversion routines
|
|
//
|
|
// Separated from generic routines in text2pol.cpp and text2spd.cpp
|
|
//
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
#include "ipseccmd.h"
|
|
|
|
int isdnsname(char *szStr)
|
|
{
|
|
// if there is an alpha character in the string,
|
|
// then we consider a DNS name
|
|
if ( szStr )
|
|
{
|
|
for (UINT i = 0; i < strlen(szStr); ++i)
|
|
{
|
|
if ( isalpha(szStr[i]) )
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// takes inFilter and reflects it to outFilter
|
|
// creates GUID and name for outFilter
|
|
bool MirrorFilter(IN T2P_FILTER inFilter, OUT T2P_FILTER & outFilter)
|
|
{
|
|
bool bReturn = true;
|
|
|
|
memset(&outFilter, 0, sizeof(T2P_FILTER));
|
|
outFilter.QMFilterType = inFilter.QMFilterType;
|
|
|
|
if (inFilter.QMFilterType != QM_TUNNEL_FILTER)
|
|
{
|
|
// process transport
|
|
// GUID first
|
|
RPC_STATUS RpcStat = UuidCreate(&outFilter.TransportFilter.gFilterID);
|
|
if (RpcStat != RPC_S_OK && RpcStat != RPC_S_UUID_LOCAL_ONLY)
|
|
{
|
|
sprintf(STRLASTERR, "Couldn't get GUID for mirror filter - UuidCreate failed with status: %ul\n",
|
|
RpcStat);
|
|
WARN;
|
|
bReturn = false;
|
|
}
|
|
if (bReturn)
|
|
{
|
|
// now name, add " - Mirror"
|
|
WCHAR wszMirrorSuffix[] = L" - Mirror";
|
|
int iNameLen = 0;
|
|
if (inFilter.TransportFilter.pszFilterName != NULL)
|
|
{
|
|
iNameLen = wcslen(inFilter.TransportFilter.pszFilterName);
|
|
}
|
|
WCHAR* pwszTmp = new WCHAR[iNameLen+wcslen(wszMirrorSuffix)+1];
|
|
assert(pwszTmp != NULL);
|
|
|
|
wcscpy(pwszTmp, inFilter.TransportFilter.pszFilterName);
|
|
wcscat(pwszTmp, wszMirrorSuffix);
|
|
outFilter.TransportFilter.pszFilterName = pwszTmp;
|
|
}
|
|
|
|
// direction
|
|
outFilter.TransportFilter.dwDirection = inFilter.TransportFilter.dwDirection;
|
|
if (inFilter.TransportFilter.dwDirection == FILTER_DIRECTION_INBOUND)
|
|
{
|
|
outFilter.TransportFilter.dwDirection = FILTER_DIRECTION_OUTBOUND;
|
|
}
|
|
if (inFilter.TransportFilter.dwDirection == FILTER_DIRECTION_OUTBOUND)
|
|
{
|
|
outFilter.TransportFilter.dwDirection = FILTER_DIRECTION_INBOUND;
|
|
}
|
|
|
|
// straight copy stuff
|
|
outFilter.TransportFilter.InterfaceType = inFilter.TransportFilter.InterfaceType;
|
|
outFilter.TransportFilter.bCreateMirror = inFilter.TransportFilter.bCreateMirror;
|
|
outFilter.TransportFilter.dwFlags = inFilter.TransportFilter.dwFlags;
|
|
outFilter.TransportFilter.Protocol = inFilter.TransportFilter.Protocol;
|
|
outFilter.TransportFilter.dwWeight = inFilter.TransportFilter.dwWeight;
|
|
outFilter.TransportFilter.gPolicyID = inFilter.TransportFilter.gPolicyID;
|
|
|
|
// the reflected stuff
|
|
outFilter.TransportFilter.SrcAddr = inFilter.TransportFilter.DesAddr;
|
|
outFilter.TransportFilter.DesAddr = inFilter.TransportFilter.SrcAddr;
|
|
outFilter.TransportFilter.SrcPort = inFilter.TransportFilter.DesPort;
|
|
outFilter.TransportFilter.DesPort = inFilter.TransportFilter.SrcPort;
|
|
outFilter.TransportFilter.InboundFilterFlag = inFilter.TransportFilter.OutboundFilterFlag;
|
|
outFilter.TransportFilter.OutboundFilterFlag = inFilter.TransportFilter.InboundFilterFlag;
|
|
}
|
|
else
|
|
{
|
|
// GUID first
|
|
RPC_STATUS RpcStat = UuidCreate(&outFilter.TunnelFilter.gFilterID);
|
|
if (RpcStat != RPC_S_OK && RpcStat != RPC_S_UUID_LOCAL_ONLY)
|
|
{
|
|
sprintf(STRLASTERR, "Couldn't get GUID for mirror filter - UuidCreate failed with status: %ul\n",
|
|
RpcStat);
|
|
WARN;
|
|
bReturn = false;
|
|
}
|
|
if (bReturn)
|
|
{
|
|
// now name, add " - Mirror"
|
|
WCHAR wszMirrorSuffix[] = L" - Mirror";
|
|
int iNameLen = 0;
|
|
if (inFilter.TunnelFilter.pszFilterName != NULL)
|
|
{
|
|
iNameLen = wcslen(inFilter.TunnelFilter.pszFilterName);
|
|
}
|
|
WCHAR* pwszTmp = new WCHAR[iNameLen+wcslen(wszMirrorSuffix)+1];
|
|
assert(pwszTmp != NULL);
|
|
|
|
wcscpy(pwszTmp, inFilter.TunnelFilter.pszFilterName);
|
|
wcscat(pwszTmp, wszMirrorSuffix);
|
|
outFilter.TunnelFilter.pszFilterName = pwszTmp;
|
|
}
|
|
|
|
// direction
|
|
outFilter.TunnelFilter.dwDirection = inFilter.TunnelFilter.dwDirection;
|
|
if (inFilter.TunnelFilter.dwDirection == FILTER_DIRECTION_INBOUND)
|
|
{
|
|
outFilter.TunnelFilter.dwDirection = FILTER_DIRECTION_OUTBOUND;
|
|
}
|
|
if (inFilter.TunnelFilter.dwDirection == FILTER_DIRECTION_OUTBOUND)
|
|
{
|
|
outFilter.TunnelFilter.dwDirection = FILTER_DIRECTION_INBOUND;
|
|
}
|
|
|
|
// straight copy stuff
|
|
outFilter.TunnelFilter.InterfaceType = inFilter.TunnelFilter.InterfaceType;
|
|
outFilter.TunnelFilter.bCreateMirror = inFilter.TunnelFilter.bCreateMirror;
|
|
outFilter.TunnelFilter.dwFlags = inFilter.TunnelFilter.dwFlags;
|
|
outFilter.TunnelFilter.Protocol = inFilter.TunnelFilter.Protocol;
|
|
outFilter.TunnelFilter.dwWeight = inFilter.TunnelFilter.dwWeight;
|
|
outFilter.TunnelFilter.gPolicyID = inFilter.TunnelFilter.gPolicyID;
|
|
|
|
// the reflected stuff
|
|
outFilter.TunnelFilter.SrcAddr = inFilter.TunnelFilter.DesAddr;
|
|
outFilter.TunnelFilter.DesAddr = inFilter.TunnelFilter.SrcAddr;
|
|
outFilter.TunnelFilter.SrcTunnelAddr = inFilter.TunnelFilter.DesTunnelAddr;
|
|
outFilter.TunnelFilter.DesTunnelAddr = inFilter.TunnelFilter.SrcTunnelAddr;
|
|
outFilter.TunnelFilter.SrcPort = inFilter.TunnelFilter.DesPort;
|
|
outFilter.TunnelFilter.DesPort = inFilter.TunnelFilter.SrcPort;
|
|
outFilter.TunnelFilter.InboundFilterFlag = inFilter.TunnelFilter.OutboundFilterFlag;
|
|
outFilter.TunnelFilter.OutboundFilterFlag = inFilter.TunnelFilter.InboundFilterFlag;
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
void LoadIkeDefaults(OUT IPSEC_MM_POLICY & IkePol)
|
|
{
|
|
IkePol.dwOfferCount = 4;
|
|
IkePol.pOffers = new IPSEC_MM_OFFER[IkePol.dwOfferCount];
|
|
assert(IkePol.pOffers != NULL);
|
|
memset(IkePol.pOffers, 0, sizeof(IPSEC_MM_OFFER) * IkePol.dwOfferCount);
|
|
|
|
// init these
|
|
for (UINT i = 0; i < IkePol.dwOfferCount; ++i)
|
|
{
|
|
IkePol.pOffers[i].dwQuickModeLimit = POTF_DEFAULT_P1REKEY_QMS;
|
|
IkePol.pOffers[i].Lifetime.uKeyExpirationKBytes = 0;
|
|
IkePol.pOffers[i].Lifetime.uKeyExpirationTime = POTF_DEFAULT_P1REKEY_TIME;
|
|
}
|
|
|
|
IkePol.pOffers[0].EncryptionAlgorithm.uAlgoIdentifier = IPSEC_DOI_ESP_3_DES;
|
|
IkePol.pOffers[0].EncryptionAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
|
|
IkePol.pOffers[0].EncryptionAlgorithm.uAlgoRounds = POTF_OAKLEY_ALGOROUNDS;
|
|
|
|
IkePol.pOffers[0].HashingAlgorithm.uAlgoIdentifier = IPSEC_DOI_AH_SHA1;
|
|
IkePol.pOffers[0].HashingAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
|
|
|
|
IkePol.pOffers[0].dwDHGroup = POTF_OAKLEY_GROUP2;
|
|
|
|
IkePol.pOffers[1].EncryptionAlgorithm.uAlgoIdentifier = IPSEC_DOI_ESP_3_DES;
|
|
IkePol.pOffers[1].EncryptionAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
|
|
IkePol.pOffers[1].EncryptionAlgorithm.uAlgoRounds = POTF_OAKLEY_ALGOROUNDS;
|
|
|
|
IkePol.pOffers[1].HashingAlgorithm.uAlgoIdentifier = IPSEC_DOI_AH_MD5;
|
|
IkePol.pOffers[1].HashingAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
|
|
|
|
IkePol.pOffers[1].dwDHGroup = POTF_OAKLEY_GROUP2;
|
|
|
|
IkePol.pOffers[2].EncryptionAlgorithm.uAlgoIdentifier = IPSEC_DOI_ESP_DES;
|
|
IkePol.pOffers[2].HashingAlgorithm.uAlgoIdentifier = IPSEC_DOI_AH_SHA1;
|
|
IkePol.pOffers[2].dwDHGroup = POTF_OAKLEY_GROUP1;
|
|
|
|
IkePol.pOffers[3].EncryptionAlgorithm.uAlgoIdentifier = IPSEC_DOI_ESP_DES;
|
|
IkePol.pOffers[3].EncryptionAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
|
|
IkePol.pOffers[3].EncryptionAlgorithm.uAlgoRounds = POTF_OAKLEY_ALGOROUNDS;
|
|
|
|
IkePol.pOffers[3].HashingAlgorithm.uAlgoIdentifier = IPSEC_DOI_AH_MD5;
|
|
IkePol.pOffers[3].HashingAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
|
|
|
|
IkePol.pOffers[3].dwDHGroup = POTF_OAKLEY_GROUP1;
|
|
|
|
}
|
|
|
|
// Loads the following defaults, in order:
|
|
void LoadOfferDefaults(OUT PIPSEC_QM_OFFER & Offers, OUT DWORD & NumOffers)
|
|
{
|
|
NumOffers = 4;
|
|
|
|
Offers = new IPSEC_QM_OFFER[NumOffers];
|
|
assert(Offers != NULL);
|
|
memset(Offers, 0, sizeof(IPSEC_QM_OFFER) * NumOffers);
|
|
|
|
for (DWORD i = 0; i < NumOffers; ++i)
|
|
{
|
|
Offers[i].Lifetime.uKeyExpirationKBytes = POTF_DEFAULT_P2REKEY_BYTES;
|
|
Offers[i].Lifetime.uKeyExpirationTime = POTF_DEFAULT_P2REKEY_TIME;
|
|
Offers[i].bPFSRequired = FALSE;
|
|
Offers[i].dwPFSGroup = 0;
|
|
Offers[i].dwFlags = 0;
|
|
Offers[i].dwNumAlgos = 1; // we don't do AND proposals
|
|
Offers[i].Algos[0].Operation = ENCRYPTION;
|
|
}
|
|
|
|
Offers[0].Algos[0].uAlgoIdentifier = IPSEC_DOI_ESP_3_DES;
|
|
Offers[0].Algos[0].uSecAlgoIdentifier = HMAC_AH_SHA1;
|
|
|
|
Offers[1].Algos[0].uAlgoIdentifier = IPSEC_DOI_ESP_3_DES;
|
|
Offers[1].Algos[0].uSecAlgoIdentifier = HMAC_AH_MD5;
|
|
|
|
Offers[2].Algos[0].uAlgoIdentifier = IPSEC_DOI_ESP_DES;
|
|
Offers[2].Algos[0].uSecAlgoIdentifier = HMAC_AH_SHA1;
|
|
|
|
Offers[3].Algos[0].uAlgoIdentifier = IPSEC_DOI_ESP_DES;
|
|
Offers[3].Algos[0].uSecAlgoIdentifier = HMAC_AH_MD5;
|
|
}
|
|
|
|
// generate corresponding mainmode filter for inFilter
|
|
// creates name and guid for outFilter
|
|
bool GenerateMMFilter(IN T2P_FILTER inFilter, OUT MM_FILTER &outFilter)
|
|
{
|
|
bool bReturn = true;
|
|
|
|
if (inFilter.QMFilterType == QM_TRANSPORT_FILTER)
|
|
{
|
|
// transport filter
|
|
// GUID first
|
|
RPC_STATUS RpcStat = UuidCreate(&outFilter.gFilterID);
|
|
if (RpcStat != RPC_S_OK && RpcStat != RPC_S_UUID_LOCAL_ONLY)
|
|
{
|
|
sprintf(STRLASTERR, "Couldn't get GUID for MM filter - UuidCreate failed with status: %ul\n",
|
|
RpcStat);
|
|
WARN;
|
|
bReturn = false;
|
|
}
|
|
if (bReturn)
|
|
{
|
|
// set the name to be equal to the "text2pol " + GUID
|
|
WCHAR StringTxt[POTF_MAX_STRLEN];
|
|
int iReturn;
|
|
|
|
wcscpy(StringTxt, L"text2pol ");
|
|
iReturn = StringFromGUID2(outFilter.gFilterID, StringTxt+wcslen(StringTxt), POTF_MAX_STRLEN-wcslen(StringTxt));
|
|
assert(iReturn != 0);
|
|
outFilter.pszFilterName = new WCHAR[wcslen(StringTxt)+1];
|
|
assert(outFilter.pszFilterName != NULL);
|
|
wcscpy(outFilter.pszFilterName, StringTxt);
|
|
}
|
|
|
|
outFilter.InterfaceType = inFilter.TransportFilter.InterfaceType;
|
|
outFilter.bCreateMirror = inFilter.TransportFilter.bCreateMirror;
|
|
outFilter.dwFlags = 0; // by default, set to none
|
|
outFilter.SrcAddr = inFilter.TransportFilter.SrcAddr;
|
|
outFilter.DesAddr = inFilter.TransportFilter.DesAddr;
|
|
outFilter.dwDirection = inFilter.TransportFilter.dwDirection;
|
|
outFilter.dwWeight = inFilter.TransportFilter.dwWeight;
|
|
}
|
|
else
|
|
{
|
|
// tunnel filter
|
|
// GUID first
|
|
RPC_STATUS RpcStat = UuidCreate(&outFilter.gFilterID);
|
|
if (RpcStat != RPC_S_OK && RpcStat != RPC_S_UUID_LOCAL_ONLY)
|
|
{
|
|
sprintf(STRLASTERR, "Couldn't get GUID for mirror filter - UuidCreate failed with status: %ul\n",
|
|
RpcStat);
|
|
WARN;
|
|
bReturn = false;
|
|
}
|
|
if (bReturn)
|
|
{
|
|
// set the name to be equal to the "text2pol " + GUID
|
|
WCHAR StringTxt[POTF_MAX_STRLEN];
|
|
int iReturn;
|
|
|
|
wcscpy(StringTxt, L"text2pol ");
|
|
iReturn = StringFromGUID2(outFilter.gFilterID, StringTxt+wcslen(StringTxt), POTF_MAX_STRLEN-wcslen(StringTxt));
|
|
assert(iReturn != 0);
|
|
outFilter.pszFilterName = new WCHAR[wcslen(StringTxt)+1];
|
|
assert(outFilter.pszFilterName != NULL);
|
|
wcscpy(outFilter.pszFilterName, StringTxt);
|
|
}
|
|
|
|
outFilter.InterfaceType = inFilter.TunnelFilter.InterfaceType;
|
|
outFilter.bCreateMirror = TRUE;
|
|
outFilter.dwFlags = 0; // by default, set to none
|
|
outFilter.SrcAddr.AddrType = IP_ADDR_UNIQUE;
|
|
outFilter.SrcAddr.uIpAddr = IP_ADDRESS_ME;
|
|
outFilter.SrcAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
|
|
UuidCreateNil(&(outFilter.SrcAddr.gInterfaceID));
|
|
outFilter.DesAddr = inFilter.TunnelFilter.DesTunnelAddr;
|
|
outFilter.dwDirection = inFilter.TunnelFilter.dwDirection;
|
|
outFilter.dwWeight = inFilter.TunnelFilter.dwWeight;
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
DWORD CM_EncodeName ( LPTSTR pszSubjectName, BYTE **EncodedName, DWORD *EncodedNameLength )
|
|
{
|
|
|
|
*EncodedNameLength=0;
|
|
|
|
|
|
if (!CertStrToName(
|
|
X509_ASN_ENCODING,
|
|
pszSubjectName,
|
|
CERT_X500_NAME_STR,
|
|
NULL,
|
|
NULL,
|
|
EncodedNameLength,
|
|
NULL)) {
|
|
|
|
// DebugPrint1(L"Error in CertStrToName %d",GetLastError());
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
|
|
(*EncodedName)= new BYTE[*EncodedNameLength];
|
|
assert (*EncodedName);
|
|
|
|
if (!CertStrToName(
|
|
X509_ASN_ENCODING,
|
|
pszSubjectName,
|
|
CERT_X500_NAME_STR,
|
|
NULL,
|
|
(*EncodedName),
|
|
EncodedNameLength,
|
|
NULL)) {
|
|
|
|
delete (*EncodedName);
|
|
(*EncodedName) = 0;
|
|
// DebugPrint1(L"Error in CertStrToName %d",GetLastError());
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
DWORD CM_DecodeName ( BYTE *EncodedName, DWORD EncodedNameLength, LPTSTR *ppszSubjectName )
|
|
{
|
|
|
|
DWORD DecodedNameLength=0;
|
|
CERT_NAME_BLOB CertName;
|
|
|
|
CertName.cbData = EncodedNameLength;
|
|
CertName.pbData = EncodedName;
|
|
|
|
|
|
DecodedNameLength = CertNameToStr(
|
|
X509_ASN_ENCODING,
|
|
&CertName,
|
|
CERT_X500_NAME_STR,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (!DecodedNameLength)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
|
|
(*ppszSubjectName)= new TCHAR[DecodedNameLength];
|
|
assert (*ppszSubjectName);
|
|
|
|
DecodedNameLength = CertNameToStr(
|
|
X509_ASN_ENCODING,
|
|
&CertName,
|
|
CERT_X500_NAME_STR,
|
|
*ppszSubjectName,
|
|
DecodedNameLength);
|
|
|
|
if (!DecodedNameLength)
|
|
{
|
|
delete (*ppszSubjectName);
|
|
(*ppszSubjectName) = 0;
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|