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.
406 lines
10 KiB
406 lines
10 KiB
// Copyright (c) 1997, Microsoft Corporation, all rights reserved
|
|
//
|
|
// eapcfg.c
|
|
// EAP package utility library
|
|
//
|
|
// These utility routines wrap the third-party EAP authentication
|
|
// configuration information written to the registry by third-party EAP
|
|
// security package providers.
|
|
//
|
|
// 11/25/97 Steve Cobb
|
|
//
|
|
|
|
|
|
#include <windows.h>
|
|
#include <stdlib.h>
|
|
#include <debug.h>
|
|
#include <nouiutil.h>
|
|
#include <raseapif.h>
|
|
#include <ole2.h>
|
|
|
|
// EAP configuration registry definitions.
|
|
//
|
|
#define REGKEY_Eap TEXT("System\\CurrentControlSet\\Services\\Rasman\\PPP\\EAP")
|
|
#define REGVAL_szFriendlyName TEXT("FriendlyName")
|
|
#define REGVAL_szConfigDll TEXT("ConfigUIPath")
|
|
#define REGVAL_szIdentityDll TEXT("IdentityPath")
|
|
#define REGVAL_fRequirePwd TEXT("InvokePasswordDialog")
|
|
#define REGVAL_fRequireUser TEXT("InvokeUsernameDialog")
|
|
#define REGVAL_pData TEXT("ConfigData")
|
|
#define REGVAL_fForceConfig TEXT("RequireConfigUI")
|
|
#define REGVAL_fMppeSupported TEXT("MPPEEncryptionSupported")
|
|
//
|
|
// HACKY Key not to display PEAP and Eapmschapv2 type in here
|
|
//
|
|
#define REGVAL_fHidePEAPMSChapv2 TEXT("HidePEAPMSChapv2")
|
|
#define EAPTYPE_PEAP "25"
|
|
#define EAPTYPE_EAPMSCHAPv2 "26"
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// EAP configuration utilitiy routines (alphabetically)
|
|
//-----------------------------------------------------------------------------
|
|
|
|
DTLNODE*
|
|
CreateEapcfgNode(
|
|
void )
|
|
|
|
// Returns a created, empty EAPCFG descriptor node, or NULL on error.
|
|
//
|
|
{
|
|
DTLNODE* pNode;
|
|
EAPCFG* pEapcfg;
|
|
|
|
pNode = DtlCreateSizedNode( sizeof(EAPCFG), 0L );
|
|
if (pNode)
|
|
{
|
|
pEapcfg = (EAPCFG* )DtlGetData( pNode );
|
|
ASSERT( pEapcfg );
|
|
|
|
pEapcfg->dwKey = (DWORD )-1;
|
|
pEapcfg->pszConfigDll = NULL;
|
|
pEapcfg->pszIdentityDll = NULL;
|
|
pEapcfg->dwStdCredentialFlags = 0;
|
|
pEapcfg->fProvidesMppeKeys = FALSE;
|
|
pEapcfg->fForceConfig = FALSE;
|
|
pEapcfg->pData = NULL;
|
|
pEapcfg->cbData = 0;
|
|
pEapcfg->fConfigDllCalled = FALSE;
|
|
}
|
|
|
|
return pNode;
|
|
}
|
|
|
|
|
|
VOID
|
|
DestroyEapcfgNode(
|
|
IN OUT DTLNODE* pNode )
|
|
|
|
// Release resources associated with EAPCFG node 'pNode'. See
|
|
// DtlDestroyList.
|
|
//
|
|
{
|
|
EAPCFG* pEapcfg;
|
|
|
|
ASSERT( pNode );
|
|
pEapcfg = (EAPCFG* )DtlGetData( pNode );
|
|
ASSERT( pEapcfg );
|
|
|
|
Free0( pEapcfg->pszConfigDll );
|
|
Free0( pEapcfg->pszIdentityDll );
|
|
Free0( pEapcfg->pData );
|
|
|
|
DtlDestroyNode( pNode );
|
|
}
|
|
|
|
|
|
DTLNODE*
|
|
EapcfgNodeFromKey(
|
|
IN DTLLIST* pList,
|
|
IN DWORD dwKey )
|
|
|
|
// Returns the EAPCFG node in list 'pList' with EAP key value of 'dwKey'
|
|
// or NULL if not found.
|
|
//
|
|
{
|
|
DTLNODE* pNode;
|
|
|
|
for (pNode = DtlGetFirstNode( pList );
|
|
pNode;
|
|
pNode = DtlGetNextNode( pNode ))
|
|
{
|
|
EAPCFG* pEapcfg = (EAPCFG* )DtlGetData( pNode );
|
|
ASSERT( pEapcfg );
|
|
|
|
if (pEapcfg->dwKey == dwKey)
|
|
{
|
|
return pNode;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Will tell us if there is a need to cripple PEAP
|
|
// - if true is retured, we dont show PEAP and eapmschapv2
|
|
// in the list.
|
|
BOOL
|
|
IsRasDlgPeapCrippled(HKEY hkeyEap)
|
|
{
|
|
BOOL fRetCode = FALSE;
|
|
DWORD dwRetCode = NO_ERROR;
|
|
DWORD dwValue = 0;
|
|
DWORD dwType = 0;
|
|
DWORD cbValueDataSize = sizeof(DWORD);
|
|
|
|
|
|
dwRetCode = RegQueryValueEx(
|
|
hkeyEap,
|
|
REGVAL_fHidePEAPMSChapv2,
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)&dwValue,
|
|
&cbValueDataSize );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
goto LDone;
|
|
}
|
|
|
|
if ( dwValue != 0 )
|
|
{
|
|
fRetCode = TRUE;
|
|
}
|
|
|
|
LDone:
|
|
|
|
return fRetCode;
|
|
|
|
}
|
|
|
|
|
|
DTLLIST*
|
|
ReadEapcfgList(
|
|
IN TCHAR* pszMachine )
|
|
|
|
// Returns the address of a created list of installed custom
|
|
// authentication packages or NULL if none could be read. On success, it
|
|
// is caller's responsibility to eventually call DtlDestroyList on the
|
|
// returned list.
|
|
//
|
|
{
|
|
DWORD dwErr;
|
|
BOOL fOk = FALSE;
|
|
DTLLIST* pList;
|
|
DTLNODE* pNode;
|
|
EAPCFG* pEapcfg;
|
|
HKEY hkeyLM = NULL;
|
|
HKEY hkeyEap = NULL;
|
|
HKEY hkeyPackage = NULL;
|
|
CHAR szEapType[ 11 + 1 ];
|
|
TCHAR* psz;
|
|
DWORD dw;
|
|
DWORD cb;
|
|
INT i;
|
|
TCHAR* szCLSID;
|
|
HRESULT hr;
|
|
BOOL fRasDlgPeapCrippled = FALSE;
|
|
|
|
|
|
pList = DtlCreateList( 0L );
|
|
if (!pList)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Open the EAP key which contains a sub-key for each installed package.
|
|
//
|
|
dwErr = RegConnectRegistry( pszMachine, HKEY_LOCAL_MACHINE, &hkeyLM );
|
|
|
|
if (dwErr != 0 || !hkeyLM)
|
|
{
|
|
return pList;
|
|
}
|
|
|
|
dwErr = RegOpenKeyEx(
|
|
hkeyLM, (LPCTSTR )REGKEY_Eap, 0, KEY_READ, &hkeyEap );
|
|
|
|
RegCloseKey( hkeyLM );
|
|
|
|
if (dwErr != 0)
|
|
{
|
|
return pList;
|
|
}
|
|
|
|
fRasDlgPeapCrippled = IsRasDlgPeapCrippled ( hkeyEap );
|
|
|
|
// Open each sub-key and extract the package definition from it's values.
|
|
// Problems with opening individual sub-keys result in that node only
|
|
// being discarded.
|
|
//
|
|
for (i = 0; TRUE; ++i)
|
|
{
|
|
cb = sizeof(szEapType);
|
|
dwErr = RegEnumKeyExA(
|
|
hkeyEap, i, szEapType, &cb, NULL, NULL, NULL, NULL );
|
|
if (dwErr != 0)
|
|
{
|
|
// Includes "out of items", the normal loop termination.
|
|
//
|
|
break;
|
|
}
|
|
|
|
dwErr = RegOpenKeyExA(
|
|
hkeyEap, szEapType, 0, KEY_READ, &hkeyPackage );
|
|
if (dwErr != 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// For whistler bug 442519 and 442458 gangz
|
|
// For LEAP, a RolesSupported DWORD will be added, if it is set to 2,
|
|
// then we wont show it on the client side
|
|
{
|
|
DWORD dwRolesSupported = 0;
|
|
|
|
GetRegDword( hkeyPackage,
|
|
RAS_EAP_VALUENAME_ROLES_SUPPORTED,
|
|
&dwRolesSupported);
|
|
|
|
// This values is not configured, or equals 0 or 1, then go ahead
|
|
// and show it, or else wont show it
|
|
// 0 means can be either Authenticator or Authenticatee
|
|
// 1 means can ONLY be Authenticator, for LEAP, it is 1
|
|
// 2 means can ONLY be Authenticatee
|
|
if ( 0 != dwRolesSupported )
|
|
{
|
|
if ( !(RAS_EAP_ROLE_AUTHENTICATEE & dwRolesSupported ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( RAS_EAP_ROLE_EXCLUDE_IN_EAP & dwRolesSupported )
|
|
{
|
|
continue;
|
|
}
|
|
if ( RAS_EAP_ROLE_EXCLUDE_IN_VPN & dwRolesSupported )
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
do
|
|
{
|
|
pNode = CreateEapcfgNode();
|
|
if (!pNode)
|
|
{
|
|
break;
|
|
}
|
|
|
|
pEapcfg = (EAPCFG* )DtlGetData( pNode );
|
|
ASSERT( pEapcfg );
|
|
|
|
// EAP type ID.
|
|
//
|
|
pEapcfg->dwKey = (LONG )atol( szEapType );
|
|
|
|
// Friendly display name.
|
|
//
|
|
psz = NULL;
|
|
dwErr = GetRegSz( hkeyPackage, REGVAL_szFriendlyName, &psz );
|
|
if (dwErr != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (!*psz)
|
|
{
|
|
Free( psz );
|
|
psz = StrDupTFromA( szEapType );
|
|
if (!psz)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
pEapcfg->pszFriendlyName = psz;
|
|
|
|
// Configuration DLL path.
|
|
//
|
|
psz = NULL;
|
|
dwErr = GetRegExpandSz( hkeyPackage, REGVAL_szConfigDll, &psz );
|
|
if (dwErr != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (*psz)
|
|
{
|
|
pEapcfg->pszConfigDll = psz;
|
|
}
|
|
else
|
|
{
|
|
Free( psz );
|
|
}
|
|
|
|
// Identity DLL path.
|
|
//
|
|
psz = NULL;
|
|
dwErr = GetRegExpandSz( hkeyPackage, REGVAL_szIdentityDll, &psz );
|
|
if (dwErr != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (*psz)
|
|
{
|
|
pEapcfg->pszIdentityDll = psz;
|
|
}
|
|
else
|
|
{
|
|
Free( psz );
|
|
}
|
|
|
|
// Prompt user name
|
|
//
|
|
dw = 1;
|
|
GetRegDword( hkeyPackage, REGVAL_fRequireUser, &dw );
|
|
if (dw)
|
|
pEapcfg->dwStdCredentialFlags |= EAPCFG_FLAG_RequireUsername;
|
|
|
|
// Prompt password
|
|
//
|
|
dw = 0;
|
|
GetRegDword( hkeyPackage, REGVAL_fRequirePwd, &dw );
|
|
if (dw)
|
|
pEapcfg->dwStdCredentialFlags |= EAPCFG_FLAG_RequirePassword;
|
|
|
|
// MPPE encryption keys flag.
|
|
//
|
|
dw = 0;
|
|
GetRegDword( hkeyPackage, REGVAL_fMppeSupported, &dw );
|
|
pEapcfg->fProvidesMppeKeys = !!dw;
|
|
|
|
// Force configuration API to run at least once.
|
|
//
|
|
dw = FALSE;
|
|
GetRegDword( hkeyPackage, REGVAL_fForceConfig, &dw );
|
|
pEapcfg->fForceConfig = !!dw;
|
|
|
|
// Configuration blob.
|
|
//
|
|
GetRegBinary(
|
|
hkeyPackage, REGVAL_pData,
|
|
&pEapcfg->pData, &pEapcfg->cbData );
|
|
|
|
// ConfigCLSID
|
|
//
|
|
dwErr = GetRegSz( hkeyPackage, RAS_EAP_VALUENAME_CONFIG_CLSID,
|
|
&szCLSID );
|
|
if (dwErr != 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Ignore errors. Eg. EAP MD5-Challenge does not have a ConfigCLSID.
|
|
//
|
|
hr = CLSIDFromString( szCLSID, &( pEapcfg->guidConfigCLSID ) );
|
|
Free( szCLSID );
|
|
|
|
// Add the completed node to the list.
|
|
//
|
|
DtlAddNodeLast( pList, pNode );
|
|
fOk = TRUE;
|
|
}
|
|
while (FALSE);
|
|
|
|
if (!fOk && pNode)
|
|
{
|
|
DestroyEapcfgNode( pNode );
|
|
}
|
|
|
|
RegCloseKey( hkeyPackage );
|
|
}
|
|
|
|
RegCloseKey( hkeyEap );
|
|
|
|
return pList;
|
|
}
|