Leaked source code of windows server 2003
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

// 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;
}