1057 lines
32 KiB
C
1057 lines
32 KiB
C
/********************************************************************/
|
||
/** Copyright(c) 1985-1998 Microsoft Corporation. **/
|
||
/********************************************************************/
|
||
|
||
//***
|
||
//
|
||
// Filename: packconv.c
|
||
//
|
||
// Description:
|
||
//
|
||
// History: Feb 11,1998 NarenG Created original version.
|
||
//
|
||
#include <nt.h>
|
||
#include <ntrtl.h>
|
||
#include <nturtl.h>
|
||
#include <windows.h>
|
||
#include <lmcons.h>
|
||
#include <lmapibuf.h>
|
||
#include <lmaccess.h>
|
||
#include <raserror.h>
|
||
#include <time.h>
|
||
#include <string.h>
|
||
#include <rasauth.h>
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <rtutils.h>
|
||
#include <mprlog.h>
|
||
#include <mprerror.h>
|
||
#define INCL_RASAUTHATTRIBUTES
|
||
#define INCL_HOSTWIRE
|
||
#include <ppputil.h>
|
||
#include "radclnt.h"
|
||
#include "hmacmd5.h"
|
||
#include "md5.h"
|
||
#include "radclnt.h"
|
||
|
||
//**
|
||
//
|
||
// Call: Router2Radius
|
||
//
|
||
// Returns: NO_ERROR - Success
|
||
// Non-zero returns - Failure
|
||
//
|
||
// Description: Converts attribute array from RAS_AUTH_ATTRIBUTE to
|
||
// RADIUS_ATTRIBUTE
|
||
// INPUT:
|
||
// prgRouter - array of attributes passed in from
|
||
// the application
|
||
// pRadiusServer - RADIUS server
|
||
// descriptor(ip address, secret)
|
||
// pHeader - RADIUS packet header
|
||
// bSubCode - accounting sub codes.
|
||
// OUTPUT:
|
||
// prgRadius - array of attribtes that will be sent
|
||
// to the RADIUS server.
|
||
// pAttrLength - Length of the Radius packet.
|
||
//
|
||
DWORD
|
||
Router2Radius(
|
||
IN RAS_AUTH_ATTRIBUTE * prgRouter,
|
||
OUT RADIUS_ATTRIBUTE UNALIGNED * prgRadius,
|
||
IN RADIUSSERVER UNALIGNED * pRadiusServer,
|
||
IN RADIUS_PACKETHEADER UNALIGNED * pHeader,
|
||
IN BYTE bSubCode,
|
||
IN DWORD dwRetryCount,
|
||
OUT PBYTE * ppSignature,
|
||
OUT DWORD * pAttrLength
|
||
)
|
||
{
|
||
DWORD dwError = NO_ERROR;
|
||
BOOL fEAPMessage = FALSE;
|
||
|
||
*pAttrLength = 0;
|
||
*ppSignature = NULL;
|
||
|
||
do
|
||
{
|
||
//
|
||
// add the attribute for accounting records
|
||
//
|
||
|
||
switch( bSubCode )
|
||
{
|
||
case atStart:
|
||
case atStop:
|
||
case atAccountingOn:
|
||
case atAccountingOff:
|
||
case atInterimUpdate:
|
||
|
||
//
|
||
// Add the accounting status type attribute
|
||
//
|
||
|
||
prgRadius->bType = ptAcctStatusType;
|
||
prgRadius->bLength = sizeof(RADIUS_ATTRIBUTE) + sizeof(DWORD);
|
||
(*pAttrLength) += prgRadius->bLength;
|
||
|
||
prgRadius++;
|
||
|
||
*((DWORD UNALIGNED *) prgRadius) = htonl(bSubCode);
|
||
prgRadius = (RADIUS_ATTRIBUTE *)(((PBYTE) prgRadius)+sizeof(DWORD));
|
||
|
||
//
|
||
// Add the accounting delay time attribute
|
||
//
|
||
|
||
prgRadius->bType = raatAcctDelayTime;
|
||
prgRadius->bLength = sizeof(RADIUS_ATTRIBUTE) + sizeof(DWORD);
|
||
(*pAttrLength) += prgRadius->bLength;
|
||
|
||
prgRadius++;
|
||
|
||
HostToWireFormat32( dwRetryCount * pRadiusServer->Timeout.tv_sec,
|
||
(LPBYTE)(prgRadius) );
|
||
|
||
prgRadius = (RADIUS_ATTRIBUTE *)(((PBYTE) prgRadius)+sizeof(DWORD));
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
break;
|
||
}
|
||
|
||
while( prgRouter->raaType != raatMinimum )
|
||
{
|
||
//
|
||
// Copy attribute type & length
|
||
//
|
||
|
||
prgRadius->bType = (BYTE)(prgRouter->raaType);
|
||
prgRadius->bLength = (BYTE)(prgRouter->dwLength);
|
||
|
||
switch( prgRouter->raaType )
|
||
{
|
||
case raatUserPassword:
|
||
|
||
(*pAttrLength) += EncryptPassword( prgRouter,
|
||
prgRadius,
|
||
pRadiusServer,
|
||
pHeader,
|
||
bSubCode);
|
||
break;
|
||
|
||
case raatUserName:
|
||
case raatMD5CHAPPassword:
|
||
case raatFilterId:
|
||
case raatReplyMessage:
|
||
case raatCallbackNumber:
|
||
case raatCallbackId:
|
||
case raatFramedRoute:
|
||
case raatState:
|
||
case raatClass:
|
||
case raatVendorSpecific:
|
||
case raatCalledStationId:
|
||
case raatCallingStationId:
|
||
case raatNASIdentifier:
|
||
case raatProxyState:
|
||
case raatLoginLATService:
|
||
case raatLoginLATNode:
|
||
case raatLoginLATGroup:
|
||
case raatFramedAppleTalkZone:
|
||
case raatAcctSessionId:
|
||
case raatAcctMultiSessionId:
|
||
case raatMD5CHAPChallenge:
|
||
case raatLoginLATPort:
|
||
case raatTunnelClientEndpoint:
|
||
case raatTunnelServerEndpoint:
|
||
case raatARAPPassword:
|
||
case raatARAPFeatures:
|
||
case raatARAPSecurityData:
|
||
case raatConnectInfo:
|
||
case raatConfigurationToken:
|
||
case raatSignature:
|
||
case raatCertificateOID:
|
||
|
||
CopyMemory( prgRadius+1,
|
||
(PBYTE)prgRouter->Value,
|
||
prgRadius->bLength);
|
||
|
||
prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
|
||
|
||
(*pAttrLength) += prgRadius->bLength;
|
||
|
||
break;
|
||
|
||
case raatEAPMessage:
|
||
|
||
{
|
||
DWORD dwLength = prgRouter->dwLength;
|
||
PBYTE pRouterEapMessage = (PBYTE)(prgRouter->Value);
|
||
|
||
while( dwLength > 0 )
|
||
{
|
||
if ( dwLength > 253 )
|
||
{
|
||
CopyMemory( (PBYTE)(prgRadius+1),
|
||
pRouterEapMessage,
|
||
253 );
|
||
|
||
prgRadius->bLength = 253;
|
||
pRouterEapMessage += 253;
|
||
|
||
dwLength -= 253;
|
||
}
|
||
else
|
||
{
|
||
CopyMemory( prgRadius+1,
|
||
(PBYTE)pRouterEapMessage,
|
||
dwLength );
|
||
|
||
prgRadius->bLength = (BYTE)dwLength;
|
||
dwLength = 0;
|
||
}
|
||
|
||
prgRadius->bType = (BYTE)raatEAPMessage;
|
||
prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
|
||
|
||
(*pAttrLength) += prgRadius->bLength;
|
||
|
||
if ( dwLength > 0 )
|
||
{
|
||
prgRadius = (PRADIUS_ATTRIBUTE)
|
||
((PBYTE) prgRadius + prgRadius->bLength);
|
||
}
|
||
}
|
||
}
|
||
|
||
fEAPMessage = TRUE;
|
||
|
||
break;
|
||
|
||
case raatNASPort:
|
||
case raatServiceType:
|
||
case raatFramedProtocol:
|
||
case raatFramedRouting:
|
||
case raatFramedMTU:
|
||
case raatFramedCompression:
|
||
case raatLoginIPHost:
|
||
case raatLoginService:
|
||
case raatLoginTCPPort:
|
||
case raatFramedIPXNetwork:
|
||
case raatSessionTimeout:
|
||
case raatIdleTimeout:
|
||
case raatTerminationAction:
|
||
case raatFramedAppleTalkLink:
|
||
case raatFramedAppleTalkNetwork:
|
||
case raatNASPortType:
|
||
case raatPortLimit:
|
||
case raatTunnelType:
|
||
case raatTunnelMediumType:
|
||
case raatAcctStatusType:
|
||
case raatAcctDelayTime:
|
||
case raatAcctInputOctets:
|
||
case raatAcctOutputOctets:
|
||
case raatAcctAuthentic:
|
||
case raatAcctSessionTime:
|
||
case raatAcctInputPackets:
|
||
case raatAcctOutputPackets:
|
||
case raatAcctTerminateCause:
|
||
case raatAcctLinkCount:
|
||
case raatFramedIPAddress:
|
||
case raatFramedIPNetmask:
|
||
case raatPrompt:
|
||
case raatPasswordRetry:
|
||
case raatARAPZoneAccess:
|
||
case raatARAPSecurity:
|
||
case raatAcctInterimInterval:
|
||
case raatAcctEventTimeStamp:
|
||
case raatPEAPFastRoamedSession:
|
||
case raatPEAPEmbeddedEAPTypeId:
|
||
|
||
switch( prgRouter->dwLength )
|
||
{
|
||
case 1:
|
||
*((LPBYTE)(prgRadius+1)) = (BYTE)prgRouter->Value;
|
||
break;
|
||
|
||
case 2:
|
||
HostToWireFormat16U( (WORD)prgRouter->Value,
|
||
(LPBYTE)(prgRadius+1) );
|
||
break;
|
||
|
||
case 4:
|
||
HostToWireFormat32( PtrToUlong(prgRouter->Value),
|
||
(LPBYTE)(prgRadius+1) );
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
|
||
|
||
(*pAttrLength) += prgRadius->bLength;
|
||
|
||
break;
|
||
|
||
case raatNASIPAddress:
|
||
|
||
RTASSERT( 4 == prgRouter->dwLength );
|
||
|
||
if ( pRadiusServer->nboNASIPAddress != INADDR_NONE )
|
||
{
|
||
CopyMemory( (LPBYTE)(prgRadius+1),
|
||
(LPBYTE)&(pRadiusServer->nboNASIPAddress),
|
||
4 );
|
||
}
|
||
else if( pRadiusServer->nboBestIf != INADDR_NONE)
|
||
{
|
||
CopyMemory( (LPBYTE)(prgRadius+1),
|
||
(LPBYTE)&(pRadiusServer->nboBestIf),
|
||
4 );
|
||
}
|
||
else
|
||
{
|
||
HostToWireFormat32( PtrToUlong(prgRouter->Value),
|
||
(LPBYTE)(prgRadius+1) );
|
||
}
|
||
|
||
prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
|
||
|
||
(*pAttrLength) += prgRadius->bLength;
|
||
|
||
break;
|
||
}
|
||
|
||
prgRadius = (PRADIUS_ATTRIBUTE)
|
||
((PBYTE) prgRadius + prgRadius->bLength);
|
||
prgRouter++;
|
||
}
|
||
|
||
}while( FALSE );
|
||
|
||
if ( dwError != NO_ERROR )
|
||
{
|
||
(*pAttrLength) = 0;
|
||
}
|
||
else
|
||
{
|
||
if ( ( ( bSubCode == atInvalid )
|
||
? pRadiusServer->fSendSignature
|
||
: FALSE ) || ( fEAPMessage ) )
|
||
{
|
||
//
|
||
// Add a signature attribute as well. Zero this out for now.
|
||
//
|
||
|
||
*ppSignature = (BYTE *)prgRadius;
|
||
|
||
prgRadius->bType = (BYTE)raatSignature;
|
||
prgRadius->bLength = (BYTE)18;
|
||
|
||
ZeroMemory( prgRadius+1, 16 );
|
||
|
||
(*pAttrLength) += prgRadius->bLength;
|
||
}
|
||
}
|
||
|
||
return( dwError );
|
||
}
|
||
|
||
//**
|
||
//
|
||
// Call: Radius2Router
|
||
//
|
||
// Returns: NO_ERROR - Success
|
||
// Non-zero returns - Failure
|
||
//
|
||
// Description: Converts RADIUS attribute array to RAS_AUTH_ATTRIBUTE array
|
||
//
|
||
DWORD
|
||
Radius2Router(
|
||
IN RADIUS_PACKETHEADER UNALIGNED * pRecvHeader,
|
||
IN RADIUSSERVER UNALIGNED * pRadiusServer,
|
||
IN PBYTE pRequestAuthenticator,
|
||
IN DWORD dwNumAttributes,
|
||
OUT DWORD * pdwExtError,
|
||
OUT PRAS_AUTH_ATTRIBUTE * pprgRouter,
|
||
OUT BOOL * fEapMessageReceived
|
||
)
|
||
{
|
||
LONG cbLength;
|
||
DWORD dwRetCode = NO_ERROR;
|
||
BOOL fEAPMessage = FALSE;
|
||
BOOL fSignature = FALSE;
|
||
PBYTE pEAPMessage = NULL;
|
||
DWORD cbEAPMessage = 0;
|
||
RADIUS_ATTRIBUTE UNALIGNED * prgRadius
|
||
= (PRADIUS_ATTRIBUTE)(pRecvHeader + 1);
|
||
*pdwExtError = 0;
|
||
*pprgRouter = NULL;
|
||
*fEapMessageReceived = FALSE;
|
||
|
||
*pprgRouter = RasAuthAttributeCreate( dwNumAttributes );
|
||
|
||
if ( *pprgRouter == NULL )
|
||
{
|
||
return( GetLastError() );
|
||
}
|
||
|
||
dwNumAttributes = 0;
|
||
|
||
cbLength = ntohs( pRecvHeader->wLength ) - sizeof(RADIUS_PACKETHEADER);
|
||
|
||
while( cbLength > 0 )
|
||
{
|
||
switch( (RAS_AUTH_ATTRIBUTE_TYPE)prgRadius->bType )
|
||
{
|
||
case raatNASPort:
|
||
case raatServiceType:
|
||
case raatFramedProtocol:
|
||
case raatFramedRouting:
|
||
case raatFramedMTU:
|
||
case raatFramedCompression:
|
||
case raatLoginIPHost:
|
||
case raatLoginService:
|
||
case raatLoginTCPPort:
|
||
case raatFramedIPXNetwork:
|
||
case raatSessionTimeout:
|
||
case raatIdleTimeout:
|
||
case raatTerminationAction:
|
||
case raatFramedAppleTalkLink:
|
||
case raatFramedAppleTalkNetwork:
|
||
case raatNASPortType:
|
||
case raatPortLimit:
|
||
case raatTunnelType:
|
||
case raatTunnelMediumType:
|
||
case raatAcctStatusType:
|
||
case raatAcctDelayTime:
|
||
case raatAcctInputOctets:
|
||
case raatAcctOutputOctets:
|
||
case raatAcctAuthentic:
|
||
case raatAcctSessionTime:
|
||
case raatAcctInputPackets:
|
||
case raatAcctOutputPackets:
|
||
case raatAcctTerminateCause:
|
||
case raatAcctLinkCount:
|
||
case raatFramedIPAddress:
|
||
case raatFramedIPNetmask:
|
||
case raatNASIPAddress:
|
||
case raatPrompt:
|
||
case raatPasswordRetry:
|
||
case raatARAPZoneAccess:
|
||
case raatARAPSecurity:
|
||
case raatAcctInterimInterval:
|
||
case raatAcctEventTimeStamp:
|
||
case raatPEAPFastRoamedSession:
|
||
case raatPEAPEmbeddedEAPTypeId:
|
||
|
||
{
|
||
DWORD dwIntegralValue;
|
||
DWORD dwLength = prgRadius->bLength - sizeof(RADIUS_ATTRIBUTE);
|
||
|
||
if ( dwLength == 1 )
|
||
{
|
||
dwIntegralValue = (DWORD)(*(LPBYTE)(prgRadius+1));
|
||
}
|
||
else if ( dwLength == 2 )
|
||
{
|
||
dwIntegralValue=(DWORD)WireToHostFormat16U(
|
||
(PBYTE)(prgRadius+1));
|
||
}
|
||
else if ( dwLength == 4 )
|
||
{
|
||
dwIntegralValue=(DWORD)WireToHostFormat32(
|
||
(PBYTE)(prgRadius+1));
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Drop bad attribute
|
||
//
|
||
|
||
break;
|
||
}
|
||
|
||
dwRetCode = RasAuthAttributeInsert(
|
||
dwNumAttributes++,
|
||
*pprgRouter,
|
||
(RAS_AUTH_ATTRIBUTE_TYPE)prgRadius->bType,
|
||
FALSE,
|
||
prgRadius->bLength-sizeof(RADIUS_ATTRIBUTE),
|
||
(LPVOID)ULongToPtr(dwIntegralValue) );
|
||
|
||
}
|
||
|
||
break;
|
||
|
||
case raatSignature:
|
||
|
||
//
|
||
// Check the signature
|
||
//
|
||
|
||
{
|
||
BYTE MD5d[MD5_LEN];
|
||
HmacContext HmacMD5c;
|
||
BYTE Signature[16];
|
||
|
||
HmacMD5Init( &HmacMD5c,
|
||
(PBYTE)(pRadiusServer->szSecret),
|
||
pRadiusServer->cbSecret);
|
||
|
||
//
|
||
// Zero out the signature attribute before calculating it
|
||
//
|
||
|
||
if ( prgRadius->bLength != 18 )
|
||
{
|
||
RADIUS_TRACE("Received invalid signature length in packet");
|
||
|
||
*pdwExtError = ERROR_INVALID_SIGNATURE_LENGTH;
|
||
|
||
dwRetCode = ERROR_INVALID_RADIUS_RESPONSE;
|
||
|
||
break;
|
||
}
|
||
|
||
CopyMemory( Signature, (prgRadius+1), 16 );
|
||
|
||
ZeroMemory( (PBYTE)(prgRadius+1), 16 );
|
||
|
||
CopyMemory( (PBYTE)(pRecvHeader->rgAuthenticator),
|
||
pRequestAuthenticator,
|
||
16 );
|
||
|
||
HmacMD5Update( &HmacMD5c,
|
||
(PBYTE)pRecvHeader,
|
||
ntohs(pRecvHeader->wLength) );
|
||
|
||
HmacMD5Final( MD5d, &HmacMD5c );
|
||
|
||
if ( memcmp( Signature, MD5d, 16 ) != 0 )
|
||
{
|
||
RADIUS_TRACE("Received invalid signature in packet");
|
||
|
||
*pdwExtError = ERROR_INVALID_SIGNATURE;
|
||
|
||
dwRetCode = ERROR_INVALID_RADIUS_RESPONSE;
|
||
|
||
break;
|
||
}
|
||
|
||
fSignature = TRUE;
|
||
}
|
||
|
||
//
|
||
// Fall thru
|
||
//
|
||
|
||
case raatUserName:
|
||
case raatUserPassword:
|
||
case raatMD5CHAPPassword:
|
||
case raatFilterId:
|
||
case raatReplyMessage:
|
||
case raatCallbackNumber:
|
||
case raatCallbackId:
|
||
case raatFramedRoute:
|
||
case raatState:
|
||
case raatClass:
|
||
case raatCalledStationId:
|
||
case raatCallingStationId:
|
||
case raatNASIdentifier:
|
||
case raatProxyState:
|
||
case raatLoginLATService:
|
||
case raatLoginLATNode:
|
||
case raatLoginLATGroup:
|
||
case raatFramedAppleTalkZone:
|
||
case raatAcctSessionId:
|
||
case raatAcctMultiSessionId:
|
||
case raatMD5CHAPChallenge:
|
||
case raatLoginLATPort:
|
||
case raatTunnelClientEndpoint:
|
||
case raatTunnelServerEndpoint:
|
||
case raatARAPPassword:
|
||
case raatARAPFeatures:
|
||
case raatARAPSecurityData:
|
||
case raatConnectInfo:
|
||
case raatConfigurationToken:
|
||
case raatARAPChallengeResponse:
|
||
case raatCertificateOID:
|
||
|
||
dwRetCode = RasAuthAttributeInsert(
|
||
dwNumAttributes++,
|
||
*pprgRouter,
|
||
(RAS_AUTH_ATTRIBUTE_TYPE)prgRadius->bType,
|
||
FALSE,
|
||
prgRadius->bLength-sizeof(RADIUS_ATTRIBUTE),
|
||
(LPVOID)(prgRadius+1) );
|
||
break;
|
||
|
||
case raatVendorSpecific:
|
||
|
||
if ( WireToHostFormat32( (PBYTE)(prgRadius+1) ) == 311 )
|
||
{
|
||
BYTE abTemp[34];
|
||
PBYTE pVSAWalker = (PBYTE)(prgRadius+1)+4;
|
||
DWORD cbVSALength = prgRadius->bLength -
|
||
sizeof( RADIUS_ATTRIBUTE ) - 4;
|
||
|
||
while( cbVSALength > 1 )
|
||
{
|
||
if ( *pVSAWalker == 12 )
|
||
{
|
||
if ( *(pVSAWalker+1) != 34 )
|
||
{
|
||
RADIUS_TRACE("Recvd invalid MPPE key packet");
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// We don't want to modify whatever data we got
|
||
// from RADIUS (to keep the signature valid).
|
||
//
|
||
|
||
CopyMemory( abTemp, pVSAWalker, 34 );
|
||
|
||
//
|
||
// Decrypt the MPPE session keys.
|
||
//
|
||
|
||
dwRetCode = DecryptMPPEKeys( pRadiusServer,
|
||
pRequestAuthenticator,
|
||
abTemp+2 );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
break;
|
||
}
|
||
|
||
dwRetCode = RasAuthAttributeInsertVSA(
|
||
dwNumAttributes++,
|
||
*pprgRouter,
|
||
311,
|
||
*(pVSAWalker+1),
|
||
abTemp );
|
||
}
|
||
}
|
||
else if ( ( *pVSAWalker == 16 )
|
||
|| ( *pVSAWalker == 17 ) )
|
||
{
|
||
DWORD dwLength;
|
||
BYTE* pbTemp;
|
||
|
||
dwLength = *(pVSAWalker+1);
|
||
|
||
if ( ( dwLength <= 4 )
|
||
|| ( ( dwLength - 4 ) % 16 != 0 ) )
|
||
{
|
||
RADIUS_TRACE("Recvd invalid MPPE key packet");
|
||
}
|
||
else
|
||
{
|
||
pbTemp = LocalAlloc( LPTR, dwLength );
|
||
|
||
if ( NULL == pbTemp )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
RADIUS_TRACE("Out of memory");
|
||
break;
|
||
}
|
||
|
||
//
|
||
// We don't want to modify whatever data we got
|
||
// from RADIUS (to keep the signature valid).
|
||
//
|
||
|
||
CopyMemory( pbTemp, pVSAWalker, dwLength );
|
||
|
||
//
|
||
// Decrypt the MPPE Send/Recv keys.
|
||
//
|
||
|
||
dwRetCode = DecryptMPPESendRecvKeys(
|
||
pRadiusServer,
|
||
pRequestAuthenticator,
|
||
dwLength,
|
||
pbTemp+2 );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
LocalFree( pbTemp );
|
||
break;
|
||
}
|
||
|
||
dwRetCode = RasAuthAttributeInsertVSA(
|
||
dwNumAttributes++,
|
||
*pprgRouter,
|
||
311,
|
||
*(pVSAWalker+1),
|
||
pbTemp );
|
||
|
||
LocalFree( pbTemp );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
dwRetCode = RasAuthAttributeInsertVSA(
|
||
dwNumAttributes++,
|
||
*pprgRouter,
|
||
311,
|
||
*(pVSAWalker+1),
|
||
pVSAWalker );
|
||
}
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
break;
|
||
}
|
||
|
||
cbVSALength -= *(pVSAWalker+1);
|
||
pVSAWalker += *(pVSAWalker+1);
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
case raatEAPMessage:
|
||
|
||
fEAPMessage = TRUE;
|
||
|
||
{
|
||
if ( pEAPMessage == NULL )
|
||
{
|
||
//
|
||
// Nothing has been allocated for EAP yet.
|
||
//
|
||
|
||
pEAPMessage = (PBYTE)LocalAlloc(
|
||
LPTR,
|
||
prgRadius->bLength
|
||
- sizeof( RADIUS_ATTRIBUTE ) );
|
||
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Need to increase the size of the buffer to hold this
|
||
// message
|
||
//
|
||
|
||
PBYTE pReallocEAPMessage =
|
||
(PBYTE)LocalReAlloc(
|
||
pEAPMessage,
|
||
cbEAPMessage
|
||
+ prgRadius->bLength
|
||
- sizeof( RADIUS_ATTRIBUTE ),
|
||
LMEM_MOVEABLE );
|
||
|
||
if ( pReallocEAPMessage == NULL )
|
||
{
|
||
LocalFree( pEAPMessage );
|
||
|
||
pEAPMessage = NULL;
|
||
}
|
||
else
|
||
{
|
||
pEAPMessage = pReallocEAPMessage;
|
||
}
|
||
}
|
||
|
||
if ( pEAPMessage == NULL )
|
||
{
|
||
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Copy existing buffer to new buffer
|
||
//
|
||
|
||
CopyMemory( pEAPMessage+cbEAPMessage,
|
||
(PBYTE)(prgRadius+1),
|
||
prgRadius->bLength - sizeof(RADIUS_ATTRIBUTE) );
|
||
|
||
//
|
||
// Increment the cbEAPMessage so that the size is updated
|
||
// properly
|
||
//
|
||
|
||
cbEAPMessage += (prgRadius->bLength - sizeof(RADIUS_ATTRIBUTE));
|
||
}
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
//
|
||
// Drop attributes we do not know about.
|
||
//
|
||
|
||
break;
|
||
}
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
RasAuthAttributeDestroy( *pprgRouter );
|
||
|
||
*pprgRouter = NULL;
|
||
|
||
if ( pEAPMessage != NULL )
|
||
{
|
||
LocalFree( pEAPMessage );
|
||
}
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
RADIUS_TRACE1( "Returning attribute type %d", prgRadius->bType );
|
||
|
||
cbLength -= prgRadius->bLength;
|
||
|
||
prgRadius = (PRADIUS_ATTRIBUTE)((PBYTE)prgRadius+prgRadius->bLength);
|
||
}
|
||
|
||
if ( dwRetCode == NO_ERROR )
|
||
{
|
||
if ( fEAPMessage )
|
||
{
|
||
//
|
||
// If we have received an EAP message, make sure we received a valid
|
||
// signature as well
|
||
//
|
||
|
||
if ( !fSignature )
|
||
{
|
||
RADIUS_TRACE("Did not receive signature along auth EAPMessage");
|
||
|
||
*pdwExtError = ERROR_NO_SIGNATURE;
|
||
|
||
dwRetCode = ERROR_INVALID_RADIUS_RESPONSE;
|
||
}
|
||
else
|
||
{
|
||
|
||
dwRetCode = RasAuthAttributeInsert(
|
||
dwNumAttributes++,
|
||
*pprgRouter,
|
||
(RAS_AUTH_ATTRIBUTE_TYPE)raatEAPMessage,
|
||
FALSE,
|
||
cbEAPMessage,
|
||
(LPVOID)pEAPMessage );
|
||
|
||
*fEapMessageReceived = TRUE;
|
||
}
|
||
|
||
LocalFree( pEAPMessage );
|
||
}
|
||
}
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
DWORD
|
||
EncryptPassword(
|
||
IN RAS_AUTH_ATTRIBUTE * prgRouter,
|
||
IN RADIUS_ATTRIBUTE UNALIGNED * prgRadius,
|
||
IN RADIUSSERVER UNALIGNED * pRadiusServer,
|
||
IN RADIUS_PACKETHEADER UNALIGNED * pHeader,
|
||
IN BYTE bSubCode
|
||
)
|
||
{
|
||
MD5_CTX MD5c;
|
||
DWORD iIndex, iBlock, cBlocks;
|
||
DWORD bLength, AttrLength;
|
||
BYTE UNALIGNED *pbValue;
|
||
|
||
//
|
||
// make the password into a 16 octet multiple
|
||
//
|
||
|
||
bLength = ((prgRadius->bLength + 15) / 16) * 16;
|
||
|
||
if ( bLength == 0 )
|
||
{
|
||
bLength = 16;
|
||
}
|
||
|
||
prgRadius->bLength = (BYTE)(sizeof(RADIUS_ATTRIBUTE) + bLength);
|
||
|
||
pbValue = (PBYTE) (prgRadius + 1);
|
||
|
||
AttrLength = sizeof(RADIUS_ATTRIBUTE);
|
||
|
||
//
|
||
// Zero pad the password
|
||
//
|
||
|
||
ZeroMemory( pbValue, bLength );
|
||
|
||
//
|
||
// Copy the original password
|
||
//
|
||
|
||
CopyMemory( pbValue, (PBYTE)prgRouter->Value, (BYTE)prgRouter->dwLength);
|
||
|
||
cBlocks = bLength / 16;
|
||
|
||
for ( iBlock = 0; iBlock < cBlocks; iBlock++ )
|
||
{
|
||
MD5Init( &MD5c );
|
||
|
||
MD5Update(&MD5c,(PBYTE)pRadiusServer->szSecret,pRadiusServer->cbSecret);
|
||
|
||
if (iBlock == 0)
|
||
{
|
||
MD5Update( &MD5c,
|
||
pHeader->rgAuthenticator,
|
||
sizeof(pHeader->rgAuthenticator));
|
||
}
|
||
else
|
||
{
|
||
MD5Update(&MD5c, (pbValue - 16), 16);
|
||
}
|
||
|
||
MD5Final( &MD5c );
|
||
|
||
for ( iIndex = 0; iIndex < 16; iIndex++ )
|
||
{
|
||
*pbValue ^= MD5c.digest[iIndex];
|
||
|
||
pbValue++;
|
||
}
|
||
}
|
||
|
||
return( AttrLength + bLength );
|
||
}
|
||
|
||
DWORD
|
||
DecryptMPPEKeys(
|
||
IN RADIUSSERVER UNALIGNED * pRadiusServer,
|
||
IN PBYTE pRequestAuthenticator,
|
||
IN OUT PBYTE pEncryptionKeys
|
||
)
|
||
{
|
||
BYTE * pbValue = (BYTE *)pEncryptionKeys;
|
||
MD5_CTX MD5c;
|
||
DWORD dwIndex;
|
||
DWORD dwBlock;
|
||
BYTE abCipherText[16];
|
||
|
||
//
|
||
// Save the cipherText from the first block.
|
||
//
|
||
|
||
CopyMemory(abCipherText, pbValue, sizeof(abCipherText));
|
||
|
||
//
|
||
// Walk thru the 2 blocks
|
||
//
|
||
|
||
for ( dwBlock = 0; dwBlock < 2; dwBlock++ )
|
||
{
|
||
MD5Init( &MD5c );
|
||
|
||
MD5Update( &MD5c,
|
||
(PBYTE)(pRadiusServer->szSecret),
|
||
pRadiusServer->cbSecret);
|
||
|
||
if ( dwBlock == 0 )
|
||
{
|
||
//
|
||
// Use the Request Authenticator for the first block
|
||
//
|
||
|
||
MD5Update( &MD5c, pRequestAuthenticator, 16 );
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Use the first block of cipherText for the second block
|
||
//
|
||
|
||
MD5Update( &MD5c, abCipherText, 16 );
|
||
}
|
||
|
||
MD5Final( &MD5c );
|
||
|
||
for ( dwIndex = 0; dwIndex < 16; dwIndex ++ )
|
||
{
|
||
*pbValue ^= MD5c.digest[dwIndex];
|
||
|
||
pbValue++;
|
||
}
|
||
}
|
||
|
||
return( NO_ERROR );
|
||
}
|
||
|
||
DWORD
|
||
DecryptMPPESendRecvKeys(
|
||
IN RADIUSSERVER UNALIGNED * pRadiusServer,
|
||
IN PBYTE pRequestAuthenticator,
|
||
IN DWORD dwLength,
|
||
IN OUT PBYTE pEncryptionKeys
|
||
)
|
||
{
|
||
BYTE * pbValue = (BYTE *)pEncryptionKeys + 2;
|
||
BYTE abCipherText[16];
|
||
MD5_CTX MD5c;
|
||
DWORD dwIndex;
|
||
DWORD dwBlock;
|
||
DWORD dwNumBlocks;
|
||
|
||
dwNumBlocks = ( dwLength - 2 ) / 16;
|
||
|
||
//
|
||
// Walk thru the blocks
|
||
//
|
||
|
||
for ( dwBlock = 0; dwBlock < dwNumBlocks; dwBlock++ )
|
||
{
|
||
MD5Init( &MD5c );
|
||
|
||
MD5Update( &MD5c,
|
||
(PBYTE)(pRadiusServer->szSecret),
|
||
pRadiusServer->cbSecret);
|
||
|
||
if ( dwBlock == 0 )
|
||
{
|
||
//
|
||
// Use the Request Authenticator and salt for the first block
|
||
//
|
||
|
||
MD5Update( &MD5c, pRequestAuthenticator, 16 );
|
||
MD5Update( &MD5c, pEncryptionKeys, 2 );
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Use the previous block of cipherText
|
||
//
|
||
|
||
MD5Update( &MD5c, abCipherText, 16 );
|
||
}
|
||
|
||
MD5Final( &MD5c );
|
||
|
||
//
|
||
// Save the cipherText from this block.
|
||
//
|
||
|
||
CopyMemory(abCipherText, pbValue, sizeof(abCipherText));
|
||
|
||
for ( dwIndex = 0; dwIndex < 16; dwIndex++ )
|
||
{
|
||
*pbValue ^= MD5c.digest[dwIndex];
|
||
|
||
pbValue++;
|
||
}
|
||
}
|
||
|
||
return( NO_ERROR );
|
||
}
|