|
|
/********************************************************************/ /** Copyright(c) 1985-1997 Microsoft Corporation. **/ /********************************************************************/
//***
//
// Filename: raseap.c
//
// Description: Main module that will do interfacing between the PPP engine
// and the various EAP modules.
//
// History: May 11,1997 NarenG Created original version.
//
#define UNICODE
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntlsa.h>
#include <ntmsv1_0.h>
#include <ntsamp.h>
#include <crypt.h>
#include <windows.h>
#include <lmcons.h>
#include <string.h>
#include <stdlib.h>
#include <rasman.h>
#include <pppcp.h>
#include <mprlog.h>
#include <mprerror.h>
#include <raserror.h>
#include <rtutils.h>
#include <rasauth.h>
#include <raseapif.h>
#define INCL_PWUTIL
#define INCL_HOSTWIRE
#define INCL_RASAUTHATTRIBUTES
#include <ppputil.h>
#include <raseapif.h>
#define RASEAPGLOBALS
#include "raseap.h"
#include "bltincps.h"
//**
//
// Call: LoadEapDlls
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will load all the EAP dlls installed.
//
DWORD LoadEapDlls( VOID ) { HKEY hKeyEap = (HKEY)NULL; LPWSTR pEapDllPath = (LPWSTR)NULL; LPWSTR pEapDllExpandedPath = (LPWSTR)NULL; HKEY hKeyEapDll = (HKEY)NULL; DWORD dwRetCode; DWORD dwNumSubKeys; DWORD dwMaxSubKeySize; DWORD dwNumValues; DWORD cbMaxValNameLen; DWORD cbMaxValueDataSize; DWORD dwKeyIndex; WCHAR wchSubKeyName[200]; HINSTANCE hInstance; FARPROC pRasEapGetInfo; DWORD cbSubKeyName; DWORD dwSecDescLen; DWORD cbSize; DWORD dwType; DWORD dwEapTypeId;
//
// Open the EAP key
//
dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE, RAS_EAP_REGISTRY_LOCATION, 0, KEY_READ, &hKeyEap );
if ( dwRetCode != NO_ERROR ) { EapLogErrorString( ROUTERLOG_CANT_OPEN_PPP_REGKEY,0,NULL, dwRetCode,0);
return( dwRetCode ); }
//
// Find out how many EAP DLLs there are
//
dwRetCode = RegQueryInfoKey( hKeyEap, NULL, NULL, NULL, &dwNumSubKeys, &dwMaxSubKeySize, NULL, &dwNumValues, &cbMaxValNameLen, &cbMaxValueDataSize, NULL, NULL );
if ( dwRetCode != NO_ERROR ) { EapLogErrorString(ROUTERLOG_CANT_OPEN_PPP_REGKEY,0,NULL, dwRetCode,0);
RegCloseKey( hKeyEap );
return( dwRetCode ); }
//
// Allocate space in the table to hold information for each one
//
gblpEapTable=(EAP_INFO*)LocalAlloc(LPTR,sizeof(EAP_INFO)*dwNumSubKeys);
if ( gblpEapTable == NULL ) { RegCloseKey( hKeyEap );
return( GetLastError() ); }
//
// Read the registry to find out the various EAPs to load.
//
for ( dwKeyIndex = 0; dwKeyIndex < dwNumSubKeys; dwKeyIndex++ ) { cbSubKeyName = sizeof( wchSubKeyName ) / sizeof(TCHAR);
dwRetCode = RegEnumKeyEx( hKeyEap, dwKeyIndex, wchSubKeyName, &cbSubKeyName, NULL, NULL, NULL, NULL );
if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) && ( dwRetCode != ERROR_NO_MORE_ITEMS ) ) { EapLogErrorString(ROUTERLOG_CANT_ENUM_REGKEYVALUES,0, NULL,dwRetCode,0); break; } else { if ( dwRetCode == ERROR_NO_MORE_ITEMS ) { dwRetCode = NO_ERROR;
break; } }
dwRetCode = RegOpenKeyEx( hKeyEap, wchSubKeyName, 0, KEY_QUERY_VALUE, &hKeyEapDll );
if ( dwRetCode != NO_ERROR ) { EapLogErrorString( ROUTERLOG_CANT_OPEN_PPP_REGKEY,0,NULL, dwRetCode,0); break; }
dwEapTypeId = _wtol( wchSubKeyName );
//
// Find out the size of the path value.
//
dwRetCode = RegQueryInfoKey( hKeyEapDll, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &cbMaxValNameLen, &cbMaxValueDataSize, NULL, NULL );
if ( dwRetCode != NO_ERROR ) { EapLogErrorString(ROUTERLOG_CANT_OPEN_PPP_REGKEY,0,NULL, dwRetCode,0); break; }
//
// Allocate space for path and add one for NULL terminator
//
cbMaxValueDataSize += sizeof( WCHAR );
pEapDllPath = (LPWSTR)LocalAlloc( LPTR, cbMaxValueDataSize );
if ( pEapDllPath == (LPWSTR)NULL ) { dwRetCode = GetLastError(); EapLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode); break; }
//
// Read in the path
//
dwRetCode = RegQueryValueEx( hKeyEapDll, RAS_EAP_VALUENAME_PATH, NULL, &dwType, (LPBYTE)pEapDllPath, &cbMaxValueDataSize );
if ( dwRetCode != NO_ERROR ) { EapLogError(ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; }
if ( ( dwType != REG_EXPAND_SZ ) && ( dwType != REG_SZ ) ) { dwRetCode = ERROR_REGISTRY_CORRUPT; EapLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; }
//
// Replace the %SystemRoot% with the actual path.
//
cbSize = ExpandEnvironmentStrings( pEapDllPath, NULL, 0 );
if ( cbSize == 0 ) { dwRetCode = GetLastError(); EapLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; }
pEapDllExpandedPath = (LPWSTR)LocalAlloc( LPTR, cbSize*sizeof(WCHAR) );
if ( pEapDllExpandedPath == (LPWSTR)NULL ) { dwRetCode = GetLastError(); EapLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode); break; }
cbSize = ExpandEnvironmentStrings( pEapDllPath, pEapDllExpandedPath, cbSize*sizeof(WCHAR) ); if ( cbSize == 0 ) { dwRetCode = GetLastError(); EapLogError(ROUTERLOG_CANT_GET_REGKEYVALUES,0,NULL,dwRetCode); break; }
hInstance = LoadLibrary( pEapDllExpandedPath );
if ( hInstance == (HINSTANCE)NULL ) { dwRetCode = GetLastError(); EapLogErrorString( ROUTERLOG_PPP_CANT_LOAD_DLL,1, &pEapDllExpandedPath,dwRetCode, 1); break; }
gblpEapTable[dwKeyIndex].hInstance = hInstance;
gbldwNumEapProtocols++;
pRasEapGetInfo = GetProcAddress( hInstance, "RasEapGetInfo" );
if ( pRasEapGetInfo == (FARPROC)NULL ) { dwRetCode = GetLastError();
EapLogErrorString( ROUTERLOG_PPPCP_DLL_ERROR, 1, &pEapDllExpandedPath, dwRetCode, 1); break; }
gblpEapTable[dwKeyIndex].RasEapInfo.dwSizeInBytes = sizeof( PPP_EAP_INFO );
dwRetCode = (DWORD) (*pRasEapGetInfo)( dwEapTypeId, &(gblpEapTable[dwKeyIndex].RasEapInfo));
if ( dwRetCode != NO_ERROR ) { EapLogErrorString(ROUTERLOG_PPPCP_DLL_ERROR, 1, &pEapDllExpandedPath, dwRetCode, 1); break;
}
//
// Also initialize the GetCredentials entrypoint if available.
//
gblpEapTable[dwKeyIndex].RasEapGetCredentials = (DWORD (*) ( DWORD,VOID *, VOID **)) GetProcAddress( hInstance, "RasEapGetCredentials"); #if DBG
if(NULL != gblpEapTable[dwKeyIndex].RasEapGetCredentials) { EAP_TRACE1("GetCredentials entry point found for typeid %d", dwEapTypeId); } #endif
if ( gblpEapTable[dwKeyIndex].RasEapInfo.RasEapInitialize != NULL ) { dwRetCode = gblpEapTable[dwKeyIndex].RasEapInfo.RasEapInitialize( TRUE );
if ( dwRetCode != NO_ERROR ) { EapLogErrorString(ROUTERLOG_PPPCP_DLL_ERROR, 1, &pEapDllExpandedPath, dwRetCode, 1); break; } }
EAP_TRACE1("Successfully loaded EAP DLL type id = %d", dwEapTypeId );
RegCloseKey( hKeyEapDll );
hKeyEapDll = (HKEY)NULL;
LocalFree( pEapDllExpandedPath );
pEapDllExpandedPath = NULL;
LocalFree( pEapDllPath );
pEapDllPath = (LPWSTR)NULL; }
if ( hKeyEap != (HKEY)NULL ) { RegCloseKey( hKeyEap ); }
if ( hKeyEapDll == (HKEY)NULL ) { RegCloseKey( hKeyEapDll ); }
if ( pEapDllPath != (LPWSTR)NULL ) { LocalFree( pEapDllPath ); }
if ( pEapDllExpandedPath != NULL ) { LocalFree( pEapDllExpandedPath ); }
return( dwRetCode ); }
//**
//
// Call: EapInit
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Called to initialize/uninitialize this CP. In the former case,
// fInitialize will be TRUE; in the latter case, it will be FALSE.
//
DWORD EapInit( IN BOOL fInitialize ) { DWORD dwError;
if ( fInitialize ) { g_dwTraceIdEap = TraceRegister( TEXT("RASEAP") );
g_hLogEvents = RouterLogRegister( TEXT("RemoteAccess") );
if ( ( dwError = LoadEapDlls() ) != NO_ERROR ) { if ( g_dwTraceIdEap != INVALID_TRACEID ) { TraceDeregister( g_dwTraceIdEap );
g_dwTraceIdEap = INVALID_TRACEID; }
if ( g_hLogEvents != NULL ) { RouterLogDeregister( g_hLogEvents );
g_hLogEvents = NULL; }
if ( gblpEapTable != NULL ) { LocalFree( gblpEapTable );
gblpEapTable = NULL; }
gbldwNumEapProtocols = 0;
return( dwError ); } } else { if ( g_dwTraceIdEap != INVALID_TRACEID ) { TraceDeregister( g_dwTraceIdEap );
g_dwTraceIdEap = INVALID_TRACEID; }
if ( g_hLogEvents != NULL ) { RouterLogDeregister( g_hLogEvents );
g_hLogEvents = NULL; }
if ( gblpEapTable != NULL ) { DWORD dwIndex;
//
// Unload loaded DLLs
//
for ( dwIndex = 0; dwIndex < gbldwNumEapProtocols; dwIndex++ ) { if ( gblpEapTable[dwIndex].hInstance != NULL ) { if ( gblpEapTable[dwIndex].RasEapInfo.RasEapInitialize != NULL ) { dwError = gblpEapTable[dwIndex].RasEapInfo. RasEapInitialize( FALSE );
if ( dwError != NO_ERROR ) { EAP_TRACE2( "RasEapInitialize(%d) failed and returned %d", gblpEapTable[dwIndex].RasEapInfo.dwEapTypeId, dwError ); } }
FreeLibrary( gblpEapTable[dwIndex].hInstance ); gblpEapTable[dwIndex].hInstance = NULL; } }
LocalFree( gblpEapTable );
gblpEapTable = NULL; }
gbldwNumEapProtocols = 0; }
return(NO_ERROR); }
//**
//
// Call: EapGetInfo
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Called to get information for all protocols supported in this
// module
//
LONG_PTR EapGetInfo( IN DWORD dwProtocolId, OUT PPPCP_INFO* pInfo ) { ZeroMemory( pInfo, sizeof( PPPCP_INFO ) );
pInfo->Protocol = (DWORD )PPP_EAP_PROTOCOL; lstrcpyA(pInfo->SzProtocolName, "EAP"); pInfo->Recognize = MAXEAPCODE + 1; pInfo->RasCpInit = EapInit; pInfo->RasCpBegin = EapBegin; pInfo->RasCpEnd = EapEnd; pInfo->RasApMakeMessage = EapMakeMessage;
return( 0 ); }
//**
//
// Call: EapBegin
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Called by the engine to begin a EAP PPP session.
//
DWORD EapBegin( OUT VOID** ppWorkBuf, IN VOID* pInfo ) { DWORD dwRetCode; PPPAP_INPUT* pInput = (PPPAP_INPUT* )pInfo; EAPCB* pEapCb;
EAP_TRACE1("EapBegin(fServer=%d)",pInput->fServer );
if ( pInput->dwEapTypeToBeUsed != -1 ) { //
// First check if we support this EAP type
//
if ( GetEapTypeIndex( (BYTE)(pInput->dwEapTypeToBeUsed) ) == -1 ) { return( ERROR_NOT_SUPPORTED ); } }
//
// Allocate work buffer.
//
if ( ( pEapCb = (EAPCB* )LocalAlloc( LPTR, sizeof( EAPCB ) ) ) == NULL ) { return( ERROR_NOT_ENOUGH_MEMORY ); }
pEapCb->hPort = pInput->hPort; pEapCb->fAuthenticator = pInput->fServer; pEapCb->fRouter = pInput->fRouter; pEapCb->fLogon = pInput->fLogon; pEapCb->fNonInteractive = pInput->fNonInteractive; pEapCb->fPortWillBeBundled = pInput->fPortWillBeBundled; pEapCb->fThisIsACallback = pInput->fThisIsACallback; pEapCb->hTokenImpersonateUser = pInput->hTokenImpersonateUser; pEapCb->pCustomAuthConnData = pInput->pCustomAuthConnData; pEapCb->pCustomAuthUserData = pInput->pCustomAuthUserData; pEapCb->EapState = EAPSTATE_Initial; pEapCb->dwEapIndex = (DWORD)-1; pEapCb->dwEapTypeToBeUsed = pInput->dwEapTypeToBeUsed; pEapCb->chSeed = GEN_RAND_ENCODE_SEED;
if ( !pEapCb->fAuthenticator ) { if ( ( pInput->pszDomain != NULL ) && ( pInput->pszDomain[0] != (CHAR)NULL ) ) { strcpy( pEapCb->szIdentity, pInput->pszDomain ); strcat( pEapCb->szIdentity, "\\" ); strcat( pEapCb->szIdentity, pInput->pszUserName ); } else { strcpy( pEapCb->szIdentity, pInput->pszUserName ); }
strcpy( pEapCb->szPassword, pInput->pszPassword ); EncodePw( pEapCb->chSeed, pEapCb->szPassword );
if ( pInput->EapUIData.pEapUIData != NULL ) { PPP_EAP_UI_DATA EapUIData;
EapUIData.dwSizeOfEapUIData = pInput->EapUIData.dwSizeOfEapUIData; EapUIData.dwContextId = pInput->EapUIData.dwContextId;
EapUIData.pEapUIData = LocalAlloc( LPTR, EapUIData.dwSizeOfEapUIData );
if ( NULL == EapUIData.pEapUIData ) { LocalFree( pEapCb );
return( ERROR_NOT_ENOUGH_MEMORY ); }
CopyMemory( EapUIData.pEapUIData, pInput->EapUIData.pEapUIData, EapUIData.dwSizeOfEapUIData );
pEapCb->EapUIData = EapUIData; } }
//
// Register work buffer with engine.
//
*ppWorkBuf = pEapCb;
EAP_TRACE("EapBegin done");
return( NO_ERROR ); }
//**
//
// Call: EapEnd
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Called to end the Eap session initiated by an EapBegin
//
DWORD EapEnd( IN VOID* pWorkBuf ) { EAPCB* pEapCb = (EAPCB* )pWorkBuf;
EAP_TRACE("EapEnd");
if ( pEapCb == NULL ) { return( NO_ERROR ); }
EapDllEnd( pEapCb );
if ( pEapCb->pUserAttributes != NULL ) { RasAuthAttributeDestroy( pEapCb->pUserAttributes ); }
LocalFree( pEapCb->EapUIData.pEapUIData );
//
// Nuke any credentials in memory.
//
ZeroMemory( pEapCb, sizeof(EAPCB) );
LocalFree( pEapCb );
return( NO_ERROR ); }
//**
//
// Call: EapExtractMessage
//
// Returns: VOID
//
// Description: If there is any message in the Request/Notification packet, then
// save the string in pResult->szReplyMessage
//
VOID EapExtractMessage( IN PPP_CONFIG* pReceiveBuf, OUT PPPAP_RESULT* pResult ) { DWORD dwNumBytes; CHAR* szReplyMessage = NULL; WORD cbPacket;
cbPacket = WireToHostFormat16( pReceiveBuf->Length );
if ( PPP_CONFIG_HDR_LEN + 1 >= cbPacket ) { goto LDone; }
dwNumBytes = cbPacket - PPP_CONFIG_HDR_LEN - 1;
//
// One more for the terminating NULL.
//
szReplyMessage = LocalAlloc( LPTR, dwNumBytes + 1 );
if ( NULL == szReplyMessage ) { EAP_TRACE( "LocalAlloc failed. Cannot extract server's message." ); goto LDone; }
CopyMemory( szReplyMessage, pReceiveBuf->Data + 1, dwNumBytes );
LocalFree( pResult->szReplyMessage );
pResult->szReplyMessage = szReplyMessage;
szReplyMessage = NULL;
LDone:
LocalFree( szReplyMessage );
return; }
//**
//
// Call: EapMakeMessage
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Called to process and/or to send an EAP packet.
//
DWORD EapMakeMessage( IN VOID* pWorkBuf, IN PPP_CONFIG* pReceiveBuf, OUT PPP_CONFIG* pSendBuf, IN DWORD cbSendBuf, OUT PPPAP_RESULT* pResult, IN PPPAP_INPUT* pInput ) { EAPCB* pEapCb = (EAPCB* )pWorkBuf;
EAP_TRACE1("EapMakeMessage,RBuf=%x",pReceiveBuf);
if ( ( pReceiveBuf != NULL ) && ( pReceiveBuf->Code == EAPCODE_Request ) ) { //
// Always respond to notitication request, with a notification response
//
if ( pReceiveBuf->Data[0] == EAPTYPE_Notification ) { pSendBuf->Code = EAPCODE_Response; pSendBuf->Id = pReceiveBuf->Id;
HostToWireFormat16( PPP_CONFIG_HDR_LEN + 1, pSendBuf->Length );
pSendBuf->Data[0] = EAPTYPE_Notification;
pResult->Action = APA_Send;
EapExtractMessage( pReceiveBuf, pResult );
return( NO_ERROR ); }
//
// Always respond to Identity request, with an Identity response
//
if ( pReceiveBuf->Data[0] == EAPTYPE_Identity ) { pSendBuf->Code = EAPCODE_Response; pSendBuf->Id = pReceiveBuf->Id;
if ( !pEapCb->fAuthenticator ) { HostToWireFormat16( (WORD)(PPP_CONFIG_HDR_LEN+1+strlen(pEapCb->szIdentity)), pSendBuf->Length );
strcpy( pSendBuf->Data+1, pEapCb->szIdentity ); } else { HostToWireFormat16( (WORD)(PPP_CONFIG_HDR_LEN+1), pSendBuf->Length ); }
pSendBuf->Data[0] = EAPTYPE_Identity;
pResult->Action = APA_Send;
return( NO_ERROR ); } }
return (pEapCb->fAuthenticator) ? MakeAuthenticatorMessage( pEapCb, pReceiveBuf, pSendBuf, cbSendBuf, pResult, pInput ) : MakeAuthenticateeMessage( pEapCb, pReceiveBuf, pSendBuf, cbSendBuf, pResult, pInput ); }
//**
//
// Call: MakeAuthenticateeMessage
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: EAP Authenticatee engine
//
DWORD MakeAuthenticateeMessage( IN EAPCB* pEapCb, IN PPP_CONFIG* pReceiveBuf, OUT PPP_CONFIG* pSendBuf, IN DWORD cbSendBuf, OUT PPPAP_RESULT* pResult, IN PPPAP_INPUT* pInput ) { DWORD dwEapIndex; DWORD dwRetCode = NO_ERROR;
EAP_TRACE("MakeAuthenticateeMessage...");
switch( pEapCb->EapState ) { case EAPSTATE_Initial:
EAP_TRACE("EAPSTATE_Initial");
if ( pReceiveBuf == NULL ) { //
// Do nothing. Wait for request from authenticator
//
pResult->Action = APA_NoAction;
break; } else { if ( pReceiveBuf->Code != EAPCODE_Request ) { //
// We are authenticatee side so drop everything other than
// requests, since we do not send requests
//
pResult->Action = APA_NoAction;
break; }
//
// We got a packet, see if we support this EAP type, also that
// we are authorized to use it
//
dwEapIndex = GetEapTypeIndex( pReceiveBuf->Data[0] );
if (( dwEapIndex == -1 ) || ( ( pEapCb->dwEapTypeToBeUsed != -1 ) && ( dwEapIndex != GetEapTypeIndex( pEapCb->dwEapTypeToBeUsed)))) { //
// We do not support this type or we are not authorized to use
// it so we NAK with a type we support
//
pSendBuf->Code = EAPCODE_Response; pSendBuf->Id = pReceiveBuf->Id;
HostToWireFormat16( PPP_CONFIG_HDR_LEN + 2, pSendBuf->Length );
pSendBuf->Data[0] = EAPTYPE_Nak;
if ( pEapCb->dwEapTypeToBeUsed != -1 ) { pSendBuf->Data[1] = (BYTE)pEapCb->dwEapTypeToBeUsed; } else { pSendBuf->Data[1] = (BYTE)gblpEapTable[0].RasEapInfo.dwEapTypeId; }
pResult->Action = APA_Send;
break; } else { //
// The EAP type is acceptable to us so we begin authentication
//
if ( (dwRetCode = EapDllBegin(pEapCb, dwEapIndex)) != NO_ERROR ) { break; }
pEapCb->EapState = EAPSTATE_Working;
//
// Fall thru
//
} }
case EAPSTATE_Working:
EAP_TRACE("EAPSTATE_Working");
if ( pReceiveBuf != NULL ) { if ( ( pReceiveBuf->Code != EAPCODE_Request ) && ( pReceiveBuf->Code != EAPCODE_Success ) && ( pReceiveBuf->Code != EAPCODE_Failure ) ) { //
// We are authenticatee side so drop everything other than
// request/success/failure
//
EAP_TRACE("Dropping invlid packet not request/success/failure");
pResult->Action = APA_NoAction;
break; }
if ( ( pReceiveBuf->Code == EAPCODE_Request ) && ( pReceiveBuf->Data[0] != gblpEapTable[pEapCb->dwEapIndex].RasEapInfo.dwEapTypeId ) ) { EAP_TRACE("Dropping invalid request packet with unknown Id");
pResult->Action = APA_NoAction;
break; } }
dwRetCode = EapDllWork( pEapCb, pReceiveBuf, pSendBuf, cbSendBuf, pResult, pInput );
break;
default: RTASSERT( FALSE );
break; }
return( dwRetCode ); }
//**
//
// Call: MakeAuthenticatorMessage
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: EAP Authenticator engine
//
DWORD MakeAuthenticatorMessage( IN EAPCB* pEapCb, IN PPP_CONFIG* pReceiveBuf, OUT PPP_CONFIG* pSendBuf, IN DWORD cbSendBuf, OUT PPPAP_RESULT* pResult, IN PPPAP_INPUT* pInput ) { DWORD dwRetCode = NO_ERROR; DWORD dwEapTypeIndex; CHAR * pszReplyMessage; DWORD dwNumBytes; WORD wLength; BYTE bCode; RAS_AUTH_ATTRIBUTE * pAttribute;
EAP_TRACE("MakeAuthenticatorMessage...");
pResult->dwEapTypeId = pEapCb->dwEapTypeToBeUsed;
switch( pEapCb->EapState ) { case EAPSTATE_IdentityRequestSent:
EAP_TRACE("EAPSTATE_IdentityRequestSent");
if ( pReceiveBuf != NULL ) { //
// If we received a response to our identity request, then process
// it.
//
if ( ( pReceiveBuf->Code == EAPCODE_Response ) && ( pReceiveBuf->Data[0] == EAPTYPE_Identity ) ) { DWORD dwIdentityLength=WireToHostFormat16(pReceiveBuf->Length);
dwIdentityLength -= ( PPP_CONFIG_HDR_LEN + 1 );
//
// Truncate the identity length if it is greater than UNLEN
//
if ( dwIdentityLength > UNLEN+DNLEN+1 ) { dwIdentityLength = UNLEN+DNLEN+1; }
CopyMemory( pEapCb->szIdentity, pReceiveBuf->Data+1, dwIdentityLength );
pEapCb->szIdentity[dwIdentityLength] = (CHAR)NULL;
dwRetCode = MakeRequestAttributes( pEapCb, pReceiveBuf );
if ( dwRetCode == NO_ERROR ) { pResult->pUserAttributes = pEapCb->pUserAttributes;
pEapCb->EapState = EAPSTATE_EapPacketSentToAuthServer;
pResult->Action = APA_Authenticate; } } else { //
// Otherwise drop the packet
//
EAP_TRACE("Dropping invalid packet");
pResult->Action = APA_NoAction; }
break; }
//
// Else if If timed out, fallthru and resend
//
case EAPSTATE_Initial:
EAP_TRACE("EAPSTATE_Initial");
pEapCb->dwIdExpected = bNextId++;
//
// Create Identity request packet
//
pSendBuf->Code = EAPCODE_Request; pSendBuf->Id = (BYTE)pEapCb->dwIdExpected;
HostToWireFormat16( PPP_CONFIG_HDR_LEN + 1, pSendBuf->Length );
pSendBuf->Data[0] = EAPTYPE_Identity; pResult->Action = APA_SendWithTimeout; pResult->bIdExpected = (BYTE)pEapCb->dwIdExpected; pEapCb->EapState = EAPSTATE_IdentityRequestSent;
break;
case EAPSTATE_EapPacketSentToAuthServer:
//
// Wait for response from RADIUS authentication provider
// drop all other packets received in the mean time.
//
if ( pInput == NULL ) { pResult->Action = APA_NoAction;
break; }
if ( !pInput->fAuthenticationComplete ) { //
// If authentication was not complete then we do nothing
//
pResult->Action = APA_NoAction;
break; }
strcpy( pResult->szUserName, pEapCb->szIdentity );
//
// If authentication completed with an error, then we error out
// now, otherwise we process the authentication completion
// event below
//
if ( pInput->dwAuthError != NO_ERROR ) { EAP_TRACE1("Error %d while processing Access-Request", pInput->dwAuthError );
return( pInput->dwAuthError ); }
//
// If we got here then the authentication completed successfully,
// ie the RADIUS server returned attributes. First save the state
// attribute from the access challenge if there was one.
//
if ( pEapCb->pStateAttribute != NULL ) { LocalFree( pEapCb->pStateAttribute );
pEapCb->pStateAttribute = NULL; }
pAttribute = RasAuthAttributeGet( raatState, pInput->pAttributesFromAuthenticator );
if ( pAttribute != NULL ) { pEapCb->pStateAttribute = (PBYTE)LocalAlloc(LPTR, pAttribute->dwLength);
if ( pEapCb->pStateAttribute == NULL ) { return( GetLastError() ); }
CopyMemory( pEapCb->pStateAttribute, (PBYTE)(pAttribute->Value), pAttribute->dwLength );
pEapCb->cbStateAttribute = pAttribute->dwLength; }
//
// Try to get the EAP Message if there is one
//
pAttribute = RasAuthAttributeGet( raatEAPMessage, pInput->pAttributesFromAuthenticator );
if ( pAttribute != NULL ) { //
// Save the send buffer in case we have to resend
//
if ( pEapCb->pEAPSendBuf != NULL ) { LocalFree( pEapCb->pEAPSendBuf ); pEapCb->cbEAPSendBuf = 0; }
pszReplyMessage = RasAuthAttributeGetConcatString( raatReplyMessage, pInput->pAttributesFromAuthenticator, &dwNumBytes );
wLength = (USHORT) (PPP_CONFIG_HDR_LEN + 1 + dwNumBytes); bCode = ((PPP_CONFIG*)(pAttribute->Value))->Code;
if ( ( NULL != pszReplyMessage ) && ( wLength <= cbSendBuf ) && ( ( bCode == EAPCODE_Success ) || ( bCode == EAPCODE_Failure ) ) ) { pEapCb->pEAPSendBuf = (PBYTE)LocalAlloc( LPTR, wLength );
if ( pEapCb->pEAPSendBuf == NULL ) { LocalFree( pszReplyMessage );
return( GetLastError() ); }
pEapCb->cbEAPSendBuf = wLength;
pSendBuf->Code = EAPCODE_Request; pSendBuf->Id = ++((PPP_CONFIG*)(pAttribute->Value))->Id; HostToWireFormat16( wLength, pSendBuf->Length );
pSendBuf->Data[0] = EAPTYPE_Notification;
CopyMemory( pSendBuf->Data + 1, pszReplyMessage, dwNumBytes );
LocalFree( pszReplyMessage );
CopyMemory( pEapCb->pEAPSendBuf, pSendBuf, wLength );
pResult->Action = APA_SendWithTimeout; pResult->bIdExpected = pSendBuf->Id;
pEapCb->fSendWithTimeoutInteractive = FALSE; pEapCb->dwIdExpected = pSendBuf->Id; pEapCb->EapState = EAPSTATE_NotificationSentToClient;
pEapCb->pSavedAttributesFromAuthenticator = pInput->pAttributesFromAuthenticator; pEapCb->dwSavedAuthResultCode = pInput->dwAuthResultCode;
EAP_TRACE("Sending notification to client");
break; }
LocalFree( pszReplyMessage );
if ( pAttribute->dwLength > cbSendBuf ) { EAP_TRACE( "Need a larger buffer to construct reply" ); // return( ERROR_BUFFER_TOO_SMALL );
}
pEapCb->pEAPSendBuf = (PBYTE)LocalAlloc(LPTR, pAttribute->dwLength);
if ( pEapCb->pEAPSendBuf == NULL ) { return( GetLastError() ); }
EAP_TRACE("Sending packet to client");
pEapCb->cbEAPSendBuf = pAttribute->dwLength;
CopyMemory( pEapCb->pEAPSendBuf, pAttribute->Value, pAttribute->dwLength );
CopyMemory( pSendBuf, pAttribute->Value, pAttribute->dwLength ); } else { //
// No EAP Message attribute returned so fail the authentication
//
EAP_TRACE("No EAP Message attribute received, failing auth");
if ( pInput->dwAuthResultCode == NO_ERROR ) { pInput->dwAuthResultCode = ERROR_AUTHENTICATION_FAILURE; } }
if ( pInput->dwAuthResultCode != NO_ERROR ) { //
// If we failed authentication
//
pResult->dwError = pInput->dwAuthResultCode;
if ( pAttribute == NULL ) { //
// If there was no EAP packet then we are done
//
pResult->Action = APA_Done; } else { //
// If there was an EAP packet returned then simply send it
//
pResult->Action = APA_SendAndDone; } } else { //
// Otherwise either we succeeded or for some reason, we don't have
// a success or failure packet.
//
if ( pAttribute == NULL ) { //
// We succeeded but there was no packet to send, so we are
// done
//
pResult->Action = APA_Done; } else { //
// If we succeeded and there is a packet to send and that
// packet is a success packet, then send it and we are done
//
if ( pSendBuf->Code == EAPCODE_Success ) { pResult->Action = APA_SendAndDone; } else { pResult->Action = APA_SendWithTimeout;
pEapCb->fSendWithTimeoutInteractive = FALSE;
pAttribute = RasAuthAttributeGet( raatSessionTimeout, pInput->pAttributesFromAuthenticator );
if ( pAttribute != NULL ) { //
// If session timeout in Access-Challenge is
// greater then 10 then send with interactive
// timeout.
//
if ( PtrToUlong(pAttribute->Value) > 10 ) { pResult->Action = APA_SendWithTimeout2;
pEapCb->fSendWithTimeoutInteractive = TRUE; } }
pEapCb->dwIdExpected = pSendBuf->Id; pResult->bIdExpected = (BYTE)pEapCb->dwIdExpected; pEapCb->EapState = EAPSTATE_EapPacketSentToClient; } }
pResult->dwError = NO_ERROR; }
break;
case EAPSTATE_NotificationSentToClient:
if ( pReceiveBuf != NULL ) { //
// Make sure the packet IDs match
//
if ( pReceiveBuf->Id != ((PPP_CONFIG*)(pEapCb->pEAPSendBuf))->Id ) { EAP_TRACE("Id of packet recvd doesn't match one sent");
pResult->Action = APA_NoAction;
break; }
strcpy( pResult->szUserName, pEapCb->szIdentity );
pAttribute = RasAuthAttributeGet( raatEAPMessage, pEapCb->pSavedAttributesFromAuthenticator );
if ( pAttribute != NULL ) { //
// Save the send buffer in case we have to resend
//
if ( pEapCb->pEAPSendBuf != NULL ) { LocalFree( pEapCb->pEAPSendBuf ); pEapCb->cbEAPSendBuf = 0; }
if ( pAttribute->dwLength > cbSendBuf ) { EAP_TRACE( "Need a larger buffer to construct reply" ); // return( ERROR_BUFFER_TOO_SMALL );
}
pEapCb->pEAPSendBuf = (PBYTE)LocalAlloc(LPTR, pAttribute->dwLength);
if ( pEapCb->pEAPSendBuf == NULL ) { return( GetLastError() ); }
EAP_TRACE("Sending packet to client");
pEapCb->cbEAPSendBuf = pAttribute->dwLength;
CopyMemory( pEapCb->pEAPSendBuf, pAttribute->Value, pAttribute->dwLength );
CopyMemory( pSendBuf, pAttribute->Value, pAttribute->dwLength );
if ( pEapCb->dwSavedAuthResultCode != NO_ERROR ) { //
// If we failed authentication
//
pResult->dwError = pEapCb->dwSavedAuthResultCode; pResult->Action = APA_SendAndDone; break; } else if ( EAPCODE_Success == pSendBuf->Code ) { pResult->dwError = NO_ERROR; pResult->Action = APA_SendAndDone; break; } }
pResult->dwError = ERROR_AUTHENTICATION_FAILURE; pResult->Action = APA_Done; break; }
//
// Fall thru
//
case EAPSTATE_EapPacketSentToClient:
//
// If we did not get any input structure, then we either received
// a packet or we timed out.
//
if ( pReceiveBuf != NULL ) { //
// Make sure the packet IDs match
//
if ( pReceiveBuf->Id != ((PPP_CONFIG*)(pEapCb->pEAPSendBuf))->Id ) { EAP_TRACE("Id of packet recvd doesn't match one sent");
pResult->Action = APA_NoAction;
break; }
//
// Save the Eap Type. Make sure that the response from the client
// contains an authentication Type code, and not something like
// a Nak.
//
if ( ( pReceiveBuf->Code == EAPCODE_Response ) && ( pReceiveBuf->Data[0] > EAPTYPE_Nak ) ) { pEapCb->dwEapTypeToBeUsed = pReceiveBuf->Data[0]; }
//
// We received a packet so simply send it to the RADIUS server
//
dwRetCode = MakeRequestAttributes( pEapCb, pReceiveBuf );
if ( dwRetCode == NO_ERROR ) { pResult->pUserAttributes = pEapCb->pUserAttributes; pResult->Action = APA_Authenticate; pEapCb->EapState = EAPSTATE_EapPacketSentToAuthServer; } } else { //
// We timed out and have to resend
//
EAP_TRACE("Timed out, resending packet to client");
CopyMemory(pSendBuf, pEapCb->pEAPSendBuf, pEapCb->cbEAPSendBuf);
if ( pEapCb->fSendWithTimeoutInteractive ) { pResult->Action = APA_SendWithTimeout2; } else { pResult->Action = APA_SendWithTimeout; }
pResult->bIdExpected = (BYTE)pEapCb->dwIdExpected; }
break;
default:
RTASSERT( FALSE ); break; }
return( dwRetCode ); }
//**
//
// Call: EapDllBegin
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Called to initiate an EAP session for a certain type
//
//
DWORD EapDllBegin( IN EAPCB * pEapCb, IN DWORD dwEapIndex ) { PPP_EAP_INPUT PppEapInput; WCHAR awszIdentity[DNLEN+UNLEN+2]; WCHAR awszPassword[PWLEN+1]; DWORD dwRetCode;
EAP_TRACE1("EapDllBegin called for EAP Type %d", gblpEapTable[dwEapIndex].RasEapInfo.dwEapTypeId);
if (0 == MultiByteToWideChar( CP_ACP, 0, pEapCb->szIdentity, -1, awszIdentity, DNLEN+UNLEN+2 ) ) { dwRetCode = GetLastError();
EAP_TRACE2("MultiByteToWideChar(%s) failed: %d", pEapCb->szIdentity, dwRetCode);
return( dwRetCode ); }
ZeroMemory( &PppEapInput, sizeof( PppEapInput ) );
PppEapInput.dwSizeInBytes = sizeof( PPP_EAP_INPUT ); PppEapInput.fFlags = ( pEapCb->fRouter ? RAS_EAP_FLAG_ROUTER : 0 ); PppEapInput.fFlags |= ( pEapCb->fLogon ? RAS_EAP_FLAG_LOGON : 0 ); PppEapInput.fFlags |= ( pEapCb->fNonInteractive ? RAS_EAP_FLAG_NON_INTERACTIVE : 0 );
if ( !pEapCb->fThisIsACallback && !pEapCb->fPortWillBeBundled ) { PppEapInput.fFlags |= RAS_EAP_FLAG_FIRST_LINK; }
PppEapInput.fAuthenticator = pEapCb->fAuthenticator; PppEapInput.pwszIdentity = awszIdentity; PppEapInput.pwszPassword = awszPassword; PppEapInput.hTokenImpersonateUser = pEapCb->hTokenImpersonateUser; PppEapInput.fAuthenticationComplete = FALSE; PppEapInput.dwAuthResultCode = NO_ERROR;
if ( NULL != pEapCb->pCustomAuthConnData ) { PppEapInput.pConnectionData = pEapCb->pCustomAuthConnData->abCustomAuthData; PppEapInput.dwSizeOfConnectionData = pEapCb->pCustomAuthConnData->cbCustomAuthData; }
if ( NULL != pEapCb->pCustomAuthUserData ) { PppEapInput.pUserData = pEapCb->pCustomAuthUserData->abCustomAuthData; PppEapInput.dwSizeOfUserData = pEapCb->pCustomAuthUserData->cbCustomAuthData; }
if ( NULL != pEapCb->EapUIData.pEapUIData ) { PppEapInput.pDataFromInteractiveUI = pEapCb->EapUIData.pEapUIData; PppEapInput.dwSizeOfDataFromInteractiveUI = pEapCb->EapUIData.dwSizeOfEapUIData; }
DecodePw( pEapCb->chSeed, pEapCb->szPassword );
MultiByteToWideChar( CP_ACP, 0, pEapCb->szPassword, -1, awszPassword, PWLEN+1 );
awszPassword[PWLEN] = 0;
dwRetCode = gblpEapTable[dwEapIndex].RasEapInfo.RasEapBegin( &pEapCb->pWorkBuffer, &PppEapInput ); EncodePw( pEapCb->chSeed, pEapCb->szPassword ); ZeroMemory( awszPassword, sizeof(awszPassword) );
if ( dwRetCode == NO_ERROR ) { pEapCb->dwEapIndex = dwEapIndex; } else { pEapCb->dwEapIndex = (DWORD)-1; }
return( dwRetCode ); }
//**
//
// Call: EapDllEnd
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Called to end an EAP session for a certain type
//
//
DWORD EapDllEnd( EAPCB * pEapCb ) { DWORD dwRetCode = NO_ERROR;
EAP_TRACE1("EapDllEnd called for EAP Index %d", pEapCb->dwEapIndex );
if ( pEapCb->pWorkBuffer != NULL ) { //
// On the server, pWorkBuffer must be NULL. IAS must call RasEapEnd.
//
if ( pEapCb->dwEapIndex != (DWORD)-1 ) { dwRetCode = gblpEapTable[pEapCb->dwEapIndex].RasEapInfo.RasEapEnd( pEapCb->pWorkBuffer ); }
pEapCb->pWorkBuffer = NULL; }
if ( pEapCb->pEAPSendBuf != NULL ) { LocalFree( pEapCb->pEAPSendBuf );
pEapCb->pEAPSendBuf = NULL; pEapCb->cbEAPSendBuf = 0; }
if ( pEapCb->pStateAttribute != NULL ) { LocalFree( pEapCb->pStateAttribute );
pEapCb->pStateAttribute = NULL; }
pEapCb->dwEapIndex = (DWORD)-1;
return( dwRetCode ); }
//**
//
// Call: EapDllWork
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Called to process an incomming packet or timeout etc
//
DWORD EapDllWork( IN EAPCB * pEapCb, IN PPP_CONFIG* pReceiveBuf, OUT PPP_CONFIG* pSendBuf, IN DWORD cbSendBuf, OUT PPPAP_RESULT* pResult, IN PPPAP_INPUT* pInput ) { PPP_EAP_OUTPUT PppEapOutput; PPP_EAP_INPUT PppEapInput; DWORD dwRetCode; CHAR * pChar = NULL;
EAP_TRACE1("EapDllWork called for EAP Type %d", gblpEapTable[pEapCb->dwEapIndex].RasEapInfo.dwEapTypeId);
ZeroMemory( &PppEapOutput, sizeof( PppEapOutput ) ); PppEapOutput.dwSizeInBytes = sizeof( PppEapOutput );
ZeroMemory( &PppEapInput, sizeof( PppEapInput ) ); PppEapInput.dwSizeInBytes = sizeof( PPP_EAP_INPUT ); PppEapInput.fAuthenticator = pEapCb->fAuthenticator; PppEapInput.hTokenImpersonateUser = pEapCb->hTokenImpersonateUser;
if ( pInput != NULL ) { PppEapInput.fAuthenticationComplete = pInput->fAuthenticationComplete; PppEapInput.dwAuthResultCode = pInput->dwAuthResultCode; PppEapInput.fSuccessPacketReceived = pInput->fSuccessPacketReceived;
if ( pInput->fEapUIDataReceived ) { //
// EapUIData.pEapUIData is allocated by rasman and freed by engine.
// raseap.c must not free it.
//
if ( pInput->EapUIData.dwContextId != pEapCb->dwUIInvocationId ) { //
// Ignore this data received
//
EAP_TRACE("Out of date data received from UI" );
return( NO_ERROR ); }
PppEapInput.fDataReceivedFromInteractiveUI = TRUE;
PppEapInput.pDataFromInteractiveUI = pInput->EapUIData.pEapUIData; PppEapInput.dwSizeOfDataFromInteractiveUI = pInput->EapUIData.dwSizeOfEapUIData;
} }
dwRetCode = gblpEapTable[pEapCb->dwEapIndex].RasEapInfo.RasEapMakeMessage( pEapCb->pWorkBuffer, (PPP_EAP_PACKET *)pReceiveBuf, (PPP_EAP_PACKET *)pSendBuf, cbSendBuf, &PppEapOutput, &PppEapInput ); if ( dwRetCode != NO_ERROR ) { switch( dwRetCode ) { case ERROR_PPP_INVALID_PACKET:
EAP_TRACE("Silently discarding invalid EAP packet");
pResult->Action = APA_NoAction;
return( NO_ERROR ); default:
EAP_TRACE2("EapDLLMakeMessage for type %d returned %d", gblpEapTable[pEapCb->dwEapIndex].RasEapInfo.dwEapTypeId, dwRetCode ); break; }
return( dwRetCode ); }
switch( PppEapOutput.Action ) { case EAPACTION_NoAction:
pResult->Action = APA_NoAction; EAP_TRACE( "EAP Dll returned Action=EAPACTION_NoAction" ); break;
case EAPACTION_Send:
pResult->Action = APA_Send; EAP_TRACE( "EAP Dll returned Action=EAPACTION_Send" ); break;
case EAPACTION_Done: case EAPACTION_SendAndDone:
if ( PppEapOutput.Action == EAPACTION_SendAndDone ) { pResult->Action = APA_SendAndDone; EAP_TRACE( "EAP Dll returned Action=EAPACTION_SendAndDone" ); } else { pResult->Action = APA_Done; EAP_TRACE( "EAP Dll returned Action=EAPACTION_Done" ); }
pResult->dwError = PppEapOutput.dwAuthResultCode; pResult->pUserAttributes = PppEapOutput.pUserAttributes;
strcpy( pResult->szUserName, pEapCb->szIdentity );
break;
case EAPACTION_SendWithTimeout: case EAPACTION_SendWithTimeoutInteractive: case EAPACTION_Authenticate:
EAP_TRACE1( "EAP Dll returned disallowed Action=%d", PppEapOutput.Action ); break;
default:
RTASSERT( FALSE ); EAP_TRACE1( "EAP Dll returned unknown Action=%d", PppEapOutput.Action ); break; } //
// Check to see if EAP dll wants to bring up UI
//
if ( PppEapOutput.fInvokeInteractiveUI ) { if ( pEapCb->fAuthenticator ) { EAP_TRACE( "EAP Dll wants to bring up UI on the server side" );
return( ERROR_INTERACTIVE_MODE ); }
if ( PppEapOutput.pUIContextData != NULL ) { pResult->InvokeEapUIData.dwSizeOfUIContextData = PppEapOutput.dwSizeOfUIContextData;
pResult->InvokeEapUIData.pUIContextData = LocalAlloc(LPTR, PppEapOutput.dwSizeOfUIContextData);
if ( pResult->InvokeEapUIData.pUIContextData == NULL ) { return( ERROR_NOT_ENOUGH_MEMORY ); } CopyMemory( pResult->InvokeEapUIData.pUIContextData, PppEapOutput.pUIContextData, pResult->InvokeEapUIData.dwSizeOfUIContextData ); } else { pResult->InvokeEapUIData.pUIContextData = NULL; pResult->InvokeEapUIData.dwSizeOfUIContextData = 0; }
pResult->fInvokeEapUI = TRUE; pEapCb->dwUIInvocationId = gbldwGuid++; pResult->InvokeEapUIData.dwContextId = pEapCb->dwUIInvocationId; pResult->InvokeEapUIData.dwEapTypeId = gblpEapTable[pEapCb->dwEapIndex].RasEapInfo.dwEapTypeId;
EAP_TRACE( "EAP Dll wants to invoke interactive UI" ); }
pResult->dwEapTypeId = pEapCb->dwEapTypeToBeUsed; pResult->fSaveUserData = PppEapOutput.fSaveUserData; pResult->pUserData = PppEapOutput.pUserData; pResult->dwSizeOfUserData = PppEapOutput.dwSizeOfUserData;
pResult->fSaveConnectionData = PppEapOutput.fSaveConnectionData; pResult->SetCustomAuthData.pConnectionData = PppEapOutput.pConnectionData; pResult->SetCustomAuthData.dwSizeOfConnectionData = PppEapOutput.dwSizeOfConnectionData;
return( dwRetCode ); }
//**
//
// Call: GetEapIndex
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will return the index into gblpEapTable of the specified
// EAP type
//
DWORD GetEapTypeIndex( IN DWORD dwEapTypeId ) { DWORD dwIndex;
for ( dwIndex = 0; dwIndex < gbldwNumEapProtocols; dwIndex++ ) { if ( gblpEapTable[dwIndex].RasEapInfo.dwEapTypeId == dwEapTypeId ) { return( dwIndex ); } }
return( (DWORD)-1 ); }
//**
//
// Call: MakeRequestAttributes
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will begin the RADIUS/EAP dialog by sending the caller's
// identity to the RADIUS server.
//
DWORD MakeRequestAttributes( IN EAPCB * pEapCb, IN PPP_CONFIG * pReceiveBuf ) { DWORD dwIndex = 0; DWORD dwRetCode;
EAP_TRACE("Sending EAP packet to RADIUS/IAS");
if ( pEapCb->pUserAttributes != NULL ) { RasAuthAttributeDestroy( pEapCb->pUserAttributes );
pEapCb->pUserAttributes = NULL; }
//
// Allocate the appropriate amount + 1 for Identity + 1 more for EAP packet
// +1 for State attribute (if any).
//
if ( ( pEapCb->pUserAttributes = RasAuthAttributeCreate( ( pEapCb->pStateAttribute != NULL ) ? 3 : 2 ) ) == NULL ) { return( GetLastError() ); }
//
// Insert EAP Message
//
dwRetCode = RasAuthAttributeInsert( dwIndex++, pEapCb->pUserAttributes, raatEAPMessage, FALSE, WireToHostFormat16(pReceiveBuf->Length), pReceiveBuf ); if ( dwRetCode != NO_ERROR ) { RasAuthAttributeDestroy( pEapCb->pUserAttributes );
pEapCb->pUserAttributes = NULL;
return( dwRetCode ); }
//
// Insert username
//
dwRetCode = RasAuthAttributeInsert( dwIndex++, pEapCb->pUserAttributes, raatUserName, FALSE, strlen( pEapCb->szIdentity ), pEapCb->szIdentity ); if ( dwRetCode != NO_ERROR ) { RasAuthAttributeDestroy( pEapCb->pUserAttributes );
pEapCb->pUserAttributes = NULL;
return( dwRetCode ); }
//
// Insert State attribute if we have one
//
if ( pEapCb->pStateAttribute != NULL ) { dwRetCode = RasAuthAttributeInsert( dwIndex++, pEapCb->pUserAttributes, raatState, FALSE, pEapCb->cbStateAttribute, pEapCb->pStateAttribute ); if ( dwRetCode != NO_ERROR ) { RasAuthAttributeDestroy( pEapCb->pUserAttributes );
pEapCb->pUserAttributes = NULL;
return( dwRetCode ); } }
return( NO_ERROR ); }
DWORD EapGetCredentials( VOID * pWorkBuf, VOID ** ppCredentials) { EAPCB *pEapCb = (EAPCB *) pWorkBuf; DWORD dwRetCode = ERROR_SUCCESS;
if( (NULL == pEapCb) || (NULL == ppCredentials)) { return E_INVALIDARG; }
if(NULL != gblpEapTable[pEapCb->dwEapIndex].RasEapGetCredentials) { //
// Invoke appropriate eap dll for credentials
//
dwRetCode = gblpEapTable[pEapCb->dwEapIndex].RasEapGetCredentials( pEapCb->dwEapTypeToBeUsed, pEapCb->pWorkBuffer, ppCredentials); }
return dwRetCode; }
|